From bcaa39b97f1e9789e7960a0101430b1dccbae426 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 30 十一月 2023 15:37:09 +0800
Subject: [PATCH] 10019 【砍树】回合战斗(与NPC基础回合战斗)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                |   14 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py        |   60 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py    |   72 +++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py      |   23 ++
 PySysDB/PySysDBPY.h                                                                       |    9 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py |    2 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                             |   60 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py  |  275 +++++++++++++++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                         |   72 +++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py           |    3 
 10 files changed, 588 insertions(+), 2 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 204ad62..80e6844 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -880,6 +880,15 @@
 	eval		RewardInfo;	//奖励信息
 };
 
+//副本回合制表
+
+struct tagFBTurn
+{
+	DWORD		_DataMapID;	//数据地图ID
+	WORD		_LineID;	//功能线路ID
+	DWORD		NPCID;	//NPCID
+};
+
 //副本助战表
 
 struct tagFBHelpBattle
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 3014e24..a967c1f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -20357,6 +20357,66 @@
 
 
 #------------------------------------------------------
+# B4 10 回合制战斗 #tagCMTurnFight
+
+class  tagCMTurnFight(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("MapID", c_int),    # 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
+                  ("FuncLineID", c_ushort),    
+                  ("PlayerID", c_int),    # 对应玩家ID,可为0,某些功能可能有用,如竞技场
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x10
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB4
+        self.SubCmd = 0x10
+        self.MapID = 0
+        self.FuncLineID = 0
+        self.PlayerID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMTurnFight)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 10 回合制战斗 //tagCMTurnFight:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                MapID:%d,
+                                FuncLineID:%d,
+                                PlayerID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.MapID,
+                                self.FuncLineID,
+                                self.PlayerID
+                                )
+        return DumpString
+
+
+m_NAtagCMTurnFight=tagCMTurnFight()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMTurnFight.Cmd,m_NAtagCMTurnFight.SubCmd))] = m_NAtagCMTurnFight
+
+
+#------------------------------------------------------
 # B5 14 拍卖行竞价物品 #tagCMBiddingAuctionItem
 
 class  tagCMBiddingAuctionItem(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 03c840d..e72f5df 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -47123,6 +47123,78 @@
 
 
 #------------------------------------------------------
+# B4 20 回合制战斗状态 #tagMCTurnFightState
+
+class  tagMCTurnFightState(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("MapID", c_int),    # 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
+                  ("FuncLineID", c_ushort),    
+                  ("PlayerID", c_int),    # 对应玩家ID,可为0,某些功能可能有用,如竞技场
+                  ("State", c_ubyte),    # 0-开始;1-进行中;2-结束
+                  ("TurnNum", c_ubyte),    # 当前轮次
+                  ("TurnMax", c_ubyte),    # 最大轮次
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x20
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB4
+        self.SubCmd = 0x20
+        self.MapID = 0
+        self.FuncLineID = 0
+        self.PlayerID = 0
+        self.State = 0
+        self.TurnNum = 0
+        self.TurnMax = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCTurnFightState)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 20 回合制战斗状态 //tagMCTurnFightState:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                MapID:%d,
+                                FuncLineID:%d,
+                                PlayerID:%d,
+                                State:%d,
+                                TurnNum:%d,
+                                TurnMax:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.MapID,
+                                self.FuncLineID,
+                                self.PlayerID,
+                                self.State,
+                                self.TurnNum,
+                                self.TurnMax
+                                )
+        return DumpString
+
+
+m_NAtagMCTurnFightState=tagMCTurnFightState()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTurnFightState.Cmd,m_NAtagMCTurnFightState.SubCmd))] = m_NAtagMCTurnFightState
+
+
+#------------------------------------------------------
 # C1 09 跨服排位玩家信息 #tagMCChampionshipPlayerInfo
 
 class  tagMCChampionshipPlayerInfo(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 07ad34e..dbba4b9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1867,4 +1867,16 @@
 
 PacketCMD_1=0xA5
 PacketSubCMD_1=0x26
-PacketCallFunc_1=OnVisitFairyDomain
\ No newline at end of file
+PacketCallFunc_1=OnVisitFairyDomain
+
+;缥缈仙域
+[TurnAttack]
+ScriptName = Attack\TurnAttack.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 1
+
+PacketCMD_1=0xB4
+PacketSubCMD_1=0x10
+PacketCallFunc_1=OnTurnFight
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
new file mode 100644
index 0000000..097fed2
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -0,0 +1,275 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package TurnAttack
+#
+# @todo:回合制攻击逻辑
+# @author hxp
+# @date 2023-11-30
+# @version 1.0
+#
+# 详细描述: 回合制攻击逻辑
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2023-11-30 15:30"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import AICommon
+import BaseAttack
+import PlayerState
+import IpyGameDataPY
+import IPY_GameWorld
+import ChPyNetSendPack
+import NetPackCommon
+import PlayerControl
+import SkillCommon
+import NPCCommon
+import GameWorld
+import GameObj
+
+(
+FightState_Start,
+FightState_Fighting,
+FightState_Win,
+FightState_Fail,
+FightState_Over,
+) = range(5)
+
+#// B4 10 回合制战斗 #tagCMTurnFight
+#
+#struct    tagCMTurnFight
+#{
+#    tagHead        Head;
+#    DWORD        MapID;    // 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
+#    WORD        FuncLineID;
+#    DWORD        PlayerID;    // 对应玩家ID,可为0,某些功能可能有用,如竞技场
+#};
+def OnTurnFight(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    mapID = clientData.MapID
+    funcLineID = clientData.FuncLineID
+    tagPlayerID = clientData.PlayerID
+    
+    if curPlayer.GetSightLevel() != curPlayer.GetID():
+        PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
+        
+    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Start)
+    
+    DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick)
+    
+    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Over)
+    return
+
+def DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick):
+    playerID = curPlayer.GetPlayerID()
+    tagObj = None
+    if tagPlayerID:
+        pass
+    
+    else:
+        ipyData = IpyGameDataPY.GetIpyGameData("FBTurn", mapID, funcLineID)
+        if not ipyData:
+            return
+        npcID = ipyData.GetNPCID()
+        if not npcID:
+            return
+        tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID)
+        
+    if not tagObj:
+        return
+    
+    turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1)
+    curPet = curPlayer.GetPetMgr().GetFightPet()
+    tagPet = None
+    
+    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)
+            
+    curSpeed = 0
+    tagSpeed = 0
+    orderList = [1, 2] if curSpeed >= tagSpeed else [2, 1]
+    GameWorld.DebugLog("playerHP=%s,tagHP=%s,curSpeed=%s,tagSpeed=%s" 
+                       % (GameObj.GetHP(curPlayer), GameObj.GetHP(tagObj), curSpeed, tagSpeed), playerID)
+    
+    isWin = None
+    for turnNum in range(1, turnMax + 1):
+        GameWorld.DebugLog("回合制战斗轮次: %s" % turnNum, playerID)
+        SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Fighting, turnNum, turnMax)
+        for index in range(factionObjMax):
+            for faction in orderList:
+                objList = factionObjDict[faction]
+                if index >= len(objList):
+                    continue
+                gameObj = objList[index]
+                if not gameObj:
+                    continue
+                gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, turnNum)                
+                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)
+                if objType == IPY_GameWorld.gotPlayer: 
+                    PlayerAttack(gameObj, tagGameObj, tick)
+                else:
+                    NPCAttack(gameObj, tagGameObj, tick)
+                    
+                if tagGameObj and GameObj.GetHP(tagGameObj) > 0:
+                    GameWorld.DebugLog("        playerHP=%s,tagHP=%s" % (GameObj.GetHP(curPlayer), GameObj.GetHP(tagObj)), playerID)
+                    continue
+                
+                isWin = faction == 1
+                GameWorld.DebugLog("        tagObjType=%s,tagObjID=%s,被击杀,结束战斗: isWin=%s" % (tagObjType, tagObjID, isWin), playerID)
+                break
+            
+            if isWin != None:
+                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)
+            
+    GameWorld.DebugLog("回合制战斗结束: mapID=%s,funcLineID=%s,tagPlayerID=%s,isWin=%s,overState=%s" 
+                       % (mapID, funcLineID, tagPlayerID, isWin, overState), playerID)
+    return
+
+def TurnFightObjStartInit(gameObj):
+    ## 回合制战斗实例初始化
+    if not gameObj:
+        return
+    
+    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 1)
+    GameObj.SetHPFull(gameObj)
+    gameObj.RefreshView()
+    
+    objType = gameObj.GetGameObjType()
+    # 重置技能CD、战斗buff
+    if objType == IPY_GameWorld.gotPlayer:            
+        skillManager = gameObj.GetSkillManager()
+        for i in range(skillManager.GetSkillCount()):
+            skill = skillManager.GetSkillByIndex(i)
+            skill.SetRemainTime(0)
+            
+    elif objType == IPY_GameWorld.gotNPC:
+        pass
+    return
+
+def TurnFightObjOverReset(gameObj):
+    ## 回合制战斗实例结束重置
+    if not gameObj:
+        return
+    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 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)
+            
+    return
+
+def NPCAttack(curObj, tagObj, tick):
+    ## NPC攻击
+    if not curObj:
+        return
+    tagDist = 0
+    #---优先释放技能---
+    if not AICommon.DoAutoUseSkill(curObj, tagObj, tagDist, tick):
+        #普通攻击
+        isOK = BaseAttack.Attack(curObj, tagObj, None, tick)
+        GameWorld.DebugLog("        NPC普通攻击: curID=%s,tagID=%s,isOK=%s" % (curObj.GetID(), tagObj.GetID(), isOK))
+    return
+
+def PlayerAttack(curPlayer, tagObj, tick):
+    ## 玩家攻击, 参考技能使用 #def UseSkillEx(index, clientData, tick):
+    playerID = curPlayer.GetPlayerID()
+    job = curPlayer.GetJob()
+    jobAutoUseSkillDict = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 2, {})
+    if job not in jobAutoUseSkillDict:
+        return
+    skillList = jobAutoUseSkillDict[job]
+    
+    posX, posY = tagPosX, tagPosY = curPlayer.GetPosX(), curPlayer.GetPosY()
+    tagObjType, tagObjID = tagObj.GetGameObjType(), tagObj.GetID()
+    
+    curPlayer.ClearUseSkillRec()
+    curPlayer.SetAttackTargetPos(posX, posY)
+    curPlayer.SetUseSkillPosX(tagPosX)
+    curPlayer.SetUseSkillPosY(tagPosY)
+    curPlayer.SetUseSkillTagType(tagObjType)
+    curPlayer.SetUseSkillTagID(tagObjID)
+    
+    #PlayerControl.SetIsNeedProcess(curPlayer, True)
+    #PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paAttack)
+    
+    skillMgr = curPlayer.GetSkillManager()
+    for skillID in skillList:
+        curSkill = skillMgr.FindSkillBySkillID(skillID)
+        if not curSkill:
+            continue
+        
+        #CheckSkillCondition
+        #被动技能无法使用
+        if SkillCommon.isPassiveSkill(curSkill):
+            continue
+        #还在冷却时间内无法释放
+        if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0:
+            continue
+        
+        curPlayer.SetUseSkill(curSkill.GetSkillData())
+        useSkillData = curPlayer.GetUseSkill()
+        if not PlayerState.__DoClientUseSkillEx(curPlayer, useSkillData, tick):
+            GameWorld.DebugLog("        技能攻击失败%s" % skillID, playerID)
+            continue
+        GameWorld.DebugLog("        技能攻击成功%s" % skillID, playerID)
+        
+        break
+    
+    curPlayer.ClearUseSkillRec()
+    return
+
+def SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, state, turnNum=0, turnMax=0):
+    clientPack = ChPyNetSendPack.tagMCTurnFightState()
+    clientPack.Clear()
+    clientPack.MapID = mapID
+    clientPack.FuncLineID = funcLineID
+    clientPack.PlayerID = tagPlayerID
+    clientPack.State = state
+    clientPack.TurnNum = turnNum
+    clientPack.TurnMax = turnMax
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
+
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index abd54b5..5b44d89 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3047,6 +3047,9 @@
     Def_ShopType_LongSale,    #远程贩售
 ) = range(1, 2+1)
 
+#---Obj字典-------
+Def_Obj_Dict_TurnFightNum = 'TurnFightNum' # 回合制战斗当前轮次
+
 #---NPC字典-------
 #每道龙卷风最终坐标
 Def_NPC_Dict_CycloneTagPosX = 'CycloneTagPosX'
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 3014e24..a967c1f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -20357,6 +20357,66 @@
 
 
 #------------------------------------------------------
+# B4 10 回合制战斗 #tagCMTurnFight
+
+class  tagCMTurnFight(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("MapID", c_int),    # 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
+                  ("FuncLineID", c_ushort),    
+                  ("PlayerID", c_int),    # 对应玩家ID,可为0,某些功能可能有用,如竞技场
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x10
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB4
+        self.SubCmd = 0x10
+        self.MapID = 0
+        self.FuncLineID = 0
+        self.PlayerID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMTurnFight)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 10 回合制战斗 //tagCMTurnFight:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                MapID:%d,
+                                FuncLineID:%d,
+                                PlayerID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.MapID,
+                                self.FuncLineID,
+                                self.PlayerID
+                                )
+        return DumpString
+
+
+m_NAtagCMTurnFight=tagCMTurnFight()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMTurnFight.Cmd,m_NAtagCMTurnFight.SubCmd))] = m_NAtagCMTurnFight
+
+
+#------------------------------------------------------
 # B5 14 拍卖行竞价物品 #tagCMBiddingAuctionItem
 
 class  tagCMBiddingAuctionItem(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 03c840d..e72f5df 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -47123,6 +47123,78 @@
 
 
 #------------------------------------------------------
+# B4 20 回合制战斗状态 #tagMCTurnFightState
+
+class  tagMCTurnFightState(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("MapID", c_int),    # 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
+                  ("FuncLineID", c_ushort),    
+                  ("PlayerID", c_int),    # 对应玩家ID,可为0,某些功能可能有用,如竞技场
+                  ("State", c_ubyte),    # 0-开始;1-进行中;2-结束
+                  ("TurnNum", c_ubyte),    # 当前轮次
+                  ("TurnMax", c_ubyte),    # 最大轮次
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x20
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xB4
+        self.SubCmd = 0x20
+        self.MapID = 0
+        self.FuncLineID = 0
+        self.PlayerID = 0
+        self.State = 0
+        self.TurnNum = 0
+        self.TurnMax = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCTurnFightState)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 20 回合制战斗状态 //tagMCTurnFightState:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                MapID:%d,
+                                FuncLineID:%d,
+                                PlayerID:%d,
+                                State:%d,
+                                TurnNum:%d,
+                                TurnMax:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.MapID,
+                                self.FuncLineID,
+                                self.PlayerID,
+                                self.State,
+                                self.TurnNum,
+                                self.TurnMax
+                                )
+        return DumpString
+
+
+m_NAtagMCTurnFightState=tagMCTurnFightState()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTurnFightState.Cmd,m_NAtagMCTurnFightState.SubCmd))] = m_NAtagMCTurnFightState
+
+
+#------------------------------------------------------
 # C1 09 跨服排位玩家信息 #tagMCChampionshipPlayerInfo
 
 class  tagMCChampionshipPlayerInfo(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index e5ac6f5..a6baf0e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -720,6 +720,12 @@
                         ("eval", "RewardInfo", 0),
                         ),
 
+                "FBTurn":(
+                        ("DWORD", "DataMapID", 1),
+                        ("WORD", "LineID", 1),
+                        ("DWORD", "NPCID", 0),
+                        ),
+
                 "FBHelpBattle":(
                         ("DWORD", "DataMapID", 1),
                         ("BYTE", "LineID", 1),
@@ -3643,6 +3649,19 @@
     def GetRefreshNPC(self): return self.RefreshNPC # 标试点刷怪配置
     def GetGradeInfo(self): return self.GradeInfo # 评级规则
     def GetRewardInfo(self): return self.RewardInfo # 奖励信息
+
+# 副本回合制表
+class IPY_FBTurn():
+    
+    def __init__(self):
+        self.DataMapID = 0
+        self.LineID = 0
+        self.NPCID = 0
+        return
+        
+    def GetDataMapID(self): return self.DataMapID # 数据地图ID
+    def GetLineID(self): return self.LineID # 功能线路ID
+    def GetNPCID(self): return self.NPCID # NPCID
 
 # 副本助战表
 class IPY_FBHelpBattle():
@@ -6923,6 +6942,8 @@
         self.ipyFBFuncLen = len(self.ipyFBFuncCache)
         self.ipyFBLineCache = self.__LoadFileData("FBLine", IPY_FBLine)
         self.ipyFBLineLen = len(self.ipyFBLineCache)
+        self.ipyFBTurnCache = self.__LoadFileData("FBTurn", IPY_FBTurn)
+        self.ipyFBTurnLen = len(self.ipyFBTurnCache)
         self.ipyFBHelpBattleCache = self.__LoadFileData("FBHelpBattle", IPY_FBHelpBattle)
         self.ipyFBHelpBattleLen = len(self.ipyFBHelpBattleCache)
         self.ipyNPCCustomRefreshCache = self.__LoadFileData("NPCCustomRefresh", IPY_NPCCustomRefresh)
@@ -7539,6 +7560,8 @@
     def GetFBFuncByIndex(self, index): return self.ipyFBFuncCache[index]
     def GetFBLineCount(self): return self.ipyFBLineLen
     def GetFBLineByIndex(self, index): return self.ipyFBLineCache[index]
+    def GetFBTurnCount(self): return self.ipyFBTurnLen
+    def GetFBTurnByIndex(self, index): return self.ipyFBTurnCache[index]
     def GetFBHelpBattleCount(self): return self.ipyFBHelpBattleLen
     def GetFBHelpBattleByIndex(self, index): return self.ipyFBHelpBattleCache[index]
     def GetNPCCustomRefreshCount(self): return self.ipyNPCCustomRefreshLen
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
index 23c9aa9..27250ba 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
@@ -447,7 +447,7 @@
 def DoAutoUseSkill(curNPC, curTag, tagDist, tick):
     #攻击僵持中
     if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():
-        if not PetControl.IsPet(curNPC):
+        if not (PetControl.IsPet(curNPC) or curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum)):
             #GameWorld.Log('攻击僵持中')
             return False
     

--
Gitblit v1.8.0