ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
@@ -58,16 +58,29 @@
        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.mirrorIDDict = {} # 该场所有玩家镜像实例ID对应真实ID {playerID:realPlayerID, ...}
        self.realIDDict = {} # 该场所有真实玩家对应初始信息 {playerID:{k:v, ...}, ...}
        self.playerFactionDict = {} # 该场所有玩家阵营信息,真实玩家+镜像玩家 {playerID:faction, ...}
        self.playerAutoSkillInfo = {} # 玩家自动释放技能列表 {playerID:[skillTypeID, ...], ...}
        self.deadPlayerIDList = [] # 已被击杀的玩家ID列表
        self.tagPlayerIDList = [] # 对手真实玩家ID列表
        
        self.isLogout = False # 是否下线的
        self.isQuick = False # 是否快速战斗结束的
        self.isWin = False # 是否获胜
        self.winFaction = 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 AddBattlePlayer(self, curPlayer, faction, posX=0, posY=0):
        playerID = curPlayer.GetPlayerID()
@@ -220,6 +233,8 @@
    dataFightPower = PlayerControl.GetFightPower(mirrorPlayer)
    GameWorld.DebugLog("CreateMirrorPlayer mirrorID=%s,realPlayerID=%s,mapID=%s,funcLineID=%s,posX=%s,posY=%s,faction=%s,dataFightPower=%s,,accID=%s" 
                       % (mirrorID, realPlayerID, mapID, funcLineID, posX, posY, faction, dataFightPower, mirrorPlayer.GetAccID()), playerID)
    if faction != 1:
        battle.tagPlayerIDList.append(realPlayerID)
    
    ChPlayer.InitPlayerPack(mirrorPlayer)
    PlayerHorse.PlayerRideHorseUp(mirrorPlayer, False, False)
@@ -399,7 +414,7 @@
    if cmdType == 2:
        battle = GetMirrorBattle(curPlayer)
        if battle:
            DoMirrorBattleQuick(battle.battleID)
            DoMirrorBattleQuick(battle.battleID, isClick=True)
        return
    
    # 不战斗直接跳过,即玩家没有参与,创建系统战斗场,之后扩展
@@ -426,7 +441,7 @@
    
    # 如果还在战斗中,直接快速执行战斗结果
    if battle.batState == ChConfig.Def_MirrorBatState_Fight:
        DoMirrorBattleQuick(battle.battleID, True)
        DoMirrorBattleQuick(battle.battleID, isLogout=True)
        
    # 统一退出
    if PlayerControl.GetCustomMapID(curPlayer):
@@ -534,6 +549,8 @@
        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秒
    
    if not isSysbg:
        return
@@ -551,6 +568,7 @@
    if battle.batState >= ChConfig.Def_MirrorBatState_Fight:
        return
    battle.batState = ChConfig.Def_MirrorBatState_Fight
    battle.startTick = GameWorld.GetGameWorld().GetTick()
    return
def ProcessPlayerMirrorAI(curPlayer, tick):
@@ -567,6 +585,9 @@
        realPlayerID = curPlayer.GetRealPlayerID()
        if not realPlayerID:
            # 常规战斗下,真实玩家不处理,由玩家自行控制
            # 真实玩家附加判断是否PK超时
            if battle.startTick and battle.CaclFightTick(tick) <= 0:
                OnMirrorAttackOver(battle.battleID)
            return
        
    if GameObj.GetHP(curPlayer) <= 0:
@@ -709,22 +730,39 @@
    curPlayer.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
    return
def DoMirrorBattleQuick(battleID, isLogout=False):
def DoMirrorBattleQuick(battleID, isLogout=False, isClick=False):
    ## 执行快速战斗
    battle = GetMirrorBattleByID(battleID)
    if not battle:
        return
    if battle.batState > ChConfig.Def_MirrorBatState_Fight:
        return
    if battle.isQuick:
        #不重复触发处理
        return
    mapID = battle.mapID
    if not battle.isSysbg:
        if isClick:
            quickLimitMapIDList = IpyGameDataPY.GetFuncEvalCfg("MirrorAttack", 2)
            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)
    
    playerMgr = GameWorld.GetMapCopyPlayerManager()
    perLoopTick = 100 # 每次循环视为已过毫秒
    maxLoopCount = 60 * 1000 / perLoopTick # 循环次数上限,暂定最长PK时长60秒
    GameWorld.DebugLog("DoMirrorBattleQuick isLogout=%s,maxLoopCount=%s,tick=%s" % (isLogout, maxLoopCount, tick), battleID)
    maxLoopCount = battle.fightTickRemain / perLoopTick # 循环次数上限
    GameWorld.DebugLog("DoMirrorBattleQuick isLogout=%s,maxLoopCount=%s,tick=%s,fightTickRemain=%s"
                       % (isLogout, maxLoopCount, tick, battle.fightTickRemain), battleID)
    
    # 屏蔽发包
    for batPlayerID in battle.realIDDict.keys():
@@ -737,8 +775,9 @@
        if battle.batState != ChConfig.Def_MirrorBatState_Fight:
            # 可能还没循环完毕就结束了
            break
        tick += loopCount * perLoopTick # 修改每次循环的tick
        GameWorld.DebugLog("    loopCount=%s,tick=%s" % (loopCount, tick), battleID)
        tick += perLoopTick # 修改每次循环的tick
        battle.CaclFightTick(tick)
        GameWorld.DebugLog("    loopCount=%s,tick=%s,fightTickRemain=%s" % (loopCount, tick, battle.fightTickRemain), battleID)
        for batPlayerID in battle.playerFactionDict.keys():
            if batPlayerID in battle.deadPlayerIDList:
                continue
@@ -765,14 +804,11 @@
                
            ProcessPlayerMirrorAI(curPlayer, tick)
            
    if battle.winFaction:
        # 已经有获胜方了,代表已经触发过结算胜负
        return
    # 暂定没击杀算输,发起方为1
    # 没有获胜方
    if not battle.winFaction:
    GameWorld.DebugLog("没有击败对方阵营!", battleID)
    battle.winFaction = 2
    OnMirrorAttackOver(battleID)
    return
    return True
def OnPlayerDead(curPlayer):
    battleID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID)
@@ -811,13 +847,20 @@
        # 已经结算过
        return
    battle.batState = ChConfig.Def_MirrorBatState_Over
    tick = GameWorld.GetGameWorld().GetTick()
    if not battle.fightTickRemain:
        battle.CaclFightTick(tick)
    # 暂定没击杀算输,发起方为1
    if not battle.winFaction:
        battle.winFaction = 2
    battle.isWin = 1 if battle.winFaction == 1 else 0
    mapID = battle.mapID
    funcLineID = battle.funcLineID
    winFaction = battle.winFaction
    isQuick = battle.isQuick
    isLogout = battle.isLogout
    GameWorld.DebugLog("镜像战斗结束: mapID=%s,funcLineID=%s,winFaction=%s,isQuick=%s,isLogout=%s"
                       % (mapID, funcLineID, winFaction, isQuick, isLogout), battleID)
    GameWorld.DebugLog("镜像战斗结束: mapID=%s,funcLineID=%s,winFaction=%s,isWin=%s,isQuick=%s,isLogout=%s"
                       % (mapID, funcLineID, winFaction, battle.isWin, isQuick, isLogout), battleID)
    
    playerMgr = GameWorld.GetMapCopyPlayerManager()