hxp
2024-04-10 a9415978e2c4b94debfb59787771e1434a1adf19
10130 【后端】福地争夺资源功能(增加摇人功能)
12个文件已修改
3个文件已添加
615 ■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTurnFight.py 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MineArea.py 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_TurnFight.py 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -708,6 +708,11 @@
#情缘副本
Def_FBMapID_Love = 31300
#回合战斗自定义地图ID
TurnFightMapIDList = (
Def_TFMapID_MineArea, # 福地 1
) = range(1, 1 + 1)
#需要刷世界BOSS的副本
WorldBossFBMapIDList = [Def_FBMapID_SealDemon, Def_FBMapID_ZhuXianBoss, Def_FBMapID_DemonKing]
#跨服地图
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -20891,60 +20891,88 @@
# 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,某些功能可能有用,如竞技场
                  ]
    Head = tagHead()
    MapID = 0    #(DWORD MapID)// 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
    FuncLineID = 0    #(WORD FuncLineID)
    PlayerID = 0    #(DWORD PlayerID)// 战斗目标玩家ID,可为0,某些功能可能有用,如竞技场
    ValueCount = 0    #(BYTE ValueCount)
    ValueList = list()    #(vector<DWORD> ValueList)// 附加值列表,可选,具体含义由MapID决定
    data = None
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB4
        self.SubCmd = 0x10
        self.Head.Cmd = 0xB4
        self.Head.SubCmd = 0x10
        return
    def ReadData(self, stringData, _pos=0, _len=0):
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.MapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FuncLineID,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ValueCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.ValueCount):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.ValueList.append(value)
        return _pos
    def Clear(self):
        self.Cmd = 0xB4
        self.SubCmd = 0x10
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB4
        self.Head.SubCmd = 0x10
        self.MapID = 0
        self.FuncLineID = 0
        self.PlayerID = 0
        self.ValueCount = 0
        self.ValueList = list()
        return
    def GetLength(self):
        return sizeof(tagCMTurnFight)
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 2
        length += 4
        length += 1
        length += 4 * self.ValueCount
        return length
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.MapID)
        data = CommFunc.WriteWORD(data, self.FuncLineID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.ValueCount)
        for i in range(self.ValueCount):
            data = CommFunc.WriteDWORD(data, self.ValueList[i])
        return data
    def OutputString(self):
        DumpString = '''// B4 10 回合制战斗 //tagCMTurnFight:
                                Cmd:%s,
                                SubCmd:%s,
        DumpString = '''
                                Head:%s,
                                MapID:%d,
                                FuncLineID:%d,
                                PlayerID:%d
                                PlayerID:%d,
                                ValueCount:%d,
                                ValueList:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Head.OutputString(),
                                self.MapID,
                                self.FuncLineID,
                                self.PlayerID
                                self.PlayerID,
                                self.ValueCount,
                                "..."
                                )
        return DumpString
m_NAtagCMTurnFight=tagCMTurnFight()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMTurnFight.Cmd,m_NAtagCMTurnFight.SubCmd))] = m_NAtagCMTurnFight
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMTurnFight.Head.Cmd,m_NAtagCMTurnFight.Head.SubCmd))] = m_NAtagCMTurnFight
#------------------------------------------------------
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -43612,6 +43612,7 @@
    TreasureState = list()    #(vector<BYTE> TreasureState)// 聚宝盆是否已激活列表,[类型0是否已激活, ...]
    TreasureAward = list()    #(vector<BYTE> TreasureAward)// 聚宝盆奖励是否已领取列表,[类型0是否已领取, ...]
    TreasureProgress = list()    #(vector<BYTE> TreasureProgress)// 聚宝盆进度值列表,[类型0进度值, ...],满进度100
    HelpAwardCount = 0    #(BYTE HelpAwardCount)// 今日已帮助别人奖励次数
    data = None
    def __init__(self):
@@ -43637,6 +43638,7 @@
        for i in range(self.TreasureCount):
            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
            self.TreasureProgress.append(value)
        self.HelpAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        return _pos
    def Clear(self):
@@ -43652,6 +43654,7 @@
        self.TreasureState = list()
        self.TreasureAward = list()
        self.TreasureProgress = list()
        self.HelpAwardCount = 0
        return
    def GetLength(self):
@@ -43665,6 +43668,7 @@
        length += 1 * self.TreasureCount
        length += 1 * self.TreasureCount
        length += 1 * self.TreasureCount
        length += 1
        return length
@@ -43682,6 +43686,7 @@
            data = CommFunc.WriteBYTE(data, self.TreasureAward[i])
        for i in range(self.TreasureCount):
            data = CommFunc.WriteBYTE(data, self.TreasureProgress[i])
        data = CommFunc.WriteBYTE(data, self.HelpAwardCount)
        return data
    def OutputString(self):
@@ -43694,7 +43699,8 @@
                                TreasureCount:%d,
                                TreasureState:%s,
                                TreasureAward:%s,
                                TreasureProgress:%s
                                TreasureProgress:%s,
                                HelpAwardCount:%d
                                '''\
                                %(
                                self.Head.OutputString(),
@@ -43705,7 +43711,8 @@
                                self.TreasureCount,
                                "...",
                                "...",
                                "..."
                                "...",
                                self.HelpAwardCount
                                )
        return DumpString
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
@@ -20,6 +20,7 @@
import PyDataManager
import ChPyNetSendPack
import PyGameDataStruct
import PlayerCompensation
import PlayerViewCache
import PlayerDBGSEvent
import PlayerControl
@@ -42,6 +43,7 @@
# 物品实例额外属性名
MineItemAttr_MoveSpeed = "MoveSpeed"
MineItemAttr_EndTime = "EndTime"
MineItemAttr_HelpTick = "HelpTick"
# 物品类型
MineType_Normal = 0 # 常规物品
@@ -226,6 +228,7 @@
        # 不入库的属性
        setattr(mineItemData, MineItemAttr_EndTime, 0)
        setattr(mineItemData, MineItemAttr_MoveSpeed, 0)
        setattr(mineItemData, MineItemAttr_HelpTick, 0)
        return
    
    def GetMineItem(self, playerID, index):
@@ -331,9 +334,6 @@
def DoMineAreaFuncOpen(curPlayer):
    ## 福地功能开启
    playerID = curPlayer.GetPlayerID()
    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
    # 还没有福地物品数据,则刷新初始化
    if playerID not in mineItemMgr.playerMineItemDict:
        __DoMineItemRefresh(playerID, curPlayer)
    return
@@ -788,6 +788,94 @@
    mineItemMgr.socialIDListDict[playerID] = socialIDList
    return socialIDList
def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):
    # 摇人帮助请求
    if funcLineID == 0:
        return __OnMineHelpRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList)
    return
def OnTurnFightOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList):
    # 摇人帮助结果
    if funcLineID == 0:
        return __OnMineHelpOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList)
    return
def __OnMineHelpRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):
    # 摇人帮助请求
    playerID = curPlayer.GetPlayerID()
    if not valueList or len(valueList) < 2:
        GameWorld.DebugLog("没有指定valueList!", playerID)
        return
    areaPlayerID = valueList[0]
    itemIndex = valueList[1]
    if playerID == areaPlayerID:
        GameWorld.DebugLog("不能帮助自己!", playerID)
        return
    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
    mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)
    mineID = mineItemData.MineID
    if not mineID:
        # 该资源已消失
        PlayerControl.NotifyCode(curPlayer, "MineDisappeared")
        return
    robPlayerID = mineItemData.RobPlayerID
    if not robPlayerID or robPlayerID != tagPlayerID:
        # 当前资源无争夺者或已被其他玩家完成
        PlayerControl.NotifyCode(curPlayer, "MineHelpFinished")
        return
    tick = GameWorld.GetGameWorld().GetTick()
    helpTick = getattr(mineItemData, MineItemAttr_HelpTick)
    if helpTick and tick - helpTick < 10000:
        GameWorld.DebugLog("已经有其他人在帮助中!", playerID)
        return
    setattr(mineItemData, MineItemAttr_HelpTick, tick)
    return True
def __OnMineHelpOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList):
    # 摇人帮助结果
    playerID = curPlayer.GetPlayerID()
    helpPlayerName = curPlayer.GetName()
    areaPlayerID = valueList[0]
    itemIndex = valueList[1]
    isWin = fightRet[0]
    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
    mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)
    setattr(mineItemData, MineItemAttr_HelpTick, 0)
    if not isWin:
        #GameWorld.DebugLog("帮助失败")
        return
    robPlayerID = mineItemData.RobPlayerID
    # 赶走抢夺者
    if robPlayerID and robPlayerID == tagPlayerID:
        __DoCancelPull(tagPlayerID, areaPlayerID, itemIndex)
    robCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(tagPlayerID))
    robPlayerName = robCacheDict.get("Name", "")
    areaCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID))
    areaPlayerName = areaCacheDict.get("Name", "")
    # 邮件发放奖励
    PlayerCompensation.SendMailByKey("MineHelpAward", [playerID], awardItemList, [areaPlayerName, robPlayerName])
    # 通知福地玩家
    PlayerCompensation.SendMailByKey("MineHelpReqOK", [areaPlayerID], [], [helpPlayerName, robPlayerName])
    return True
def MapServer_MineArea(curPlayer, msgList):
    mapID = curPlayer.GetRealMapID()
    playerID = curPlayer.GetPlayerID()
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -81,6 +81,7 @@
import PlayerFairyDomain
import GameWorldSkyTower
import GameWorldMineArea
import PlayerTurnFight
import GameWorldArena
import GameWorldItem
import PlayerAssist
@@ -1020,6 +1021,16 @@
            return
        resultName = '%s' % ret
        
    # 回合制
    if callName == "TurnFight":
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
        if not curPlayer:
            return
        ret = PlayerTurnFight.MapServer_TurnFight(curPlayer, eval(resultName))
        if ret == None:
            return
        resultName = '%s' % ret
    # 福地
    if callName =="MineArea":
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTurnFight.py
New file
@@ -0,0 +1,62 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package PlayerTurnFight
#
# @todo:回合制
# @author hxp
# @date 2024-04-10
# @version 1.0
#
# 详细描述: 回合制
#
#-------------------------------------------------------------------------------
#"""Version = 2024-04-10 14:00"""
#-------------------------------------------------------------------------------
import GameWorld
import GameWorldMineArea
import ChConfig
def MapServer_TurnFight(curPlayer, msgList):
    mapID = curPlayer.GetRealMapID()
    playerID = curPlayer.GetPlayerID()
    GameWorld.DebugLog("MapServer_TurnFight mapID=%s,msgList=%s" % (mapID, msgList), playerID)
    if not msgList:
        return
    msgType, dataMsg = msgList
    ret = None
    if msgType == "TurnFightRequest":
        ret = __OnTurnFightRequest(curPlayer, dataMsg)
    elif msgType == "TurnFightOver":
        ret = __OnTurnFightOver(curPlayer, dataMsg)
    if ret == None:
        return
    return msgList + (ret if isinstance(ret, list) else [ret])
def __OnTurnFightRequest(curPlayer, dataMsg):
    ## 回合战斗请求
    # @return: None-不允许战斗;非None-允许战斗,具体返回内容功能自己决定
    mapID, funcLineID, tagPlayerID, valueList = dataMsg
    if mapID == ChConfig.Def_TFMapID_MineArea:
        return GameWorldMineArea.OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList)
    return
def __OnTurnFightOver(curPlayer, dataMsg):
    ## 回合战斗结束
    mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList = dataMsg
    if mapID == ChConfig.Def_TFMapID_MineArea:
        return GameWorldMineArea.OnTurnFightOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -35,6 +35,7 @@
import FBCommon
import ItemControler
import PassiveBuffEffMng
import FBLogic
# 回合战斗流程状态
(
@@ -69,13 +70,60 @@
#    tagHead        Head;
#    DWORD        MapID;    // 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
#    WORD        FuncLineID;
#    DWORD        PlayerID;    // 对应玩家ID,可为0,某些功能可能有用,如竞技场
#    DWORD        PlayerID;    // 战斗目标玩家ID,可为0,某些功能可能有用,如竞技场
#    BYTE        ValueCount;
#    DWORD        ValueList[ValueCount]; // 附加值列表,可选,具体含义由MapID决定
#};
def OnTurnFight(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    mapID = clientData.MapID
    funcLineID = clientData.FuncLineID
    tagPlayerID = clientData.PlayerID
    valueList = clientData.ValueList
    playerID = curPlayer.GetPlayerID()
    if tagPlayerID:
        if playerID == tagPlayerID:
            GameWorld.DebugLog("不能打自己!", playerID)
            return
    if not FBLogic.OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):
        return
    # 需要发送到GameServer验证
    if mapID in ChConfig.Def_TFMapID_SendToGameServer:
        SendToGameServer_TurnFight(curPlayer, "TurnFightRequest", [mapID, funcLineID, tagPlayerID, valueList])
        return
    DoTurnFightProcess(curPlayer, mapID, funcLineID, tagPlayerID, valueList, tick)
    return
def SendToGameServer_TurnFight(curPlayer, msgType, dataMsg=""):
    playerID = curPlayer.GetPlayerID()
    msgList = str([msgType, dataMsg])
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "TurnFight", msgList, len(msgList))
    GameWorld.Log("回合战斗发送GameServer: %s, %s" % (msgType, dataMsg), playerID)
    return
def GameServer_TurnFight_DoResult(curPlayer, msgData, tick):
    msgType, dataMsg, ret = msgData
    if not ret:
        return
    if msgType == "TurnFightRequest":
        mapID, funcLineID, tagPlayerID, valueList = dataMsg
        DoTurnFightProcess(curPlayer, mapID, funcLineID, tagPlayerID, valueList, tick)
    elif msgType == "TurnFightOver":
        mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList = dataMsg
        FBLogic.OnTurnFightOver_GameServerRet(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList, ret)
    return
def DoTurnFightProcess(curPlayer, mapID, funcLineID, tagPlayerID, valueList, tick):
    ## 执行回合制战斗的完整流程
    
    if curPlayer.GetSightLevel() != curPlayer.GetID():
        PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
@@ -83,23 +131,23 @@
    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Start)
    
    if tagPlayerID:
        PlayerViewCacheTube.GetPlayerPropDataCall(curPlayer, tagPlayerID, DoTrunFightVSPlayer, [mapID, funcLineID], True)
        PlayerViewCacheTube.GetPlayerPropDataCall(curPlayer, tagPlayerID, DoTrunFightVSPlayer, [mapID, funcLineID, valueList], True)
        return
    
    DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick)
    DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, valueList, tick)
    
    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Over)
    return
def DoTrunFightVSPlayer(curPlayer, tagPlayerID, callData, PropDict):
    mapID, funcLineID = callData
    mapID, funcLineID, valueList = callData
    if PropDict and curPlayer.GetPlayerID() != tagPlayerID:
        tick = GameWorld.GetGameWorld().GetTick()
        DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick)
        DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, valueList, tick)
    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Over)
    return
def DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick):
def DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, valueList, tick):
    playerID = curPlayer.GetPlayerID()
    factionInfoA = GetPlayerFactionInfoByCache(playerID)
    ipyData = None
@@ -121,20 +169,32 @@
        skillIDExList.extend(ipyData.GetSTSkillIDList())
        factionInfoB = {"npcID":npcID, "pet":petCacheInfo, "skillIDExList":skillIDExList}
        
    ret = ProcessAutoTurnFight(mapID, funcLineID, factionInfoA, factionInfoB, tick, curPlayer)
    if not ret:
    fightRet = ProcessAutoTurnFight(mapID, funcLineID, factionInfoA, factionInfoB, tick, curPlayer)
    if not fightRet:
        return
    isWin, turnNum, turnMax, factionTotalHurtDict, playbackID = ret
    isWin, turnNum, turnMax, factionTotalHurtDict, playbackID = fightRet
    
    # 结算奖励...待扩展
    awardItemList = []
    # 结算奖励, awardWay-发放方式(0-不发放, 1-TurnAttack模块统一发放, 2-功能自己决定发放逻辑)
    needSendGameServer, awardItemList, awardWay = False, [], 1
    overRet = FBLogic.OnTurnFightOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet)
    if overRet != None:
        needSendGameServer, awardItemList, awardWay = overRet
    if isWin and ipyData:
        if awardWay == 1 and not awardItemList:
        # 山寨测试先默认都是首次奖励,正式后需删除
        awardItemList = ipyData.GetAwardItemListFirst()
        
    if awardItemList == None:
        awardItemList = []
    GameWorld.DebugLog("奖励物品: %s" % awardItemList)
    if awardWay == 1 and awardItemList:
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["TurnFight", False, {"mapID":mapID, "funcLineID":funcLineID}])
    
    if needSendGameServer or mapID in ChConfig.Def_TFMapID_SendToGameServer:
        SendToGameServer_TurnFight(curPlayer, "TurnFightOver", [mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList])
    overMsg = {"isWin":isWin, "itemInfo":FBCommon.GetJsonItemList(awardItemList), "totalHurt":factionTotalHurtDict.get(1, 0)}
    playbackID and overMsg.update({"playbackID":playbackID})
    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Award, turnNum, turnMax, overMsg)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1877,6 +1877,14 @@
#情缘副本
Def_FBMapID_Love = 31300
#回合战斗自定义地图ID
TurnFightMapIDList = (
Def_TFMapID_MineArea, # 福地 1
) = range(1, 1 + 1)
#回合战斗自定义地图需要发送GameServer的列表
Def_TFMapID_SendToGameServer = [Def_TFMapID_MineArea]
#前端自定义场景地图
ClientCustomScene = [Def_FBMapID_PersonalBoss, Def_FBMapID_ArenaBattle]
@@ -2007,6 +2015,7 @@
                'FairyTreasure':[Def_FBMapID_FairyTreasure],#缥缈宝藏
                'Love':[Def_FBMapID_Love],#情缘副本
                'CrossBattlefield':[Def_FBMapID_CrossBattlefield], #跨服战场
                'MineArea':[Def_TFMapID_MineArea], #福地
                }
#特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
@@ -4425,7 +4434,8 @@
#福地
Def_PDict_MineWorkerCount = "MineWorkerCount" # 已雇佣工人数
Def_PDict_MineWorkerEnergyUsed = "MineWorkerEnergyUsed" # 今日已已消耗体力
Def_PDict_MineWorkerEnergyUsed = "MineWorkerEnergyUsed" # 今日已消耗体力
Def_PDict_MineHelpAwardCount = "MineHelpAwardCount" # 今日已帮助别人奖励次数
Def_PDict_MineRefreshCount = "MineRefreshCount_%s" # 今日已刷新次数,参数(刷新类型)
Def_PDict_MineTreasureState = "MineTreasureState" # 聚宝盆激活状态,按类型位运算记录是否已激活
Def_PDict_MineTreasureAward = "MineTreasureAward" # 聚宝盆奖励状态,按类型位运算记录是否已领取
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -20891,60 +20891,88 @@
# 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,某些功能可能有用,如竞技场
                  ]
    Head = tagHead()
    MapID = 0    #(DWORD MapID)// 自定义地图ID,可用于绑定战斗场景功能(如野外关卡,爬塔功能,竞技场等)
    FuncLineID = 0    #(WORD FuncLineID)
    PlayerID = 0    #(DWORD PlayerID)// 战斗目标玩家ID,可为0,某些功能可能有用,如竞技场
    ValueCount = 0    #(BYTE ValueCount)
    ValueList = list()    #(vector<DWORD> ValueList)// 附加值列表,可选,具体含义由MapID决定
    data = None
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB4
        self.SubCmd = 0x10
        self.Head.Cmd = 0xB4
        self.Head.SubCmd = 0x10
        return
    def ReadData(self, stringData, _pos=0, _len=0):
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.MapID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FuncLineID,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ValueCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.ValueCount):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.ValueList.append(value)
        return _pos
    def Clear(self):
        self.Cmd = 0xB4
        self.SubCmd = 0x10
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB4
        self.Head.SubCmd = 0x10
        self.MapID = 0
        self.FuncLineID = 0
        self.PlayerID = 0
        self.ValueCount = 0
        self.ValueList = list()
        return
    def GetLength(self):
        return sizeof(tagCMTurnFight)
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 2
        length += 4
        length += 1
        length += 4 * self.ValueCount
        return length
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.MapID)
        data = CommFunc.WriteWORD(data, self.FuncLineID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.ValueCount)
        for i in range(self.ValueCount):
            data = CommFunc.WriteDWORD(data, self.ValueList[i])
        return data
    def OutputString(self):
        DumpString = '''// B4 10 回合制战斗 //tagCMTurnFight:
                                Cmd:%s,
                                SubCmd:%s,
        DumpString = '''
                                Head:%s,
                                MapID:%d,
                                FuncLineID:%d,
                                PlayerID:%d
                                PlayerID:%d,
                                ValueCount:%d,
                                ValueList:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Head.OutputString(),
                                self.MapID,
                                self.FuncLineID,
                                self.PlayerID
                                self.PlayerID,
                                self.ValueCount,
                                "..."
                                )
        return DumpString
m_NAtagCMTurnFight=tagCMTurnFight()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMTurnFight.Cmd,m_NAtagCMTurnFight.SubCmd))] = m_NAtagCMTurnFight
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMTurnFight.Head.Cmd,m_NAtagCMTurnFight.Head.SubCmd))] = m_NAtagCMTurnFight
#------------------------------------------------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -43612,6 +43612,7 @@
    TreasureState = list()    #(vector<BYTE> TreasureState)// 聚宝盆是否已激活列表,[类型0是否已激活, ...]
    TreasureAward = list()    #(vector<BYTE> TreasureAward)// 聚宝盆奖励是否已领取列表,[类型0是否已领取, ...]
    TreasureProgress = list()    #(vector<BYTE> TreasureProgress)// 聚宝盆进度值列表,[类型0进度值, ...],满进度100
    HelpAwardCount = 0    #(BYTE HelpAwardCount)// 今日已帮助别人奖励次数
    data = None
    def __init__(self):
@@ -43637,6 +43638,7 @@
        for i in range(self.TreasureCount):
            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
            self.TreasureProgress.append(value)
        self.HelpAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        return _pos
    def Clear(self):
@@ -43652,6 +43654,7 @@
        self.TreasureState = list()
        self.TreasureAward = list()
        self.TreasureProgress = list()
        self.HelpAwardCount = 0
        return
    def GetLength(self):
@@ -43665,6 +43668,7 @@
        length += 1 * self.TreasureCount
        length += 1 * self.TreasureCount
        length += 1 * self.TreasureCount
        length += 1
        return length
@@ -43682,6 +43686,7 @@
            data = CommFunc.WriteBYTE(data, self.TreasureAward[i])
        for i in range(self.TreasureCount):
            data = CommFunc.WriteBYTE(data, self.TreasureProgress[i])
        data = CommFunc.WriteBYTE(data, self.HelpAwardCount)
        return data
    def OutputString(self):
@@ -43694,7 +43699,8 @@
                                TreasureCount:%d,
                                TreasureState:%s,
                                TreasureAward:%s,
                                TreasureProgress:%s
                                TreasureProgress:%s,
                                HelpAwardCount:%d
                                '''\
                                %(
                                self.Head.OutputString(),
@@ -43705,7 +43711,8 @@
                                self.TreasureCount,
                                "...",
                                "...",
                                "..."
                                "...",
                                self.HelpAwardCount
                                )
        return DumpString
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MineArea.py
@@ -35,12 +35,14 @@
        GameWorld.DebugAnswer(curPlayer, "设置工人数量: MineArea w 数量")
        GameWorld.DebugAnswer(curPlayer, "设置刷新次数: MineArea r 次数 [是否超级]")
        GameWorld.DebugAnswer(curPlayer, "设置聚宝进度: MineArea t 类型 进度值")
        GameWorld.DebugAnswer(curPlayer, "设置帮助次数: MineArea h 次数")
        return True
    
    value1 = msgList[0]
    if value1 == 0:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerCount, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerEnergyUsed, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHelpAwardCount, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % 0, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % 1, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureState, 0)
@@ -73,6 +75,11 @@
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineTreasureProgess % treasureType, setProgress)
        GameWorld.DebugAnswer(curPlayer, "设置聚宝进度: Type:%s,进度=%s" % (treasureType, setProgress))
        
    elif value1 == "h":
        helpAwardCount = msgList[1] if len(msgList) > 1 else 0
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHelpAwardCount, helpAwardCount)
        GameWorld.DebugAnswer(curPlayer, "设置帮助次数: %s" % helpAwardCount)
    else:
        return True
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -2423,4 +2423,44 @@
    if callFunc == None:
        return False
    return callFunc(curPlayer)
def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):
    ## 回合战斗请求 - 地图验证
    # @return: 是否允许
    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnTurnFightRequest"))
    if callFunc == None:
        # 默认不限制
        return True
    return callFunc(curPlayer, mapID, funcLineID, tagPlayerID, valueList)
def OnTurnFightOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet):
    ## 回合战斗结束
    # @return: 是否需要同步GameServer, 奖励列表, 发放方式(0-不发放, 1-TurnAttack模块统一发放, 2-功能自己决定发放逻辑)
    # @return: None - 无结算逻辑,可走TurnAttack模块通用逻辑
    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnTurnFightOver"))
    if callFunc == None:
        return
    return callFunc(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet)
def OnTurnFightOver_GameServerRet(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList, ret):
    ## 回合战斗结束 - GameServer处理完毕返回
    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnTurnFightOver_GameServerRet"))
    if callFunc == None:
        return
    return callFunc(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList, ret)
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MineArea.py
New file
@@ -0,0 +1,75 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GameWorldLogic.FBProcess.GameLogic_MineArea
#
# @todo:福地
# @author hxp
# @date 2024-04-10
# @version 1.0
#
# 详细描述: 福地
#
#-------------------------------------------------------------------------------
#"""Version = 2024-04-10 14:00"""
#-------------------------------------------------------------------------------
import ChConfig
import IpyGameDataPY
import PlayerMineArea
import PlayerControl
import GameWorld
def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):
    ## 回合战斗请求 - 地图验证
    # 摇人帮助
    if funcLineID == 0:
        if not tagPlayerID:
            return
        awardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineHelpAwardCount)
        awardCountMax = IpyGameDataPY.GetFuncCfg("MineAreaHelp", 1)
        if awardCountMax and awardCount >= awardCountMax:
            GameWorld.DebugLog("已达到今日福地帮助奖励次数上限! awardCount=%s" % awardCount, curPlayer.GetPlayerID())
            return
    else:
        # 通过lineID扩展同个功能系统下的不同战斗需求
        pass
    return True
def OnTurnFightOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet):
    ## 回合战斗结束
    # @return: 是否需要同步GameServer, 奖励列表, 发放方式(0-不发放, 1-TurnAttack模块统一发放, 2-功能自己决定发放逻辑)
    # 摇人帮助
    if funcLineID == 0:
        # 无论胜负都要同步GameServer汇报结果
        isWin = fightRet[0]
        if not isWin:
            return True, [], 0
        awardItemList = IpyGameDataPY.GetFuncEvalCfg("MineAreaHelp", 2)
        return True, awardItemList, 2
    return
def OnTurnFightOver_GameServerRet(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList, ret):
    ## 回合战斗结束 - GameServer处理完毕返回
    # 摇人帮助
    if funcLineID == 0:
        isWin = fightRet[0]
        if not isWin or not ret:
            return
        # 增加奖励次数
        awardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineHelpAwardCount) + 1
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHelpAwardCount, awardCount)
        GameWorld.DebugLog("更新福地帮助他人奖励次数: awardCount=%s" % awardCount, curPlayer.GetPlayerID())
        PlayerMineArea.SyncPlayerMineAreaInfo(curPlayer)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMineArea.py
@@ -33,6 +33,7 @@
    return
def PlayerOnDay(curPlayer):
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineHelpAwardCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineWorkerEnergyUsed, 0)
    for refreshType in [0, 1]:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MineRefreshCount % refreshType, 0)
@@ -296,6 +297,7 @@
    clientPack = ChPyNetSendPack.tagMCPlayerMineAreaInfo()
    clientPack.WorkerCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerCount)
    clientPack.EnergyUsed = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineWorkerEnergyUsed)
    clientPack.HelpAwardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineHelpAwardCount)
    clientPack.RefreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % 0)
    clientPack.RefreshCountSuper = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MineRefreshCount % 1)
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_TurnFight.py
New file
@@ -0,0 +1,47 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.RemoteQuery.GY_Query_TurnFight
#
# @todo:回合制
# @author hxp
# @date 2024-04-10
# @version 1.0
#
# 详细描述: 回合制
#
#-------------------------------------------------------------------------------
#"""Version = 2024-04-10 14:00"""
#-------------------------------------------------------------------------------
import GameWorld
import TurnAttack
#---------------------------------------------------------------------
#逻辑实现
## 请求逻辑
#  @param query_Type 请求类型
#  @param query_ID 请求的玩家ID
#  @param packCMDList 发包命令 [ ]
#  @param tick 当前时间
#  @return "True" or "False" or ""
#  @remarks 函数详细说明.
def DoLogic(query_Type, query_ID, packCMDList, tick):
    return ""
#---------------------------------------------------------------------
#执行结果
## 执行结果
#  @param curPlayer 发出请求的玩家
#  @param callFunName 功能名称
#  @param funResult 查询的结果
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def DoResult(curPlayer, callFunName, funResult, tick):
    GameWorld.DebugLog("GY_Query_TurnFight DoResult %s" % str(funResult), curPlayer.GetPlayerID())
    if funResult != "":
        TurnAttack.GameServer_TurnFight_DoResult(curPlayer, eval(funResult), tick)
    return