10263 【越南】【英文】【BT】后端支持NPC仿真实玩家战斗和快速战斗(改为真实地图战斗;竞技场、跨服PK、跨服排位赛,测试地图100均已支持;)
| | |
| | | import CrossBattlefield
|
| | | import CrossRealmPlayer
|
| | | import CrossChampionship
|
| | | import PlayerPackData
|
| | | import DataRecordPack
|
| | | import CrossRealmMsg
|
| | | import PyDataManager
|
| | |
| | | # @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)
|
| | |
| | | #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()
|
| | |
| | | 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:
|
| | |
| | | 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
|
| | | # # 玩家发起的
|
| | | # 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:
|
| | |
| | | import OperControlManager
|
| | | import PlayerViewCacheTube
|
| | | import PassiveBuffEffMng
|
| | | import GameWorldProcess
|
| | | import ChNetSendPack
|
| | | import IpyGameDataPY
|
| | | import AttackCommon
|
| | |
| | |
|
| | | import time
|
| | |
|
| | | Def_StateTimeList = [3, 60, 10] # 默认阶段时长,秒
|
| | |
|
| | | class MirrorBattle():
|
| | | ## 某场战斗
|
| | |
|
| | |
| | | return
|
| | |
|
| | | def Clear(self):
|
| | | self.isChangeMap = 0 # 是否切图战斗的
|
| | | self.isSysbg = False # 是否系统后台进行战斗的,玩家无感知,仅知道结果
|
| | | self.requestID = 0 # 请求ID,一般是玩家ID或者系统自定的ID,如某一场PK的标识信息
|
| | | self.playerID = 0 # 所属玩家ID,可能为0
|
| | |
| | | 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, ...}
|
| | |
| | | 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()
|
| | |
| | | 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)
|
| | |
| | | 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
|
| | |
| | |
|
| | | def GetMirrorBattle(curPlayer):
|
| | | ## 获取玩家实例所属的战场
|
| | | if curPlayer.GetRealPlayerID():
|
| | | return GetMirrorBattleByID(curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID))
|
| | | return GetMirrorBattleByID(curPlayer.GetPlayerID())
|
| | |
|
| | | def GetMirrorBattleByID(battleID):
|
| | | battle = None
|
| | |
| | | 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()
|
| | |
|
| | |
| | | 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):
|
| | |
| | | GameWorld.ErrLog("CreateMirrorPlayer mirrorPlayerID=%s,posX=%s,posY=%s,faction=%s"
|
| | | % (mirrorPlayerID, posX, posY, faction), playerID)
|
| | | return
|
| | | 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)
|
| | |
| | | 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)
|
| | |
| | |
|
| | | # 创建战斗,玩家自身参与
|
| | | 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:
|
| | |
| | |
|
| | | # 不战斗直接跳过,即玩家没有参与,创建系统战斗场,之后扩展
|
| | | 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()
|
| | |
| | | else:
|
| | | isSysbg = True # 系统发起的默认后台战斗
|
| | |
|
| | | mirrorIDList = []
|
| | | for battleInfo in battlePlayerList:
|
| | | batPlayerID = battleInfo["playerID"]
|
| | | faction = battleInfo["faction"]
|
| | | mirrorIDList = [] # 需要使用镜像的玩家ID列表
|
| | | for faction, batPlayerIDList in enumerate(factionPlayerList, 1):
|
| | | for batPlayerID in batPlayerIDList:
|
| | | if batPlayerID == playerID and faction == 1 and not isSysbg:
|
| | | # 自己不用,使用自身进行战斗即可
|
| | | continue
|
| | |
| | | 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):
|
| | | ''' 镜像战斗初始化
|
| | |
| | |
|
| | | 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
|
| | |
| | | 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)
|
| | | |
| | | 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
|
| | |
| | |
|
| | | 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秒
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | battle.ChangeBattleState(ChConfig.Def_MirrorBatState_Prepare, tick)
|
| | |
|
| | | if not isSysbg:
|
| | | return
|
| | |
| | | # 系统场默认直接开始、快速战斗结束
|
| | | 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):
|
| | | ## 镜像战斗开始
|
| | |
| | | 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):
|
| | |
| | | battle = GetMirrorBattle(curPlayer)
|
| | | if not battle:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | if battle.batState != ChConfig.Def_MirrorBatState_Fight:
|
| | | #GameWorld.DebugLog("镜像玩家仅自由战斗状态下需要处理! battleID=%s,batState=%s" % (battle.battleID, battle.batState), playerID)
|
| | | 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 not battle.isQuick:
|
| | | realPlayerID = curPlayer.GetRealPlayerID()
|
| | | if not realPlayerID:
|
| | | # 常规战斗下,真实玩家不处理,由玩家自行控制
|
| | | # 真实玩家附加判断是否PK超时
|
| | | if battle.startTick and battle.CaclFightTick(tick) <= 0:
|
| | | OnMirrorAttackOver(battle.battleID)
|
| | | if battle.batState != ChConfig.Def_MirrorBatState_Fight:
|
| | | #GameWorld.DebugLog("镜像玩家仅自由战斗状态下需要处理! battleID=%s,batState=%s" % (battle.battleID, battle.batState), playerID)
|
| | | return
|
| | |
|
| | | if GameObj.GetHP(curPlayer) <= 0:
|
| | |
| | |
|
| | | # 攻击间隔
|
| | | 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)
|
| | |
| | | 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:
|
| | | # 跟随玩家同频率攻击
|
| | |
| | | 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:
|
| | | #不重复触发处理
|
| | |
| | | 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():
|
| | |
| | | # 可能还没循环完毕就结束了
|
| | | 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
|
| | |
| | | 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
|
| | |
| | | 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
|
| | |
| | | #前端自定义场景地图
|
| | | 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,
|
| | |
| | | # 副本中玩家下线就被踢出
|
| | | 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]
|
| | |
| | |
|
| | | # 从副本退出时,可以返回进入前的副本ID
|
| | | Def_CanBackFBMap = []
|
| | |
|
| | | # 当日换战盟不可进入的地图 (本项目为24小时)
|
| | | Def_ChangeFamilyCanNotEnterMap = []
|
| | |
|
| | | #答题触发地图
|
| | | Def_Subject_Map = [
|
| | |
| | | '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],#聚魂副本
|
| | |
| | | 'CrossBattlefield':[Def_FBMapID_CrossBattlefield], #跨服战场
|
| | | 'CrossFamilyFlagwar':[Def_FBMapID_CrossFamilyFlagwar], #跨服仙盟夺旗战/逐鹿万界
|
| | | 'MineArea':[Def_TFMapID_MineArea], #福地
|
| | | 'MirrorBattle':[Def_FBMapID_MirrorBattle], #镜像切磋
|
| | | 'MirrorBattle':MirrorBattleMapIDList, #镜像切磋
|
| | | }
|
| | |
|
| | | #特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
|
| | |
| | | import GameWorld
|
| | | import MirrorAttack
|
| | | import PlayerViewCacheTube
|
| | | import PlayerFB
|
| | | import ChConfig
|
| | |
|
| | | ## GM命令执行入口
|
| | |
| | | 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))
|
| | | # 前面为队友
|
| | | if mirrorIDList:
|
| | | factionIDListA.append(mirrorIDList.pop(0))
|
| | | if mirrorIDList:
|
| | | factionIDListB.append(mirrorIDList.pop(-1))
|
| | | factionPlayerList = [factionIDListA, factionIDListB]
|
| | |
|
| | | 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})
|
| | | 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))
|
| | | factionIDListA, factionIDListB = [], []
|
| | | while mirrorIDList:
|
| | | factionIDListA.append(mirrorIDList.pop(0))
|
| | | if mirrorIDList:
|
| | | factionIDListB.append(mirrorIDList.pop(-1))
|
| | | factionPlayerList = [factionIDListA, factionIDListB]
|
| | |
|
| | | elif value1 == "s":
|
| | | battle = MirrorAttack.GetMirrorBattle(curPlayer)
|
| | | if battle:
|
| | | MirrorAttack.OnMirrorBattleStart(battle.battleID)
|
| | | 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 not MirrorAttack.DoMirrorBattleQuick(battle.battleID, isClick=True):
|
| | | GameWorld.DebugAnswer(curPlayer, "无法执行快速战斗,详见地图日志!")
|
| | | return
|
| | | |
| | | elif value1 == "e":
|
| | | PlayerFB.DoExitCustomScene(curPlayer)
|
| | |
|
| | | elif value1 == 5:
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | |
| | |
|
| | | 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)
|
| | |
|
| | |
| | | # 默认允许
|
| | | return True
|
| | |
|
| | | return callFunc(curPlayer, mapID, funcLineID)
|
| | | return callFunc(curPlayer, mapID, funcLineID, factionPlayerList)
|
| | |
|
| | | def OnMirrorBattleOver(battleID, mapID):
|
| | | ## 镜像战斗结束
|
| | |
| | | #-------------------------------------------------------------------------------
|
| | | #"""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
|
| | | #
|
| | |
|
| | |
| | | #-------------------------------------------------------------------------------
|
| | | #"""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
|
| | | # |
| | |
| | | #-------------------------------------------------------------------------------
|
| | | #"""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
|
| | | # |
| | |
| | | #"""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):
|
| | |
| | | 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)}
|
| | | 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
|
| | |
|
| | |
| | | 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:
|
| | |
| | |
|
| | | PassiveBuffEffMng.OnPlayerLeaveMap(curPlayer)
|
| | |
|
| | | MirrorAttack.OnPlayerLeaveMap(curPlayer)
|
| | | |
| | | #离开地图清空恶意攻击自己玩家信息
|
| | | if curPlayer.GetPlayerID() in PyGameData.g_maliciousAttackDict:
|
| | | PyGameData.g_maliciousAttackDict.pop(curPlayer.GetPlayerID())
|
| | |
| | | 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():
|
| | |
| | | # @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())
|
| | | |
| | | # 当日换战盟不可进入的地图, 改为按小时算
|
| | | #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
|
| | | 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)
|
| | |
|
| | | #进入副本通用检查
|
| | | 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
|
| | |
| | | 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请求进入副本
|
| | |
| | | #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
|
| | |
| | | import ShareDefine
|
| | | import GameFuncComm
|
| | | import FBHelpBattle
|
| | | import MirrorAttack
|
| | | import SkillShell
|
| | | import PyGameData
|
| | | import PetControl
|
| | |
| | | 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)
|
| | |
| | | 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):
|
| | |
| | | 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
|
| | |
|
| | |
| | | import GameWorld
|
| | | import MirrorAttack
|
| | | import PlayerViewCacheTube
|
| | | import PyGameData
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | # @param query_Type 请求类型
|
| | |
| | | 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():
|
| | |
| | | g_realmDiffPlayerDict = {} # 境界难度玩家信息 {realm:[playerID, ...], ...}
|
| | | g_realmDiffNPCRefresh = {} # {(lineID, realm):{refreshID:tagNPCRefresh, ...}}
|
| | |
|
| | | g_playerReqEnterFBEx = {} # 请求进入地图额外信息 {playerID:[...], ...}
|
| | | g_commMapLinePlayerCountDict = {} # 常规地图分线人数 {mapID:{lineID:人数, ...}}
|
| | | g_needRefreshMapServerState = True # 常规地图分线人数是否有变更需要通知
|
| | | g_mapLastProcess_Minute = -1 # 地图上次处理的分钟
|