ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -77,10 +77,29 @@
def DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick):
    playerID = curPlayer.GetPlayerID()
    posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
    factionListA, factionListB = [], []
    factionListA.append(curPlayer)
    curPet = curPlayer.GetPetMgr().GetFightPet()
    curPet and factionListA.append(curPet)
    # 玩家阵营的其他战斗实例,可扩展...
    assistNPCID = 0 # 协助召唤兽
    if assistNPCID:
        assistNPC = NPCCommon.SummonNPC(curPlayer, assistNPCID, posX, posY)
        assistNPC and factionListA.append(assistNPC)
    tagObj = None
    if tagPlayerID:
        npcID = ChConfig.Def_NPCID_PVP
        tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID, pvpPlayerID=tagPlayerID)
        tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID, pvpPlayerID=tagPlayerID)
        if not tagObj:
            return
        factionListB.append(tagObj)
        # 对手玩家镜像的其他战斗实例...
    else:
        ipyData = IpyGameDataPY.GetIpyGameData("FBTurn", mapID, funcLineID)
        if not ipyData:
@@ -88,91 +107,83 @@
        npcID = ipyData.GetNPCID()
        if not npcID:
            return
        tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID)
    if not tagObj:
        tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID)
        if not tagObj:
            return
        factionListB.append(tagObj)
        summerNPCID = ipyData.GetSummerNPCID()
        if summerNPCID:
            summerNPC = NPCCommon.SummonNPC(tagObj, summerNPCID, posX, posY)
            summerNPC and factionListB.append(summerNPC)
    if not factionListB:
        return
    
    turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1)
    curPet = curPlayer.GetPetMgr().GetFightPet()
    tagPet = None
    for gameObj in factionListA:
        GameObj.SetFaction(gameObj, 1)
    for gameObj in factionListB:
        GameObj.SetFaction(gameObj, 2)
    #一个回合攻击顺序,由攻击速度决定,攻速相同下阵营1先攻击,还相同则由ID决定
    fightObjList = factionListA + factionListB
    fightObjList.sort(key=lambda o: (GameObj.GetAtkSpeed(o), (10 - GameObj.GetFaction(o)), o.GetID()), reverse=True)
    
    turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1)
    GameWorld.DebugLog("===== 执行回合制战斗: mapID=%s,funcLineID=%s,tagPlayerID=%s,tagObjID=%s" 
                       % (mapID, funcLineID, tagPlayerID, tagObj.GetID()), playerID)
    GameWorld.DebugLog("curPlayer.GetSightLevel=%s,tagObj.GetSightLevel=%s"
                       % (curPlayer.GetSightLevel(), tagObj.GetSightLevel()), playerID)
    #一个回合攻击顺序
    #1. 快方宠物攻击,不存在跳过
    #2. 慢方宠物攻击,不存在跳过
    #3. 快方主体攻击
    #4. 慢方主体攻击
    # 战斗前初始化
    factionObjMax = 0 # 某个阵营的最大战斗实例数
    factionObjDict = {1:[curPet, curPlayer], 2:[tagPet, tagObj]}
    for objList in factionObjDict.values():
        if factionObjMax < len(objList):
            factionObjMax = len(objList)
        for gameObj in objList:
            TurnFightObjStartInit(gameObj)
    curAtkSpeed = GameObj.GetAtkSpeed(curPlayer)
    tagAtkSpeed = GameObj.GetAtkSpeed(tagObj)
    orderList = [1, 2] if curAtkSpeed >= tagAtkSpeed else [2, 1]
    GameWorld.DebugLog("playerHP=%s,tagHP=%s,curAtkSpeed=%s,tagAtkSpeed=%s"
                       % (GameObj.GetHP(curPlayer), GameObj.GetHP(tagObj), curAtkSpeed, tagAtkSpeed), playerID)
    for gameObj in fightObjList:
        TurnFightObjStartInit(gameObj)
    isWin = None
    for turnNum in range(1, turnMax + 1):
        GameWorld.DebugLog("----- 回合制战斗轮次: %s -----" % turnNum, playerID)
        SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Fighting, turnNum, turnMax)
        
        # 回合开始: 做一些每回合重置逻辑或者某些根据回合触发的效果等
        for objList in factionObjDict.values():
            for gameObj in objList:
                TurnFightObjTurnStart(gameObj, turnNum)
        for gameObj in fightObjList:
            TurnFightObjPerTurnStart(gameObj, turnNum)
        # 回合战斗: 轮流依次攻击
        for index in range(factionObjMax):
            for faction in orderList:
                objList = factionObjDict[faction]
                if index >= len(objList):
                    continue
                gameObj = objList[index]
                if not gameObj:
                    continue
                tagGameObj = tagObj if faction == 1 else curPlayer
                objType = gameObj.GetGameObjType()
                objID = gameObj.GetID()
                tagObjType = tagGameObj.GetGameObjType()
                tagObjID = tagGameObj.GetID()
                GameWorld.DebugLog("    行动: turnNum=%s,index=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s"
                                   % (turnNum, index, faction, objType, objID, tagObjType, tagObjID), playerID)
                DoAttack(gameObj, tagGameObj, tick)
                if tagGameObj and GameObj.GetHP(tagGameObj) > 0:
                    continue
                isWin = faction == 1
                GameWorld.DebugLog("        tagObjType=%s,tagObjID=%s,被击杀,结束战斗: isWin=%s" % (tagObjType, tagObjID, isWin))
                break
        for actNum, gameObj in enumerate(fightObjList, 1):
            if not gameObj:
                continue
            faction = GameObj.GetFaction(gameObj)
            tagGameObj = tagObj if faction == 1 else curPlayer
            objType = gameObj.GetGameObjType()
            objID = gameObj.GetID()
            tagObjType = tagGameObj.GetGameObjType()
            tagObjID = tagGameObj.GetID()
            
            if isWin != None:
                break
            GameWorld.DebugLog("    行动: turnNum=%s,actNum=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s"
                               % (turnNum, actNum, faction, objType, objID, tagObjType, tagObjID), playerID)
            DoAttack(gameObj, tagGameObj, tick)
            
            playerDead = GameObj.GetHP(curPlayer) <= 0
            tagObjDead = (not tagObj or GameObj.GetHP(tagObj) <= 0)
            if not playerDead and not tagObjDead:
                continue
            if playerDead and tagObjDead:
                isWin = False # 平局算失败
                GameWorld.DebugLog("        双方被击杀,平局算失败: isWin=%s" % isWin)
            elif playerDead:
                isWin = False
                GameWorld.DebugLog("        玩家被击杀,失败: isWin=%s" % isWin)
            elif tagObjDead:
                isWin = True # 胜利
                GameWorld.DebugLog("        对手被击杀,胜利: isWin=%s" % isWin)
            break
        if isWin != None:
            break
        
    overState = FightState_Win if isWin else FightState_Fail
    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, overState, turnNum, turnMax)
    
    for objList in factionObjDict.values():
        for gameObj in objList:
            TurnFightObjOverReset(gameObj)
    for gameObj in fightObjList:
        TurnFightObjOverReset(gameObj)
    GameWorld.DebugLog("===== 回合制战斗结束: mapID=%s,funcLineID=%s,tagPlayerID=%s,isWin=%s,overState=%s" 
                       % (mapID, funcLineID, tagPlayerID, isWin, overState), playerID)
    return
@@ -187,6 +198,10 @@
    gameObj.RefreshView()
    
    objType = gameObj.GetGameObjType()
    npcID = gameObj.GetNPCID() if objType == IPY_GameWorld.gotNPC else 0
    GameWorld.DebugLog("    初始化实例: objID=%s,npcID=%s,faction=%s,atkSpeed=%s,HP=%s"
                       % (gameObj.GetID(), npcID, GameObj.GetFaction(gameObj), GameObj.GetAtkSpeed(gameObj), GameObj.GetHP(gameObj)))
    # 重置技能CD、战斗buff
    if objType == IPY_GameWorld.gotPlayer:            
        skillManager = gameObj.GetSkillManager()
@@ -198,7 +213,7 @@
        pass
    return
def TurnFightObjTurnStart(gameObj, turnNum):
def TurnFightObjPerTurnStart(gameObj, turnNum):
    ## 回合制战斗实例 - 每回合开始时处理
    if not gameObj:
        return
@@ -223,18 +238,34 @@
        return
    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 0)
    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0)
    GameObj.SetFaction(gameObj, 0)
    
    objType = gameObj.GetGameObjType()
    if objType == IPY_GameWorld.gotPlayer:
        pass
    
    elif objType == IPY_GameWorld.gotNPC:
        npcObjType = gameObj.GetGameNPCObjType()
        if npcObjType != IPY_GameWorld.gnotPet and GameObj.GetHP(gameObj):
            NPCCommon.SetDeadEx(gameObj)
        RecycleObj(gameObj)
    return
def RecycleObj(gameObj):
    npcObjType = gameObj.GetGameNPCObjType()
    if npcObjType == IPY_GameWorld.gnotPet:
        #GameWorld.DebugLog("RecycleObj 灵宠不回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
        return
    if npcObjType == IPY_GameWorld.gnotSummon:
        curOwner = NPCCommon.GetSummonOwnerDetel(gameObj)
        if curOwner and curOwner.GetGameObjType() == IPY_GameWorld.gotNPC:
            #GameWorld.DebugLog("RecycleObj 召唤兽主人是NPC不回收 objID=%s,npcObjType=%s,%s,ownerID=%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID(), curOwner.GetID()))
            return
    if GameObj.GetHP(gameObj) <= 0:
        #GameWorld.DebugLog("RecycleObj 已死亡,不用重复回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
        return
    #GameWorld.DebugLog("RecycleObj: objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
    NPCCommon.SetDeadEx(gameObj)
    return
def DoAttack(curObj, tagObj, tick):
    curID = curObj.GetID()
    tagID = tagObj.GetID()