From cb132d533203f617129892c43c9be6a3dfecb27a Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 15 一月 2025 12:00:54 +0800
Subject: [PATCH] 10263 【越南】【英文】【BT】后端支持NPC仿真实玩家战斗和快速战斗(改为真实地图战斗;竞技场、跨服PK、跨服排位赛,测试地图100均已支持;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py | 3
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py | 4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_EnterFB.py | 4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py | 422 +++++++++++++++-------
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py | 11
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py | 1
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py | 5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_PlayerMirror.py | 9
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py | 27
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py | 87 ++--
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py | 65 ---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossChampionship.py | 117 ------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 45 -
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ArenaBattle.py | 29 -
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py | 183 ++++++++-
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 21
16 files changed, 554 insertions(+), 479 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
index e6afa38..db4f559 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -34,6 +34,7 @@
import CrossBattlefield
import CrossRealmPlayer
import CrossChampionship
+import PlayerPackData
import DataRecordPack
import CrossRealmMsg
import PyDataManager
@@ -754,7 +755,7 @@
# @return None
def EnterFBLine(curPlayer, queryCallName, sendCMD, tick):
playerID = curPlayer.GetPlayerID()
- GameWorld.Log("EnterFBLine()...queryCallName=%s,sendCMD=%s" % (queryCallName, sendCMD), curPlayer.GetPlayerID())
+ GameWorld.Log("EnterFBLine()...queryCallName=%s,sendCMD=%s" % (queryCallName, sendCMD), playerID)
playerManager = GameWorld.GetPlayerManager()
try:
mapInfo = eval(sendCMD)
@@ -769,6 +770,7 @@
#if mapInfo and len(mapInfo) == 2:
tagMapID = mapInfo[0]
tagLineID = mapInfo[1]
+ extendValue1 = mapInfo[2] if len(mapInfo) > 2 else None
fbLineIpyData = GetFBLineIpyData(tagMapID, tagLineID)
sceneMapID = tagMapID if not fbLineIpyData else fbLineIpyData.GetMapID()
@@ -777,6 +779,13 @@
GameWorld.ErrLog("目标副本地图不存在!tagMapID=%s,sceneMapID=%s" % (tagMapID, sceneMapID), curPlayer.GetPlayerID())
return
+ if isinstance(extendValue1, dict):
+ if extendValue1.get("msgType", "") == "MirrorBattle":
+ PlayerPackData.OnMGReuestPlayerPackData(extendValue1)
+ playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_EnterFB, 0, sceneMapID,
+ queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex())
+ return
+
# 组队副本, 有队伍的情况才验证其他队员可否进入,否则代表单人进入
if gameMap.GetMapFBType() == ChConfig.fbtTeam:
if tagMapID == ChConfig.Def_FBMapID_Love:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py
index 56ab2e5..f08632f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerPackData.py
@@ -408,22 +408,23 @@
msgType = msgInfo.get("msgType")
# 镜像战斗
if msgType == "MirrorBattle":
+ sceneMapID = msgInfo.get("sceneMapID", 0)
playerID = msgInfo.get("playerID", 0)
- # 玩家发起的
- if playerID:
- playerID = msgInfo["playerID"]
- curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
- if not curPlayer:
- return
- tagMapID = GameWorld.GetQueryPlayerMapID(curPlayer)
- routeIndex = curPlayer.GetRouteServerIndex()
- else:
- tagMapID = msgInfo.get("requestMapID", 0)
- routeIndex = -1
+ routeIndex = -1
+# # 玩家发起的
+# if playerID:
+# playerID = msgInfo["playerID"]
+# curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+# if not curPlayer:
+# return
+# sceneMapID = GameWorld.GetQueryPlayerMapID(curPlayer)
+# routeIndex = curPlayer.GetRouteServerIndex()
+# else:
+# routeIndex = -1
sendMsg = str([msgInfo, packDataDict])
- GameWorld.DebugLog("MapServer_QueryPlayer tagMapID=%s,len=%s" % (tagMapID, len(sendMsg)), playerID)
- GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, playerID, tagMapID, "PlayerMirror", sendMsg, len(sendMsg), routeIndex)
+ GameWorld.DebugLog("MapServer_QueryPlayer sceneMapID=%s,len=%s" % (sceneMapID, len(sendMsg)), playerID)
+ GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, playerID, sceneMapID, "PlayerMirror", sendMsg, len(sendMsg), routeIndex)
# 其他功能可再扩展
else:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
index 0d9b1e3..b4547db 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
@@ -29,6 +29,7 @@
import OperControlManager
import PlayerViewCacheTube
import PassiveBuffEffMng
+import GameWorldProcess
import ChNetSendPack
import IpyGameDataPY
import AttackCommon
@@ -43,6 +44,8 @@
import time
+Def_StateTimeList = [3, 60, 10] # 默认阶段时长,秒
+
class MirrorBattle():
## 某场战斗
@@ -51,6 +54,7 @@
return
def Clear(self):
+ self.isChangeMap = 0 # 是否切图战斗的
self.isSysbg = False # 是否系统后台进行战斗的,玩家无感知,仅知道结果
self.requestID = 0 # 请求ID,一般是玩家ID或者系统自定的ID,如某一场PK的标识信息
self.playerID = 0 # 所属玩家ID,可能为0
@@ -58,9 +62,8 @@
self.mapID = 0 # 功能mapID,代表某一个功能
self.funcLineID = 0
self.batState = 0 # 状态:0-无;1-准备中;2-战斗中;3-快速结束中,4-结束
- self.startTick = 0 # 开始战斗tick
- self.fightTickMax = 0 # 战斗最大时长,tick
- self.fightTickRemain = 0 # 剩余战斗时长,tick
+ self.stateTick = 0 # 阶段状态变更时tick
+ self.stateTickRemain = 0 # 阶段剩余时长,tick
self.mirrorIDDict = {} # 该场所有玩家镜像实例ID对应真实ID {playerID:realPlayerID, ...}
self.realIDDict = {} # 该场所有真实玩家对应初始信息 {playerID:{k:v, ...}, ...}
self.playerFactionDict = {} # 该场所有玩家阵营信息,真实玩家+镜像玩家 {playerID:faction, ...}
@@ -72,15 +75,79 @@
self.isQuick = False # 是否快速战斗结束的
self.isWin = False # 是否获胜
self.winFaction = 0 # 获胜阵营
+ # 结算时血量明细
+ self.curHP = 0
+ self.curHPMax = 0
+ self.tagHP = 0
+ self.tagHPMax = 0
return
def GetTagPlayerID(self): return self.tagPlayerIDList[0] if self.tagPlayerIDList else 0
- def CaclFightTick(self, tick):
- ## 计算战斗时长,返回剩余时长tick
- fightTickCost = tick - self.startTick # 已过战斗时长
- self.fightTickRemain = max(0, self.fightTickMax - fightTickCost) # 剩余战斗时长
- return self.fightTickRemain
+ def SyncFBStepTime(self, tick):
+ #curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)
+ if self.isSysbg:
+ return
+ self.CaclStateTick(tick)
+ state = self.batState
+ if state == ChConfig.Def_MirrorBatState_Prepare:
+ self.__SyncRealPlayerTick(ChConfig.tttWaitStart, self.stateTickRemain)
+ elif state == ChConfig.Def_MirrorBatState_Fight:
+ self.__SyncRealPlayerTick(ChConfig.tttTowerTake, self.stateTickRemain)
+ elif state == ChConfig.Def_MirrorBatState_Over:
+ self.__SyncRealPlayerTick(ChConfig.tttLeaveMap, self.stateTickRemain)
+ return
+
+ def __SyncRealPlayerTick(self, msgType, msgTick):
+ playerMgr = GameWorld.GetMapCopyPlayerManager()
+ for playerID in self.realIDDict.keys():
+ curPlayer = playerMgr.FindPlayerByID(playerID)
+ if not curPlayer:
+ continue
+ curPlayer.Sync_TimeTick(msgType, 0, msgTick, True)
+ return
+
+ def ChangeBattleState(self, state, tick):
+ GameWorld.DebugLog("镜像战斗阶段变更: mapID=%s,state=%s" % (self.mapID, state), self.battleID)
+ self.batState = state
+ self.stateTick = tick
+ self.stateTickRemain = self.GetStateTickMax()
+ self.SyncFBStepTime(tick)
+ return
+
+ def CaclStateTick(self, tick):
+ ## 计算状态时长,返回剩余时长tick
+ stateTickMax = self.GetStateTickMax()
+ passTick = tick - self.stateTick # 已过时长
+ self.stateTickRemain = max(0, stateTickMax - passTick) # 剩余时长
+ return self.stateTickRemain
+
+ def GetStateTickRemain(self): return self.stateTickRemain
+ def GetStateTickMax(self):
+ fightTimeLimitDict = IpyGameDataPY.GetFuncEvalCfg("MirrorAttack", 1, {})
+ stateTimeList = fightTimeLimitDict.get(self.mapID, []) # 阶段时长列表
+ if not stateTimeList or len(stateTimeList) != 3:
+ stateTimeList = Def_StateTimeList
+
+ state = self.batState
+ stateTime = 0
+ if state == ChConfig.Def_MirrorBatState_Prepare:
+ stateTime = stateTimeList[0]
+ elif state == ChConfig.Def_MirrorBatState_Fight:
+ stateTime = stateTimeList[1]
+ elif state == ChConfig.Def_MirrorBatState_Over:
+ stateTime = stateTimeList[2]
+ return stateTime * 1000
+
+ def CalcHPPer(self):
+ ## 结算当前阶段双方阵营剩余血量占比,一般用于结算计算
+ curHPPer = round(self.curHP / float(self.curHPMax) * 100, 2)
+ tagHPPer = round(self.tagHP / float(self.tagHPMax) * 100, 2)
+ return curHPPer, tagHPPer
+ def CalcRemainTimePer(self):
+ ## 结算当前阶段剩余时间占比,一般用于结算计算
+ remainTimePer = round(self.stateTickRemain / float(self.GetStateTickMax()) * 100)
+ return remainTimePer
def AddBattlePlayer(self, curPlayer, faction, posX=0, posY=0):
playerID = curPlayer.GetPlayerID()
@@ -88,7 +155,7 @@
if realPlayerID:
self.mirrorIDDict[playerID] = realPlayerID
else:
- self.realIDDict[playerID] = {"SightLevel":curPlayer.GetSightLevel(), "Faction":curPlayer.GetFaction(), "PosX":curPlayer.GetPosX(), "PosY":curPlayer.GetPosY()}
+ self.realIDDict[playerID] = {"SightLevel":curPlayer.GetSightLevel(), "Faction":curPlayer.GetFaction()}
self.playerFactionDict[playerID] = faction
curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleID, self.battleID)
@@ -97,6 +164,7 @@
curPlayer.SetCanAttack(True)
curPlayer.SetFaction(faction)
PlayerControl.SetPlayerSightLevel(curPlayer, self.battleID) # 视野层级默认为战场ID,每场战斗的玩家独立视野
+ PlayerControl.SetSight(curPlayer, ChConfig.Def_PlayerSight_Default * 3)
GameObj.SetHPFull(curPlayer) # 回满血
SkillCommon.ResetAllSkillCD(curPlayer) # 重置技能CD
return
@@ -144,7 +212,9 @@
def GetMirrorBattle(curPlayer):
## 获取玩家实例所属的战场
- return GetMirrorBattleByID(curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID))
+ if curPlayer.GetRealPlayerID():
+ return GetMirrorBattleByID(curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID))
+ return GetMirrorBattleByID(curPlayer.GetPlayerID())
def GetMirrorBattleByID(battleID):
battle = None
@@ -155,17 +225,14 @@
battle = MirrorBattle()
return battle
-def ClearMirrorBattleByPlayer(curPlayer):
- ## 清除玩家创建的镜像战斗
- ClearMirrorBattleByID(curPlayer.GetPlayerID())
- return
-
def ClearMirrorBattleByID(battleID):
## 清除镜像战斗
battle = PyGameData.g_mirrorBattleDict.pop(battleID, None)
if not battle:
return
+ ownerPlayerID = battle.playerID
isSysbg = battle.isSysbg
+ GameWorld.DebugLog("清除镜像战斗: battleID=%s,ownerPlayerID=%s,isSysbg=%s" % (isSysbg, ownerPlayerID, isSysbg), battleID)
playerMgr = GameWorld.GetPlayerManager()
tick = GameWorld.GetGameWorld().GetTick()
@@ -176,30 +243,25 @@
PlayerControl.DeleteMirror(mirrorPlayer, isSysbg) # 系统场延迟回收
# 重置真实玩家
- for playerID, info in battle.realIDDict.items():
- curPlayer = playerMgr.FindPlayerByID(playerID)
+ for realPlayerID, info in battle.realIDDict.items():
+ curPlayer = playerMgr.FindPlayerByID(realPlayerID)
if not curPlayer:
continue
curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleID, 0)
curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleTime, 0)
if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie or GameObj.GetHP(curPlayer) <= 0:
ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_System, tick, isAddSuperBuff=False)
- if "PosX" in info:
- curPlayer.ResetPos(info["PosX"], info["PosY"]) # 回到进去前的坐标
- curPlayer.SetFaction(0)
- PlayerControl.SetPlayerSightLevel(curPlayer, 0)
+ curPlayer.SetFaction(info.get("Faction", 0))
+ PlayerControl.SetPlayerSightLevel(curPlayer, info.get("SightLevel", 0))
+ PlayerControl.SetSight(curPlayer, ChConfig.Def_PlayerSight_Default)
GameObj.SetHPFull(curPlayer) # 回满血
SkillCommon.ResetAllSkillCD(curPlayer) # 重置技能CD
curPlayer.SetAttackTick(tick)
ChPlayer.__Sync_ClientBuff(curPlayer)
- # 所属玩家
- playerID = battle.playerID
- curPlayer = playerMgr.FindPlayerByID(playerID)
- if curPlayer:
- curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleID, 0)
- curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleTime, 0)
-
+ # 如果是真实地图战斗的,关闭副本
+ if battle.isChangeMap:
+ GameWorldProcess.CloseFB(GameWorld.GetGameWorld().GetTick())
return
def CreateMirrorPlayer(battleID, mirrorPlayerID, mirrorPlayerData, posX=0, posY=0, faction=0, curPlayer=None):
@@ -227,7 +289,10 @@
GameWorld.ErrLog("CreateMirrorPlayer mirrorPlayerID=%s,posX=%s,posY=%s,faction=%s"
% (mirrorPlayerID, posX, posY, faction), playerID)
return
- PlayerControl.SetCustomMap(mirrorPlayer, mapID, funcLineID)
+ if not battle.isChangeMap:
+ PlayerControl.SetCustomMap(mirrorPlayer, mapID, funcLineID)
+ else:
+ PlayerControl.SetCustomMap(mirrorPlayer, 0, 0)
mirrorID = mirrorPlayer.GetID()
realPlayerID = mirrorPlayer.GetRealPlayerID()
dataFightPower = PlayerControl.GetFightPower(mirrorPlayer)
@@ -289,8 +354,11 @@
realPlayerID = curPlayer.GetRealPlayerID()
posX = curPlayer.GetPosX()
posY = curPlayer.GetPosY()
+ faction = curPlayer.GetFaction()
sightLevel = curPlayer.GetSightLevel()
- GameWorld.DebugLog("realPlayerID=%s,posX=%s,posY=%s,sightLevel=%s" % (realPlayerID, posX, posY, sightLevel), playerID)
+ sight = curPlayer.GetSight()
+ GameWorld.DebugLog("realPlayerID=%s,posX=%s,posY=%s,faction=%s,sightLevel=%s,sight=%s"
+ % (realPlayerID, posX, posY, faction, sightLevel, sight), playerID)
GameWorld.DebugLog("生命=%s/%s, 护盾=%s/%s"
% (GameObj.GetHP(curPlayer), GameObj.GetMaxHP(curPlayer),
PlayerControl.GetProDef(curPlayer), PlayerControl.GetMaxProDef(curPlayer)), playerID)
@@ -394,21 +462,15 @@
# 创建战斗,玩家自身参与
if cmdType == 0:
- isSysbg = False
- requestID = playerID
- posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
- battlePlayerList = []
- battlePlayerList.append({"playerID":playerID, "faction":1, "posX":posX, "posY":posY})
- battlePlayerList.append({"playerID":tagPlayeID, "faction":2, "posX":posX + 5, "posY":posY})
- OnRequestCreateMirrorBattle(mapID, funcLineID, requestID, battlePlayerList, isSysbg, curPlayer)
+ OnRequestCreateMirrorBattle(mapID, funcLineID, playerID, [[playerID], [tagPlayeID]], False, curPlayer, True)
return
- # 开始战斗
- if cmdType == 1:
- battle = GetMirrorBattle(curPlayer)
- if battle:
- OnMirrorBattleStart(battle.battleID)
- return
+ # 开始战斗,该流程改为后端控制
+ #if cmdType == 1:
+ # battle = GetMirrorBattle(curPlayer)
+ # if battle:
+ # OnMirrorBattleStart(battle.battleID)
+ # return
# 战斗中跳过
if cmdType == 2:
@@ -419,48 +481,29 @@
# 不战斗直接跳过,即玩家没有参与,创建系统战斗场,之后扩展
if cmdType == 3:
- isSysbg = True
- requestID = playerID
- posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
- battlePlayerList = []
- battlePlayerList.append({"playerID":playerID, "faction":1, "posX":posX, "posY":posY})
- battlePlayerList.append({"playerID":tagPlayeID, "faction":2, "posX":posX + 5, "posY":posY})
- OnRequestCreateMirrorBattle(mapID, funcLineID, requestID, battlePlayerList, isSysbg, curPlayer)
+ OnRequestCreateMirrorBattle(mapID, funcLineID, playerID, [[playerID], [tagPlayeID]], True, curPlayer)
return
# 可不做验证,PK结束后由各个功能自行做结算验证
return
-def OnPlayerLeaveMap(curPlayer):
- ## 玩家离开地图
- if curPlayer.GetRealPlayerID():
- return
- battle = GetMirrorBattle(curPlayer)
- if not battle:
- return
-
- # 如果还在战斗中,直接快速执行战斗结果
- if battle.batState == ChConfig.Def_MirrorBatState_Fight:
- DoMirrorBattleQuick(battle.battleID, isLogout=True)
-
- # 统一退出
- if PlayerControl.GetCustomMapID(curPlayer):
- PlayerFB.DoExitCustomScene(curPlayer)
- return
-
-def OnRequestCreateMirrorBattle(mapID, funcLineID, requestID, battlePlayerList, isSysbg=False, curPlayer=None):
+def OnRequestCreateMirrorBattle(mapID, funcLineID, requestID, factionPlayerList, isSysbg=False, curPlayer=None, isChangeMap=False):
''' 请求创建镜像战斗,支持多对多,支持跨服,本服跨服地图中均可直接请求
@param mapID: 功能地图ID
@param funcLineID: 功能地图线路ID
@param requestID: 请求ID,如果是玩家发起的,一般传入玩家ID;如果是系统发起的,由系统自行决定,比如roomID之类
- @param battlePlayerList: 战斗的玩家信息列表 [{"playerID":玩家ID, "posX":坐标x, "posY":坐标y, "faction":阵营}, ...]
+ @param factionPlayerList: 战斗的阵营玩家列表 [[阵营1玩家ID, ...], [阵营2玩家ID, ...]]
@param isSysbg: 是否后台战斗,默认否,但是系统发起的默认是
@param curPlayer: 发起的玩家,为空时代表系统发起创建的
+ @param isChangeMap: 是否切战斗场景地图
'''
playerID = 0
if curPlayer:
- if not FBLogic.OnMirrorBattleRequest(curPlayer, mapID, funcLineID):
+ if GameWorld.IsCrossServer():
+ GameWorld.DebugLog("跨服服务器中不允许玩家镜像战斗请求!", playerID)
+ return
+ if not FBLogic.OnMirrorBattleRequest(curPlayer, mapID, funcLineID, factionPlayerList):
GameWorld.DebugLog("当前不允许该镜像战斗请求! mapID=%s,funcLineID=%s" % (mapID, funcLineID), playerID)
return
playerID = curPlayer.GetPlayerID()
@@ -477,27 +520,56 @@
else:
isSysbg = True # 系统发起的默认后台战斗
- mirrorIDList = []
- for battleInfo in battlePlayerList:
- batPlayerID = battleInfo["playerID"]
- faction = battleInfo["faction"]
- if batPlayerID == playerID and faction == 1 and not isSysbg:
- # 自己不用,使用自身进行战斗即可
- continue
- if batPlayerID not in mirrorIDList:
- mirrorIDList.append(batPlayerID)
-
+ mirrorIDList = [] # 需要使用镜像的玩家ID列表
+ for faction, batPlayerIDList in enumerate(factionPlayerList, 1):
+ for batPlayerID in batPlayerIDList:
+ if batPlayerID == playerID and faction == 1 and not isSysbg:
+ # 自己不用,使用自身进行战斗即可
+ continue
+ if batPlayerID not in mirrorIDList:
+ mirrorIDList.append(batPlayerID)
+
# 战斗相关的数据
- msgData = {"mapID":mapID, "funcLineID":funcLineID, "battlePlayerList":battlePlayerList, "isSysbg":isSysbg}
+ msgData = {"mapID":mapID, "funcLineID":funcLineID, "factionPlayerList":factionPlayerList, "isSysbg":isSysbg}
# 发送GameServer请求玩家打包数据
requestTime = curTime # 请求的时间戳,每个玩家最多允许同时存在一场战斗,每次重新请求后覆盖数据
- requestMapID = GameWorld.GetGameWorld().GetRealMapID()
- sendMsg = str({"msgType":"MirrorBattle", "msgData":msgData, "mirrorIDList":mirrorIDList,
- "requestTime":requestTime, "requestID":requestID, "requestMapID":requestMapID, "playerID":playerID})
+ sceneMapID = GameWorld.GetGameWorld().GetRealMapID()
+ sendMsg = {"msgType":"MirrorBattle", "msgData":msgData, "mirrorIDList":mirrorIDList,
+ "requestTime":requestTime, "requestID":requestID, "sceneMapID":sceneMapID, "playerID":playerID}
+
+ if isChangeMap:
+ # 默认切到PK地图
+ sendMsg["isChangeMap"] = 1
+ PlayerControl.PlayerEnterFB(curPlayer, mapID, funcLineID, reqInfoEx=sendMsg)
+ return True
+ sendMsg = str(sendMsg)
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "ReuestPlayerPackData", sendMsg, len(sendMsg))
GameWorld.DebugLog("请求创建镜像战斗: %s" % sendMsg, playerID)
return True
+
+def OnMirrorBattleEnterMapInit(curPlayer, tick):
+ ''' 镜像战斗初始化 - 需要切图的,玩家切图成功或地图收到打包数据同步时会触发,即这两个条件都准备好后才开始初始化
+ '''
+ if not curPlayer or curPlayer.IsEmpty() or not curPlayer.GetMapLoadOK():
+ return
+
+ battle = GetMirrorBattle(curPlayer)
+ if battle:
+ GameWorld.DebugLog("镜像战斗玩家断线重连成功!", curPlayer.GetPlayerID())
+ curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleID, battle.battleID)
+ curPlayer.SetFaction(1)
+ PlayerControl.SetPlayerSightLevel(curPlayer, battle.battleID)
+ PlayerControl.SetSight(curPlayer, ChConfig.Def_PlayerSight_Default * 3)
+ battle.SyncFBStepTime(tick)
+ return
+
+ playerID = curPlayer.GetPlayerID()
+ if playerID not in PyGameData.g_playerReqEnterFBEx:
+ return
+ msgInfo, packDataDict = PyGameData.g_playerReqEnterFBEx[playerID]
+ OnMirrorBattleInit(msgInfo, packDataDict, curPlayer)
+ return
def OnMirrorBattleInit(msgInfo, packDataDict, curPlayer=None):
''' 镜像战斗初始化
@@ -512,7 +584,7 @@
mapID = msgData.get("mapID", 0)
funcLineID = msgData.get("funcLineID", 0)
- battlePlayerList = msgData.get("battlePlayerList", [])
+ factionPlayerList = msgData.get("factionPlayerList", [])
isSysbg = msgData.get("isSysbg", 0) # 系统后台战斗
battleID = 0
@@ -529,28 +601,28 @@
if not battle:
GameWorld.ErrLog("镜像战场ID已存在! battleID=%s,msgInfo=%s" % (battleID, msgInfo), requestID)
return
+ battle.isChangeMap = msgInfo.get("isChangeMap", 0)
GameWorld.DebugLog("镜像战斗初始化: msgData=%s,packIDList=%s" % (msgData, packDataDict.keys()), battleID)
- for battleInfo in battlePlayerList:
- batPlayerID = battleInfo["playerID"]
- posX = battleInfo.get("posX", 0)
- posY = battleInfo.get("posY", 0)
- faction = battleInfo.get("faction", 0)
-
- if curPlayer and batPlayerID == playerID and faction == 1 and not isSysbg:
- battle.AddBattlePlayer(curPlayer, faction, posX, posY)
- continue
-
- packData = packDataDict.get(batPlayerID)
- if not packData:
- GameWorld.ErrLog("初始化镜像战斗时没有玩家镜像数据! batPlayerID=%s" % batPlayerID, playerID)
- continue
-
- CreateMirrorPlayer(battleID, batPlayerID, packData, posX, posY, faction, curPlayer)
-
- battle.batState = ChConfig.Def_MirrorBatState_Prepare
- fightTimeLimitDict = IpyGameDataPY.GetFuncEvalCfg("MirrorAttack", 1, {})
- battle.fightTickMax = fightTimeLimitDict.get(str(mapID), 60) * 1000 # 最大战斗时长,默认60秒
+ factionPosList = OnGetMirrorBattlePos(mapID, funcLineID, isSysbg)
+ for faction, batPlayerIDList in enumerate(factionPlayerList, 1):
+ posInfo = factionPosList[faction - 1]
+ factionPosX, factionPosY = posInfo
+ for index, batPlayerID in enumerate(batPlayerIDList):
+ posX, posY = factionPosX, factionPosY + index * 5
+ if curPlayer and batPlayerID == playerID and faction == 1 and not isSysbg:
+ battle.AddBattlePlayer(curPlayer, faction, posX, posY)
+ continue
+
+ packData = packDataDict.get(batPlayerID)
+ if not packData:
+ GameWorld.ErrLog("初始化镜像战斗时没有玩家镜像数据! batPlayerID=%s" % batPlayerID, playerID)
+ continue
+
+ CreateMirrorPlayer(battleID, batPlayerID, packData, posX, posY, faction, curPlayer)
+
+ tick = GameWorld.GetGameWorld().GetTick()
+ battle.ChangeBattleState(ChConfig.Def_MirrorBatState_Prepare, tick)
if not isSysbg:
return
@@ -558,7 +630,18 @@
# 系统场默认直接开始、快速战斗结束
OnMirrorBattleStart(battleID)
DoMirrorBattleQuick(battleID)
+ ClearMirrorBattleByID(battleID)
return
+
+def OnGetMirrorBattlePos(mapID, lineID, isSysbg=False):
+ if isSysbg:
+ gameMap = GameWorld.GetMap()
+ posX, posY = gameMap.GetRebornMapX(), gameMap.GetRebornMapY() # 系统战斗默认取当前地图的复活点
+ factionPosList = [[posX, posY], [posX + 5, posY]]
+ else:
+ factionPosDict = IpyGameDataPY.GetFuncEvalCfg("MirrorAttack", 4, {})
+ factionPosList = factionPosDict.get(mapID, [[10, 7], [40,37]])
+ return factionPosList
def OnMirrorBattleStart(battleID):
## 镜像战斗开始
@@ -567,8 +650,8 @@
return
if battle.batState >= ChConfig.Def_MirrorBatState_Fight:
return
- battle.batState = ChConfig.Def_MirrorBatState_Fight
- battle.startTick = GameWorld.GetGameWorld().GetTick()
+ tick = GameWorld.GetGameWorld().GetTick()
+ battle.ChangeBattleState(ChConfig.Def_MirrorBatState_Fight, tick)
return
def ProcessPlayerMirrorAI(curPlayer, tick):
@@ -576,31 +659,39 @@
battle = GetMirrorBattle(curPlayer)
if not battle:
return
+
playerID = curPlayer.GetPlayerID()
+ realPlayerID = curPlayer.GetRealPlayerID()
+ if realPlayerID:
+ # 用第一个对手镜像玩家来定时判断战斗阶段,因为玩家自身可能会掉线,所以不用自己,而用镜像玩家
+ if realPlayerID == battle.GetTagPlayerID():
+ if battle.stateTick and battle.CaclStateTick(tick) <= 0:
+ if battle.batState == ChConfig.Def_MirrorBatState_Prepare:
+ OnMirrorBattleStart(battle.battleID)
+ elif battle.batState == ChConfig.Def_MirrorBatState_Fight:
+ OnMirrorAttackOver(battle.battleID)
+ elif battle.batState == ChConfig.Def_MirrorBatState_Over:
+ ClearMirrorBattleByID(battle.battleID)
+ else:
+ # 常规战斗下,真实玩家不处理,由玩家自行控制
+ if not battle.isQuick:
+ return
+
if battle.batState != ChConfig.Def_MirrorBatState_Fight:
#GameWorld.DebugLog("镜像玩家仅自由战斗状态下需要处理! battleID=%s,batState=%s" % (battle.battleID, battle.batState), playerID)
return
- if not battle.isQuick:
- realPlayerID = curPlayer.GetRealPlayerID()
- if not realPlayerID:
- # 常规战斗下,真实玩家不处理,由玩家自行控制
- # 真实玩家附加判断是否PK超时
- if battle.startTick and battle.CaclFightTick(tick) <= 0:
- OnMirrorAttackOver(battle.battleID)
- return
-
if GameObj.GetHP(curPlayer) <= 0:
#GameWorld.DebugLog("镜像玩家已被击杀", playerID)
return
# 攻击间隔
if tick - curPlayer.GetPlayerAttackTick() < curPlayer.GetAtkInterval():
- GameWorld.DebugLog("攻击间隔: %s < %s" % (tick - curPlayer.GetPlayerAttackTick(), curPlayer.GetAtkInterval()), playerID)
+ #GameWorld.DebugLog("攻击间隔: %s < %s" % (tick - curPlayer.GetPlayerAttackTick(), curPlayer.GetAtkInterval()), playerID)
return
autoUseSkillList = battle.GetPlayerAutoUseSkillList(curPlayer)
- GameWorld.DebugLog("镜像AI攻击: autoUseSkillList=%s" % (autoUseSkillList), playerID)
+ #GameWorld.DebugLog("镜像AI攻击: autoUseSkillList=%s" % (autoUseSkillList), playerID)
if curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse:
PlayerHorse.PlayerRideHorseDown(curPlayer)
@@ -670,10 +761,10 @@
curPlayer.SetUseSkill(curSkill.GetSkillData())
useSkillData = curPlayer.GetUseSkill()
if not PlayerState.__DoClientUseSkillEx(curPlayer, useSkillData, tick):
- GameWorld.DebugLog(" 技能攻击失败: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID))
+ #GameWorld.DebugLog(" 技能攻击失败: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID))
continue
useSkillResult = True
- GameWorld.DebugLog(" 技能攻击成功: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID))
+ #GameWorld.DebugLog(" 技能攻击成功: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID))
if useSkillData and useSkillData.GetSkillID() != ChConfig.Def_SkillID_Somersault:
# 跟随玩家同频率攻击
@@ -735,7 +826,7 @@
battle = GetMirrorBattleByID(battleID)
if not battle:
return
- if battle.batState > ChConfig.Def_MirrorBatState_Fight:
+ if battle.batState != ChConfig.Def_MirrorBatState_Fight:
return
if battle.isQuick:
#不重复触发处理
@@ -747,22 +838,16 @@
if mapID in quickLimitMapIDList:
GameWorld.DebugLog("战斗中不允许点击快速战斗! mapID=%s" % mapID, battle.playerID)
return
- if isLogout:
- logoutQuickLimitMapIDList = IpyGameDataPY.GetFuncEvalCfg("MirrorAttack", 3)
- if mapID in logoutQuickLimitMapIDList:
- GameWorld.DebugLog("掉线不允许快速战斗! mapID=%s" % mapID, battle.playerID)
- return
tick = GameWorld.GetGameWorld().GetTick()
- battle.batState = ChConfig.Def_MirrorBatState_Fight
battle.isQuick = True
battle.isLogout = isLogout
- battle.CaclFightTick(tick)
+ battle.CaclStateTick(tick)
playerMgr = GameWorld.GetMapCopyPlayerManager()
perLoopTick = 100 # 每次循环视为已过毫秒
- maxLoopCount = battle.fightTickRemain / perLoopTick # 循环次数上限
- GameWorld.DebugLog("DoMirrorBattleQuick isLogout=%s,maxLoopCount=%s,tick=%s,fightTickRemain=%s"
- % (isLogout, maxLoopCount, tick, battle.fightTickRemain), battleID)
+ maxLoopCount = battle.stateTickRemain / perLoopTick # 循环次数上限
+ GameWorld.DebugLog("镜像PK快速结算: isLogout=%s,maxLoopCount=%s,tick=%s,stateTickRemain=%s"
+ % (isLogout, maxLoopCount, tick, battle.stateTickRemain), battleID)
# 屏蔽发包
for batPlayerID in battle.realIDDict.keys():
@@ -776,8 +861,7 @@
# 可能还没循环完毕就结束了
break
tick += perLoopTick # 修改每次循环的tick
- battle.CaclFightTick(tick)
- GameWorld.DebugLog(" loopCount=%s,tick=%s,fightTickRemain=%s" % (loopCount, tick, battle.fightTickRemain), battleID)
+ #GameWorld.DebugLog(" loopCount=%s,tick=%s,stateTickRemain=%s" % (loopCount, tick, battle.stateTickRemain), battleID)
for batPlayerID in battle.playerFactionDict.keys():
if batPlayerID in battle.deadPlayerIDList:
continue
@@ -846,10 +930,9 @@
if battle.batState >= ChConfig.Def_MirrorBatState_Over:
# 已经结算过
return
- battle.batState = ChConfig.Def_MirrorBatState_Over
tick = GameWorld.GetGameWorld().GetTick()
- if not battle.fightTickRemain:
- battle.CaclFightTick(tick)
+ if not battle.stateTickRemain:
+ battle.CaclStateTick(tick)
# 暂定没击杀算输,发起方为1
if not battle.winFaction:
battle.winFaction = 2
@@ -882,9 +965,72 @@
curPlayer.SetDead(curPlayer.GetDictByKey(ChConfig.Def_NPCDead_KillerID),
curPlayer.GetDictByKey(ChConfig.Def_NPCDead_KillerType))
+ #统计明细
+ for playerID, faction in battle.playerFactionDict.items():
+ player = playerMgr.FindPlayerByID(playerID)
+ if not player:
+ continue
+ realPlayerID = player.GetRealPlayerID()
+ hp = GameObj.GetHP(player)
+ hpMax = GameObj.GetMaxHP(player)
+
+ GameWorld.DebugLog("剩余血量: %s/%s, 护盾:%s/%s,playerID=%s,realPlayerID=%s,faction=%s"
+ % (hp, hpMax, PlayerControl.GetProDef(player), PlayerControl.GetMaxProDef(player), playerID, realPlayerID, faction), battleID)
+ if faction == 1:
+ battle.curHP += hp
+ battle.curHPMax += hpMax
+ else:
+ battle.tagHP += hp
+ battle.tagHPMax += hpMax
+
FBLogic.OnMirrorBattleOver(battleID, mapID)
- if battle.isSysbg:
- ClearMirrorBattleByID(battleID)
+ # 改变状态需放在最后
+ battle.ChangeBattleState(ChConfig.Def_MirrorBatState_Over, tick)
return
+def DoPlayerLeaveFB(curPlayer, tick):
+ ##玩家主动离开副本
+ if curPlayer.GetRealPlayerID():
+ return
+ battle = GetMirrorBattle(curPlayer)
+ if not battle:
+ return
+ GameWorld.DebugLog("玩家主动退出镜像战斗强制快速结算战斗!", curPlayer.GetPlayerID())
+ DoQuickOverByExit(curPlayer)
+ return
+
+def DoExitFB(curPlayer, tick):
+ ##玩家退出副本
+ if curPlayer.GetRealPlayerID():
+ return
+ battle = GetMirrorBattle(curPlayer)
+ if not battle:
+ return
+ # 退出时还有战场数据一般是掉线的,因为主动退出默认强制结算
+ mapID = battle.mapID
+ logoutQuickLimitMapIDList = IpyGameDataPY.GetFuncEvalCfg("MirrorAttack", 3)
+ if mapID in logoutQuickLimitMapIDList:
+ GameWorld.DebugLog("掉线不允许快速战斗! mapID=%s" % mapID, battle.playerID)
+ return
+ GameWorld.DebugLog("玩家掉线退出镜像战斗快速结算战斗!", curPlayer.GetPlayerID())
+ DoQuickOverByExit(curPlayer)
+ return
+
+def DoQuickOverByExit(curPlayer):
+ ## 执行退出快速结算
+
+ battle = GetMirrorBattle(curPlayer)
+ if not battle:
+ return
+
+ battleID = battle.battleID
+ if battle.batState < ChConfig.Def_MirrorBatState_Fight:
+ OnMirrorBattleStart(battleID) # 还未开始则强制开始
+
+ # 如果还在战斗中,直接快速执行战斗结果
+ if battle.batState == ChConfig.Def_MirrorBatState_Fight:
+ DoMirrorBattleQuick(battle.battleID, isLogout=True)
+
+ ClearMirrorBattleByID(battleID)
+ return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index fabb19b..5c81100 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1888,6 +1888,9 @@
#前端自定义场景地图
ClientCustomSceneList = [Def_FBMapID_PersonalBoss, Def_FBMapID_ArenaBattle, Def_FBMapID_MirrorBattle]
+#镜像PK的地图ID列表
+MirrorBattleMapIDList = [Def_FBMapID_MirrorBattle, Def_FBMapID_ArenaBattle, Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossChampionship]
+
#注册上传跨服服务器数据后直接进入跨服服务器的地图
RegisterEnter_CrossServerMapIDList = [Def_FBMapID_CrossPenglai, Def_FBMapID_CrossDemonLand, Def_FBMapID_CrossDemonKing,
Def_FBMapID_CrossGrasslandLing, Def_FBMapID_CrossGrasslandXian, Def_FBMapID_CrossBattlefield,
@@ -1927,15 +1930,16 @@
# 副本中玩家下线就被踢出
Def_DisconnectExit_FBID = []
#会有阵营的地图
-Def_MapID_NeedCamp = [Def_FBMapID_FamilyWar, Def_FBMapID_GatherSoul, Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossBattlefield]
+Def_MapID_NeedCamp = [Def_FBMapID_FamilyWar, Def_FBMapID_GatherSoul, Def_FBMapID_CrossBattlefield] + MirrorBattleMapIDList
# 进入副本需要根据请求lineID动态分配虚拟分线属性的地图
Def_MapID_LineIDToPropertyID = [Def_FBMapID_ElderBattlefield]
# 进入副本需要发送到GameServer的地图
Def_MapID_SendToGameServer = [Def_FBMapID_HorsePetBoss, Def_FBMapID_FamilyInvade, Def_FBMapID_SealDemon, Def_FBMapID_DemonKing,
- Def_FBMapID_FamilyWar, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss] + Def_MapID_LineIDToPropertyID + [Def_FBMapID_CrossChampionship]
-
+ Def_FBMapID_FamilyWar, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss] + \
+ Def_MapID_LineIDToPropertyID + [Def_FBMapID_CrossChampionship] + MirrorBattleMapIDList
+
# 刷新标识点在无玩家的情况下也需要刷新的地图
Def_NoPlayerNeedProcessRefreshPointMap = [Def_FBMapID_HorsePetBoss, Def_FBMapID_SealDemon, Def_FBMapID_GodArea, Def_FBMapID_BossHome, Def_FBMapID_GatherSoul, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss]
@@ -1952,9 +1956,6 @@
# 从副本退出时,可以返回进入前的副本ID
Def_CanBackFBMap = []
-
-# 当日换战盟不可进入的地图 (本项目为24小时)
-Def_ChangeFamilyCanNotEnterMap = []
#答题触发地图
Def_Subject_Map = [
@@ -2003,9 +2004,9 @@
'Guard':[Def_FBMapID_Guard], #守护副本
'SealDemon':[Def_FBMapID_SealDemon, Def_FBMapID_SealDemonEx], #封魔坛
'XMZZ':[Def_FBMapID_XMZZ], #仙魔之争
- 'ArenaBattle':[Def_FBMapID_ArenaBattle],#竞技场战斗
- 'CrossRealmPK':[Def_FBMapID_CrossRealmPK], #跨服竞技场
- 'CrossChampionship':[Def_FBMapID_CrossChampionship], #跨服排位
+ #'ArenaBattle':[Def_FBMapID_ArenaBattle],#竞技场战斗
+ #'CrossRealmPK':[Def_FBMapID_CrossRealmPK], #跨服竞技场
+ #'CrossChampionship':[Def_FBMapID_CrossChampionship], #跨服排位
'CrossDemonKing':[Def_FBMapID_DemonKing, Def_FBMapID_CrossDemonKing], #妖王
'CrossGrassland':[Def_FBMapID_CrossGrasslandLing, Def_FBMapID_CrossGrasslandXian], #草园
'GatherSoul':[Def_FBMapID_GatherSoul],#聚魂副本
@@ -2019,7 +2020,7 @@
'CrossBattlefield':[Def_FBMapID_CrossBattlefield], #跨服战场
'CrossFamilyFlagwar':[Def_FBMapID_CrossFamilyFlagwar], #跨服仙盟夺旗战/逐鹿万界
'MineArea':[Def_TFMapID_MineArea], #福地
- 'MirrorBattle':[Def_FBMapID_MirrorBattle], #镜像切磋
+ 'MirrorBattle':MirrorBattleMapIDList, #镜像切磋
}
#特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py
index 5aba18f..b189e3e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py
@@ -18,7 +18,6 @@
import GameWorld
import MirrorAttack
import PlayerViewCacheTube
-import PlayerFB
import ChConfig
## GM命令执行入口
@@ -29,63 +28,64 @@
def OnExec(curPlayer, paramList):
if not paramList:
GameWorld.DebugAnswer(curPlayer, "-------------------%s" % GameWorld.GetCurrentDataTimeStr())
- GameWorld.DebugAnswer(curPlayer, "创建战斗: PlayerMirror c 是否后台 [目标ID ID2 ...]")
- GameWorld.DebugAnswer(curPlayer, "开始战斗: PlayerMirror s")
+ GameWorld.DebugAnswer(curPlayer, "后台战斗: PlayerMirror s [玩家ID1 ID2 ...]")
+ GameWorld.DebugAnswer(curPlayer, "切图战斗: PlayerMirror m [功能地图ID 线路 目标ID]")
GameWorld.DebugAnswer(curPlayer, "跳过战斗: PlayerMirror q")
- GameWorld.DebugAnswer(curPlayer, "退出战斗: PlayerMirror e")
GameWorld.DebugAnswer(curPlayer, "更新镜像: PlayerMirror 5")
GameWorld.DebugAnswer(curPlayer, "加假数据: PlayerMirror a 个数 [起始ID 战力 区服ID 模版key]")
GameWorld.DebugAnswer(curPlayer, "删假数据: PlayerMirror d")
GameWorld.DebugAnswer(curPlayer, "输出数据: PlayerMirror p [起始索引 个数 ]")
- GameWorld.DebugAnswer(curPlayer, "是否后台:0-玩家自身参与战斗")
- GameWorld.DebugAnswer(curPlayer, "是否后台:1-玩家无感知,系统直接出结果")
- GameWorld.DebugAnswer(curPlayer, "目标ID:无-自己;>0-其他玩家ID支持跨服玩家ID")
- GameWorld.DebugAnswer(curPlayer, "目标ID多个时为多对多战斗")
- GameWorld.DebugAnswer(curPlayer, "多对多阵营分配均分AABBB即玩家和AA对BBB")
+ GameWorld.DebugAnswer(curPlayer, "多对多阵营分配ID为前后前后即AABB")
+ GameWorld.DebugAnswer(curPlayer, "后台战斗时ID阵营分配为[AABB]")
+ GameWorld.DebugAnswer(curPlayer, "切图战斗时ID阵营分配为[自己ABB]")
+ GameWorld.DebugAnswer(curPlayer, "玩家ID不填时默认自己跟自己打")
return
- mapID = ChConfig.Def_FBMapID_MirrorBattle
- lineID = 0
tick = GameWorld.GetGameWorld().GetTick()
playerID = curPlayer.GetPlayerID()
value1 = paramList[0]
- if value1 == "c":
- isSysbg = paramList[1] if len(paramList) > 1 else 0
- if not isSysbg:
- if not PlayerFB.DoEnterCustomScene(curPlayer, mapID, lineID, tick):
- GameWorld.DebugAnswer(curPlayer, "进入自定义PK创景失败:%s" % mapID)
- return
-
- mirrorIDList = paramList[2:]
+ if value1 == "s":
+ mapID = ChConfig.Def_FBMapID_MirrorBattle
+ lineID = 0
+ mirrorIDList = paramList[1:]
if not mirrorIDList:
- mirrorIDList.append(playerID)
+ mirrorIDList = [playerID, playerID]
+ elif len(mirrorIDList) == 1:
+ mirrorIDList = [playerID] + mirrorIDList
- factionIDListA, factionIDListB = [playerID], []
+ reqPlayer = curPlayer if mirrorIDList[0] == playerID else None # 第一个ID是玩家ID时代表属于玩家发起的后台战斗
+ requestID = playerID if curPlayer else GameWorld.GetGameWorld().GetTick()
+
+ factionIDListA, factionIDListB = [], []
while mirrorIDList:
- # 后面为对手
- factionIDListB.append(mirrorIDList.pop(-1))
- # 前面为队友
+ factionIDListA.append(mirrorIDList.pop(0))
if mirrorIDList:
- factionIDListA.append(mirrorIDList.pop(0))
-
- posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
- battlePlayerList = []
- for i, batPlayerID in enumerate(factionIDListA):
- battlePlayerList.append({"playerID":batPlayerID, "faction":1, "posX":posX, "posY":posY + i * 5})
- for i, batPlayerID in enumerate(factionIDListB):
- battlePlayerList.append({"playerID":batPlayerID, "faction":2, "posX":posX + 5, "posY":posY + i * 5})
+ factionIDListB.append(mirrorIDList.pop(-1))
+ factionPlayerList = [factionIDListA, factionIDListB]
+
+ if MirrorAttack.OnRequestCreateMirrorBattle(mapID, lineID, requestID, factionPlayerList, True, reqPlayer):
+ GameWorld.DebugAnswer(curPlayer, "后台战斗: %s VS %s" % (factionIDListA, factionIDListB))
+ else:
+ GameWorld.DebugAnswer(curPlayer, "后台战斗失败: %s VS %s" % (factionIDListA, factionIDListB))
+
+ elif value1 == "m":
+ mapID = paramList[1] if len(paramList) > 1 else ChConfig.Def_FBMapID_MirrorBattle
+ lineID = paramList[2] if len(paramList) > 2 else 0
+ mirrorIDList = [playerID] + paramList[3:]
+ if len(mirrorIDList) < 2:
+ mirrorIDList.append(playerID) # 默认和自己打
requestID = playerID
- if MirrorAttack.OnRequestCreateMirrorBattle(mapID, lineID, requestID, battlePlayerList, isSysbg, curPlayer):
- GameWorld.DebugAnswer(curPlayer, "请求创建镜像: %s VS %s" % (factionIDListA, factionIDListB))
- else:
- GameWorld.DebugAnswer(curPlayer, "请求创建镜像失败: %s VS %s" % (factionIDListA, factionIDListB))
-
- elif value1 == "s":
- battle = MirrorAttack.GetMirrorBattle(curPlayer)
- if battle:
- MirrorAttack.OnMirrorBattleStart(battle.battleID)
-
+ factionIDListA, factionIDListB = [], []
+ while mirrorIDList:
+ factionIDListA.append(mirrorIDList.pop(0))
+ if mirrorIDList:
+ factionIDListB.append(mirrorIDList.pop(-1))
+ factionPlayerList = [factionIDListA, factionIDListB]
+
+ reqOK = MirrorAttack.OnRequestCreateMirrorBattle(mapID, lineID, requestID, factionPlayerList, False, curPlayer, True)
+ GameWorld.DebugAnswer(curPlayer, "切图战斗: %s VS %s, %s" % (factionIDListA, factionIDListB, reqOK))
+
elif value1 == "q":
battle = MirrorAttack.GetMirrorBattle(curPlayer)
if battle:
@@ -93,9 +93,6 @@
GameWorld.DebugAnswer(curPlayer, "无法执行快速战斗,详见地图日志!")
return
- elif value1 == "e":
- PlayerFB.DoExitCustomScene(curPlayer)
-
elif value1 == 5:
tick = GameWorld.GetGameWorld().GetTick()
PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
index 42aa566..ad6f5fc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -2499,7 +2499,7 @@
return callFunc(curPlayer, mapID, funcLineID, tagType, tagID, valueList, fightRet, awardItemList, ret)
-def OnMirrorBattleRequest(curPlayer, mapID, funcLineID):
+def OnMirrorBattleRequest(curPlayer, mapID, funcLineID, factionPlayerList):
## 镜像战斗请求
do_FBLogic_ID = __GetFBLogic_MapID(mapID)
@@ -2509,7 +2509,7 @@
# 默认允许
return True
- return callFunc(curPlayer, mapID, funcLineID)
+ return callFunc(curPlayer, mapID, funcLineID, factionPlayerList)
def OnMirrorBattleOver(battleID, mapID):
## 镜像战斗结束
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ArenaBattle.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ArenaBattle.py
index c71d235..5e9d276 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ArenaBattle.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_ArenaBattle.py
@@ -14,30 +14,7 @@
#-------------------------------------------------------------------------------
#"""Version = 2020-12-07 19:30"""
#-------------------------------------------------------------------------------
-
-import PlayerArena
-
-## 是否能够通过活动查询进入
-def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
- return True
-
-## 是否需要做进入副本通用检查条件逻辑,默认需要检查
-def OnNeedCheckCanEnterFBComm(curPlayer, mapID, lineID):
- ## 进行中的不需要重复检查,防止断线重连被禁止进入
- return False
-
-## 客户端进入自定义场景
-def OnEnterCustomScene(curPlayer, mapID, lineID):
- return
-
-## 判断可否召唤木桩怪
-def OnCanSummonPriWoodPile(curPlayer, mapID, lineID, npcID, count):
- return True
-
-## 自定义场景副本击杀NPC
-def DoCustomScene_Player_KillNPC(curPlayer, curNPC, mapID, lineID):
- PlayerArena.OnKillBattleNPC(curPlayer, curNPC)
- return
-
-
+#
+# 改为使用镜像PK,逻辑统一放 GameLogic_MirrorBattle
+#
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossChampionship.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossChampionship.py
index e9b8e42..bdc0472 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossChampionship.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossChampionship.py
@@ -14,117 +14,6 @@
#-------------------------------------------------------------------------------
#"""Version = 2022-09-21 21:30"""
#-------------------------------------------------------------------------------
-
-import GameWorld
-import MirrorAttack
-import IPY_GameWorld
-import PlayerControl
-import CrossRealmPlayer
-import IpyGameDataPY
-import ShareDefine
-import FBCommon
-import GameObj
-
-
-###处理副本中杀死玩家逻辑
-def DoFBOnKill_Player(atkobj, defender, tick):
- GameWorld.DebugLog("镜像切磋击杀玩家: defID=%s" % (defender.GetID()), atkobj.GetID())
- return True
-
-def OnMirrorBattleRequest(curPlayer, mapID, funcLineID):
- ## 镜像战斗请求
-
- playerID = curPlayer.GetPlayerID()
- if GameWorld.IsCrossServer():
- return
-
- if not CrossRealmPlayer.IsCrossServerOpen():
- PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
- return
-
- if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie or GameObj.GetHP(curPlayer) == 0:
- GameWorld.DebugLog("已死亡,无法进行跨服排位赛!", playerID)
- return
-
- stateError = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossChampionshipStateError)
- if stateError:
- GameWorld.ErrLog("跨服排位状态已经异常无法进入! stateError=%s" % stateError, playerID)
- return
-
- state = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossChampionshipState)
- if state not in ShareDefine.CrossChampionshipEnterStateInfo:
- GameWorld.ErrLog("当前状态非跨服排位战斗状态无法进入: state=%s" % state, playerID)
- return
- groupMark = ShareDefine.CrossChampionshipEnterStateInfo[state]
- reqGroupMark = funcLineID % 100
- if reqGroupMark != groupMark:
- GameWorld.ErrLog("当前状态与跨服排位战斗分组不一致无法进入: funcLineID=%s,reqGroupMark=%s != %s" % (funcLineID, reqGroupMark, groupMark), playerID)
- return
-
- return True
-
-def OnMirrorBattleOver(battleID):
- ## 镜像战斗结束
-
- battle = MirrorAttack.GetMirrorBattleByID(battleID)
- if not battle:
- return
- mapID = battle.mapID
- funcLineID = battle.funcLineID
- isWin = battle.isWin
- curPlayerID = battle.requestID # 副本所属玩家ID,该玩家不一定参与实际战斗
- tagPlayerID = battle.GetTagPlayerID()
- fightTickRemain = battle.fightTickRemain
- curHPPer = 0 # 自己剩余血量百分比 0~100,支持小数点
- tagHPPer = 0 # 对方剩余血量百分比 0~100,支持小数点
-
- curPlayer = None
- playerMgr = GameWorld.GetMapCopyPlayerManager()
- for playerID, faction in battle.playerFactionDict.items():
- player = playerMgr.FindPlayerByID(playerID)
- if not player:
- continue
- realPlayerID = player.GetRealPlayerID()
- hp = GameObj.GetHP(player)
- hpMax = GameObj.GetMaxHP(player)
- hpPer = hp / float(hpMax) * 100
- GameWorld.DebugLog(" 剩余血量: %s/%s,hpPer=%s%%,playerID=%s,realPlayerID=%s,faction=%s"
- % (hp, hpMax, hpPer, playerID, realPlayerID, faction), battleID)
- if not realPlayerID and curPlayerID == playerID:
- curPlayer = player
- curHPPer = hpPer
- if tagPlayerID == realPlayerID:
- tagHPPer = hpPer
-
- if not curPlayer:
- return
-
- baseScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossChamMirrorPK", 2)
- baseScore = 0
- if baseScoreList and len(baseScoreList) == 2:
- baseScore = baseScoreList[0] if battle.isWin else baseScoreList[1]
- hpScore = int(eval(IpyGameDataPY.GetFuncCompileCfg("CrossChamMirrorPK", 3)))
- GameWorld.DebugLog(" hpScore=%s,curHPPer=%s,tagHPPer=%s" % (hpScore, curHPPer, tagHPPer), battleID)
- remainTimePer = fightTickRemain / float(battle.fightTickMax) * 100 # 剩余战斗时间百分比
- timeScore = int(eval(IpyGameDataPY.GetFuncCompileCfg("CrossChamMirrorPK", 4)))
- addScore = baseScore + hpScore + timeScore
- GameWorld.DebugLog(" timeScore=%s,remainTimePer=%s%%,fightTickRemain=%s,fightTickMax=%s" % (timeScore, remainTimePer, fightTickRemain, battle.fightTickMax), battleID)
-
- pkCountMax = IpyGameDataPY.GetFuncCfg("CrossChamMirrorPK", 1)
- playerID = curPlayer.GetPlayerID()
- dataMsg = {
- "playerID":playerID,
- "tagPlayerID":tagPlayerID,
- "funcLineID":funcLineID,
- "isWin":isWin,
- "addScore":addScore,
- "baseScore":baseScore,
- "hpScore":hpScore,
- "timeScore":timeScore,
- "pkCountMax":pkCountMax,
- }
- GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_ChampionshipPKOver, dataMsg)
- overDict = {"isWin":isWin, "tagPlayerID":tagPlayerID, "addScore":addScore, "baseScore":baseScore, "hpScore":hpScore, "timeScore":timeScore}
- FBCommon.NotifyFBOver(curPlayer, mapID, funcLineID, isWin, overDict)
- return
-
+#
+# 改为使用镜像PK,逻辑统一放 GameLogic_MirrorBattle
+#
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py
index 31247dc..5dea30f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossRealmPK.py
@@ -14,65 +14,6 @@
#-------------------------------------------------------------------------------
#"""Version = 2018-12-21 18:00"""
#-------------------------------------------------------------------------------
-
-import GameWorld
-import MirrorAttack
-import PlayerCrossRealmPK
-import GameObj
-
-###处理副本中杀死玩家逻辑
-def DoFBOnKill_Player(atkobj, defender, tick):
- GameWorld.DebugLog("镜像切磋击杀玩家: defID=%s" % (defender.GetID()), atkobj.GetID())
- return True
-
-def OnMirrorBattleRequest(curPlayer, mapID, funcLineID):
- ## 镜像战斗请求
-
- if not PlayerCrossRealmPK.CheckCanMatch(curPlayer):
- return
-
- if not PlayerCrossRealmPK.CheckHavePKCount(curPlayer):
- return
-
- return True
-
-
-def OnMirrorBattleOver(battleID):
- ## 镜像战斗结束
-
- battle = MirrorAttack.GetMirrorBattleByID(battleID)
- if not battle:
- return
- isLogout = battle.isLogout
-
- mapID = battle.mapID
- funcLineID = battle.funcLineID
- winFaction = battle.winFaction
- curPlayerID = battle.requestID # 副本所属玩家ID,该玩家不一定参与实际战斗
- curIsWin = 0
- tagPlayerID = 0
- GameWorld.DebugLog("镜像战斗结算: mapID=%s,funcLineID=%s,winFaction=%s,isLogout=%s" % (mapID, funcLineID, winFaction, isLogout), battleID)
-
- playerMgr = GameWorld.GetMapCopyPlayerManager()
- for playerID, faction in battle.playerFactionDict.items():
- curPlayer = playerMgr.FindPlayerByID(playerID)
- if not curPlayer:
- continue
- realPlayerID = curPlayer.GetRealPlayerID()
- isWin = (faction == winFaction)
- GameWorld.DebugLog("剩余血量: %s/%s,playerID=%s,realPlayerID=%s,faction=%s,isWin=%s"
- % (GameObj.GetHP(curPlayer), GameObj.GetMaxHP(curPlayer), playerID, realPlayerID, faction, isWin), battleID)
- if isWin and faction == 1:
- curIsWin = 1
- if faction != 1 and not tagPlayerID:
- tagPlayerID = realPlayerID
-
- if not curPlayerID:
- return
-
- curPlayer = playerMgr.FindPlayerByID(curPlayerID)
- if not curPlayer:
- return
-
- PlayerCrossRealmPK.SendPKOver(curPlayer, tagPlayerID, curIsWin)
- return
+#
+# 改为使用镜像PK,逻辑统一放 GameLogic_MirrorBattle
+#
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py
index bb16b47..ef2477c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MirrorBattle.py
@@ -15,22 +15,101 @@
#"""Version = 2024-10-17 15:00"""
#-------------------------------------------------------------------------------
-import GameWorld
+import ChConfig
+import ShareDefine
import MirrorAttack
+import PlayerControl
+import IpyGameDataPY
+import PlayerCrossRealmPK
+import CrossRealmPlayer
+import PlayerArena
+import GameWorld
import FBCommon
-import GameObj
-## 是否能够通过活动查询进入
-def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
- return True
+def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
+ return MirrorAttack.OnGetMirrorBattlePos(mapID, lineId)[0]
-## 客户端进入自定义场景
-def OnEnterCustomScene(curPlayer, mapID, lineID):
+def DoEnterFB(curPlayer, tick):
+ playerID = curPlayer.GetPlayerID()
+ GameWorld.Log("---------------- 镜像战斗DoEnterFB ----------------", playerID)
+ MirrorAttack.OnMirrorBattleEnterMapInit(curPlayer, tick)
return
+
+def DoExitFB(curPlayer, tick):
+ ##玩家退出副本
+ MirrorAttack.DoExitFB(curPlayer, tick)
+ return
+
+def DoPlayerLeaveFB(curPlayer, tick):
+ ##玩家主动离开副本
+ MirrorAttack.DoPlayerLeaveFB(curPlayer, tick)
+ return
+
+def CheckPlayersRelation_IsFriend(curPlayer, curTagPlayer):
+ return not CanAttackPlayer(curPlayer, curTagPlayer)
+
+def CanAttackPlayer(curPlayer, curTagPlayer):
+ battle = MirrorAttack.GetMirrorBattle(curPlayer)
+ if not battle:
+ return
+
+ if battle.batState != ChConfig.Def_MirrorBatState_Fight:
+ return
+
+ if curTagPlayer:
+ if curPlayer.GetFaction() == curTagPlayer.GetFaction():
+ return
+
+ return True
##处理副本中杀死玩家逻辑
def DoFBOnKill_Player(atkobj, defender, tick):
GameWorld.DebugLog("镜像切磋击杀玩家: defID=%s" % (defender.GetID()), atkobj.GetID())
+ return True
+
+def OnMirrorBattleRequest(curPlayer, mapID, funcLineID, factionPlayerList):
+ ## 镜像战斗请求
+
+ if mapID == ChConfig.Def_FBMapID_CrossRealmPK:
+ return __CheckRequest_CrossRealmPK(curPlayer, mapID, funcLineID)
+
+ if mapID == ChConfig.Def_FBMapID_CrossChampionship:
+ return __CheckRequest_CrossChampionship(curPlayer, mapID, funcLineID)
+
+ return True
+
+def __CheckRequest_CrossRealmPK(curPlayer, mapID, funcLineID):
+ if not CrossRealmPlayer.IsCrossServerOpen():
+ PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
+ return
+ if not PlayerCrossRealmPK.CheckCanMatch(curPlayer):
+ return
+ if not PlayerCrossRealmPK.CheckHavePKCount(curPlayer):
+ return
+ return True
+
+def __CheckRequest_CrossChampionship(curPlayer, mapID, funcLineID):
+
+ playerID = curPlayer.GetPlayerID()
+ if not CrossRealmPlayer.IsCrossServerOpen():
+ PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
+ return
+
+ stateError = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossChampionshipStateError)
+ if stateError:
+ GameWorld.ErrLog("跨服排位状态已经异常无法进入! stateError=%s" % stateError, playerID)
+ return
+
+ state = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossChampionshipState)
+ if state not in ShareDefine.CrossChampionshipEnterStateInfo:
+ GameWorld.ErrLog("当前状态非跨服排位战斗状态无法进入: state=%s" % state, playerID)
+ return
+ groupMark = ShareDefine.CrossChampionshipEnterStateInfo[state]
+ reqGroupMark = funcLineID % 100
+ if reqGroupMark != groupMark:
+ GameWorld.ErrLog("当前状态与跨服排位战斗分组不一致无法进入: funcLineID=%s,reqGroupMark=%s != %s" % (funcLineID, reqGroupMark, groupMark), playerID)
+ return
+
return True
def OnMirrorBattleOver(battleID):
@@ -39,35 +118,73 @@
battle = MirrorAttack.GetMirrorBattleByID(battleID)
if not battle:
return
- isLogout = battle.isLogout
-
mapID = battle.mapID
funcLineID = battle.funcLineID
- winFaction = battle.winFaction
- curPlayerID = battle.requestID # 副本所属玩家ID,该玩家不一定参与实际战斗
- curIsWin = 0
- GameWorld.DebugLog("镜像战斗结算: mapID=%s,funcLineID=%s,winFaction=%s,isLogout=%s" % (mapID, funcLineID, winFaction, isLogout), battleID)
-
- playerMgr = GameWorld.GetMapCopyPlayerManager()
- for playerID, faction in battle.playerFactionDict.items():
- curPlayer = playerMgr.FindPlayerByID(playerID)
- if not curPlayer:
- continue
- realPlayerID = curPlayer.GetRealPlayerID()
- isWin = (faction == winFaction)
- GameWorld.DebugLog("剩余血量: %s/%s,playerID=%s,realPlayerID=%s,faction=%s,isWin=%s"
- % (GameObj.GetHP(curPlayer), GameObj.GetMaxHP(curPlayer), playerID, realPlayerID, faction, isWin), battleID)
- if isWin and faction == 1:
- curIsWin = 1
-
- if not curPlayerID:
- return
-
- curPlayer = playerMgr.FindPlayerByID(curPlayerID)
+ isWin = battle.isWin
+ curPlayerID = battle.playerID # 副本所属玩家ID,该玩家不一定参与实际战斗
+ tagPlayerID = battle.GetTagPlayerID()
+ curPlayer = GameWorld.GetMapCopyPlayerManager().FindPlayerByID(curPlayerID)
if not curPlayer:
return
- # 结算奖励,通知结果
+
+ if mapID == ChConfig.Def_FBMapID_ArenaBattle:
+ arenaPlayerID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleTagID)
+ if tagPlayerID == arenaPlayerID:
+ PlayerArena.SendGameServer_ArenaBattleOver(curPlayer, isWin)
+ else:
+ GameWorld.DebugLog("非竞技场对手不结算! tagPlayerID=%s,arenaPlayerID=%s" % (tagPlayerID, arenaPlayerID), curPlayerID)
+ return
+
+ if mapID == ChConfig.Def_FBMapID_CrossRealmPK:
+ PlayerCrossRealmPK.SendPKOver(curPlayer, tagPlayerID, isWin)
+ return
+
+ if mapID == ChConfig.Def_FBMapID_CrossChampionship:
+ __MirrorBattleOver_CrossChampionship(curPlayer, battle)
+ return
+
giveItemList = []
- overDict = {"isWin":curIsWin, FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(giveItemList)}
- FBCommon.NotifyFBOver(curPlayer, mapID, funcLineID, isWin, overDict)
+ overDict = {"isWin":isWin, FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(giveItemList)}
+ FBCommon.NotifyFBOver(curPlayer, mapID, funcLineID, isWin, overDict)
return
+
+def __MirrorBattleOver_CrossChampionship(curPlayer, battle):
+ playerID = curPlayer.GetPlayerID()
+ mapID = battle.mapID
+ funcLineID = battle.funcLineID
+ isWin = battle.isWin
+ tagPlayerID = battle.GetTagPlayerID()
+ curHPPer, tagHPPer = battle.CalcHPPer()
+ remainTimePer = battle.CalcRemainTimePer()
+
+ baseScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossChamMirrorPK", 2)
+ baseScore = 0
+ if baseScoreList and len(baseScoreList) == 2:
+ baseScore = baseScoreList[0] if isWin else baseScoreList[1]
+ hpScore = int(eval(IpyGameDataPY.GetFuncCompileCfg("CrossChamMirrorPK", 3)))
+ GameWorld.DebugLog(" hpScore=%s,curHPPer=%s,tagHPPer=%s" % (hpScore, curHPPer, tagHPPer), playerID)
+
+ timeScore = int(eval(IpyGameDataPY.GetFuncCompileCfg("CrossChamMirrorPK", 4)))
+ GameWorld.DebugLog(" timeScore=%s,remainTimePer=%s%%" % (timeScore, remainTimePer), playerID)
+
+ addScore = baseScore + hpScore + timeScore
+ GameWorld.DebugLog(" addScore=%s,baseScore=%s" % (addScore, baseScore), playerID)
+
+ pkCountMax = IpyGameDataPY.GetFuncCfg("CrossChamMirrorPK", 1)
+ playerID = curPlayer.GetPlayerID()
+ dataMsg = {
+ "playerID":playerID,
+ "tagPlayerID":tagPlayerID,
+ "funcLineID":funcLineID,
+ "isWin":isWin,
+ "addScore":addScore,
+ "baseScore":baseScore,
+ "hpScore":hpScore,
+ "timeScore":timeScore,
+ "pkCountMax":pkCountMax,
+ }
+ GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_ChampionshipPKOver, dataMsg)
+ overDict = {"isWin":isWin, "tagPlayerID":tagPlayerID, "addScore":addScore, "baseScore":baseScore, "hpScore":hpScore, "timeScore":timeScore}
+ FBCommon.NotifyFBOver(curPlayer, mapID, funcLineID, isWin, overDict)
+ return
+
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 565b682..b6b3a52 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
@@ -199,6 +199,11 @@
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleTagID, tagPlayerID)
return
+ if tagPlayerID >= 10000:
+ if result:
+ GameWorld.DebugLog("真人由后端镜像PK决定胜负! tagPlayerID=%s" % tagPlayerID, playerID)
+ return
+
isWin = 1 if result == 1 else 0
# # 木桩被击杀,后端判断,其他前端同步
# if isWin:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index 942d3bc..35b52f9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -1358,8 +1358,6 @@
PassiveBuffEffMng.OnPlayerLeaveMap(curPlayer)
- MirrorAttack.OnPlayerLeaveMap(curPlayer)
-
#离开地图清空恶意攻击自己玩家信息
if curPlayer.GetPlayerID() in PyGameData.g_maliciousAttackDict:
PyGameData.g_maliciousAttackDict.pop(curPlayer.GetPlayerID())
@@ -1375,6 +1373,7 @@
PyGameData.g_playerFuncAttrDict.pop(playerID, None)
PyGameData.g_playerEquipPartAttrDict.pop(playerID, None)
PyGameData.g_equipChangeClassLVInfo.pop(playerID, None)
+ PyGameData.g_playerReqEnterFBEx.pop(playerID, None)
NPCCommon.ClearPriWoodPile(curPlayer)
#移除地图缓存的境界难度玩家ID信息
for playerIDList in PyGameData.g_realmDiffPlayerDict.values():
@@ -1860,39 +1859,20 @@
# @param posY 坐标Y
# @return 返回值无意义
# @remarks 玩家单独进入副本
-def PlayerEnterFB(curPlayer, mapID, lineID, posX=0, posY=0):
+def PlayerEnterFB(curPlayer, mapID, lineID, posX=0, posY=0, reqInfoEx=None):
mapID = FBCommon.GetRecordMapID(mapID)
- GameWorld.Log("玩家请求进入副本! mapID=%s,lineID=%s,posX=%s,posY=%s"
- % (mapID, lineID, posX, posY), curPlayer.GetPlayerID())
+ playerID = curPlayer.GetPlayerID()
+ PyGameData.g_playerReqEnterFBEx[playerID] = reqInfoEx
+ GameWorld.Log("玩家请求进入副本! mapID=%s,lineID=%s,posX=%s,posY=%s,reqInfoEx=%s" % (mapID, lineID, posX, posY, reqInfoEx), playerID)
- # 当日换战盟不可进入的地图, 改为按小时算
- #if mapID in ChConfig.Def_ChangeFamilyCanNotEnterMap:
- # if PlayerFamily.GetPlayerChangeFamilyPastHour(curPlayer) < 24:
- # NotifyCode(curPlayer, 'jiazu_xyj_671654')
- # return
-
-# #跨服活动人数分流处理
-# if GameWorld.IsCrossServer():
-# reqMapID = mapID
-# mapID = __GetMergeFBPlayerMapID(curPlayer, reqMapID)
-# if not mapID:
-# GameWorld.ErrLog("找不到可分配进入的跨服活动地图ID! reqMapID=%s" % reqMapID)
-# return
-
- #过滤封包地图ID
- if not GameWorld.GetMap().IsMapIDExist(mapID):
- GameWorld.ErrLog('###非法地图数据,mapID: %s' % (mapID), curPlayer.GetID())
- return
-
-# if not GameWorld.GetMap().CanMove(curPlayer.GetPosX(), curPlayer.GetPosY()):
-# # 坐标不可移动则不能传送,不然会导致退出副本无法退回来源地
-# GameWorld.ErrLog("原障碍点无法切换地图 %s" % ([curPlayer.GetPosX(), curPlayer.GetPosY()]))
-# return
-
#进入副本通用检查
fbIpyData = FBCommon.GetFBIpyData(mapID)
fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, lineID)
sceneMapID = mapID if not fbLineIpyData else fbLineIpyData.GetMapID()
+ #过滤封包地图ID
+ if not GameWorld.GetMap().IsMapIDExist(sceneMapID):
+ GameWorld.ErrLog('###非法地图数据,sceneMapID: %s' % (sceneMapID), curPlayer.GetID())
+ return
tick = GameWorld.GetGameWorld().GetTick()
if CheckMoveToFB(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData, tick) != ShareDefine.EntFBAskRet_OK:
return
@@ -1953,10 +1933,13 @@
elif mapID in ChConfig.Def_MapID_LineIDToPropertyID:
enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)
extendParamList = [enterCnt]
+ elif mapID in ChConfig.MirrorBattleMapIDList:
+ reqInfoEx["sceneMapID"] = sceneMapID
+ extendParamList = [reqInfoEx]
SendToGameServerEnterFB(curPlayer, mapID, lineID, tick, extendParamList)
return
- PlayerResetWorldPosFB(curPlayer, mapID, posX, posY, False, fbID, funcLineID=lineID)
+ PlayerResetWorldPosFB(curPlayer, sceneMapID, posX, posY, False, fbID, funcLineID=lineID)
return
##发送到GameServer请求进入副本
@@ -1977,7 +1960,7 @@
#GameWorld.DebugLog("send GameServer_QueryPlayerByID")
# 请求GameServer目标副本GameWorld索引
sendMsg = [mapID, lineID]
- sendMsg.extend(extendParamList)
+ sendMsg += extendParamList
sendMsg = "%s" % sendMsg
curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_EnterFB, 0, 'EnterFB', sendMsg, len(sendMsg))
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py
index 8213c7e..c9daacc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py
@@ -38,7 +38,6 @@
import ShareDefine
import GameFuncComm
import FBHelpBattle
-import MirrorAttack
import SkillShell
import PyGameData
import PetControl
@@ -513,7 +512,6 @@
curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneStepTick, tick)
PlayerControl.SetCustomMap(curPlayer, mapID, lineID)
NPCCommon.ClearPriWoodPile(curPlayer)
- MirrorAttack.ClearMirrorBattleByPlayer(curPlayer)
GameWorld.Log("玩家开始自定义场景!mapID=%s,lineID=%s" % (mapID, lineID), playerID)
if mapID:
PetControl.DoLogic_PetLoadMapOK(curPlayer)
@@ -549,7 +547,6 @@
if mapID and FBCommon.GetCustomMapStep(curPlayer, mapID, lineID) != ChConfig.CustomMapStep_Over:
FBCommon.SetCustomMapStep(curPlayer, mapID, lineID, ChConfig.CustomMapStep_Over)
NPCCommon.ClearPriWoodPile(curPlayer)
- MirrorAttack.ClearMirrorBattleByPlayer(curPlayer)
#默认回满血
if GameObj.GetHP(curPlayer) > 0 and curPlayer.GetPlayerAction() != IPY_GameWorld.paDie and GameObj.GetHP(curPlayer) < GameObj.GetMaxHP(curPlayer):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_EnterFB.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_EnterFB.py
index fb0caad..71c5577 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_EnterFB.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_EnterFB.py
@@ -271,6 +271,8 @@
return
# 传送逻辑
- PlayerControl.PlayerResetWorldPosFB(curPlayer, mapID, retPos[0], retPos[1], False, backFBID, funcLineID=funcLineID)
+ fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, funcLineID)
+ sceneMapID = mapID if not fbLineIpyData else fbLineIpyData.GetMapID()
+ PlayerControl.PlayerResetWorldPosFB(curPlayer, sceneMapID, retPos[0], retPos[1], False, backFBID, funcLineID=funcLineID)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_PlayerMirror.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_PlayerMirror.py
index cb61794..591d97a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_PlayerMirror.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_PlayerMirror.py
@@ -18,6 +18,7 @@
import GameWorld
import MirrorAttack
import PlayerViewCacheTube
+import PyGameData
#---------------------------------------------------------------------
# @param query_Type 请求类型
@@ -33,6 +34,14 @@
if msgType == "MirrorBattle":
curPlayer = None
playerID = msgInfo.get("playerID", 0)
+ isChangeMap = msgInfo.get("isChangeMap", 0)
+ # 是切图的战斗
+ if isChangeMap and playerID:
+ PyGameData.g_playerReqEnterFBEx[playerID] = [msgInfo, packDataDict]
+ curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+ MirrorAttack.OnMirrorBattleEnterMapInit(curPlayer, tick)
+ return
+
if playerID:
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
if not curPlayer or curPlayer.IsEmpty():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index f0a87cb..7d2a050 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -18,6 +18,7 @@
g_realmDiffPlayerDict = {} # 境界难度玩家信息 {realm:[playerID, ...], ...}
g_realmDiffNPCRefresh = {} # {(lineID, realm):{refreshID:tagNPCRefresh, ...}}
+g_playerReqEnterFBEx = {} # 请求进入地图额外信息 {playerID:[...], ...}
g_commMapLinePlayerCountDict = {} # 常规地图分线人数 {mapID:{lineID:人数, ...}}
g_needRefreshMapServerState = True # 常规地图分线人数是否有变更需要通知
g_mapLastProcess_Minute = -1 # 地图上次处理的分钟
--
Gitblit v1.8.0