From fd569f371890909dc35c09d1275d9204b39d77f9 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 19 四月 2024 11:41:09 +0800
Subject: [PATCH] 10054 【后端】任务系统(支持功能开启任务条件;支持任务分组如主线、支线等;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py   |  221 ++++++++++++++++++--------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Task.py    |   33 ++-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py     |   92 +++++++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py       |   10 
 PySysDB/PySysDBPY.h                                                                        |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py |    9 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                          |   92 +++++++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py            |   21 ++
 8 files changed, 355 insertions(+), 124 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index cab9d6c..e0a6ae0 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -75,6 +75,7 @@
 struct	tagTask
 {
 	WORD		_TaskID;	//任务ID
+	BYTE		TaskGroup;	//任务组别 0-主线
 	BYTE		TaskType;	//任务类型
 	list		TaskConds;	//任务条件[...]
 	DWORD		NeedValue;	//所需任务值
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 9b233d2..f880c1f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -44660,19 +44660,17 @@
 #------------------------------------------------------
 # B1 10 当前任务信息 #tagMCTaskInfo
 
-class  tagMCTaskInfo(Structure):
+class  tagMCTask(Structure):
     _pack_ = 1
     _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ("TaskID", c_int),    # 任务ID
+                  ("TaskGroup", c_ubyte),    # 任务组,0-主线
+                  ("TaskID", c_int),    # 当前任务ID,可能为0,表示该分组暂时没有任务
                   ("CurValue", c_int),    # 当前进度值
+                  ("State", c_ubyte),    # 任务状态 1-进行中 2-已完成
                   ]
 
     def __init__(self):
         self.Clear()
-        self.Cmd = 0xB1
-        self.SubCmd = 0x10
         return
 
     def ReadData(self, stringData, _pos=0, _len=0):
@@ -44681,36 +44679,98 @@
         return _pos + self.GetLength()
 
     def Clear(self):
-        self.Cmd = 0xB1
-        self.SubCmd = 0x10
+        self.TaskGroup = 0
         self.TaskID = 0
         self.CurValue = 0
+        self.State = 0
         return
 
     def GetLength(self):
-        return sizeof(tagMCTaskInfo)
+        return sizeof(tagMCTask)
 
     def GetBuffer(self):
         return string_at(addressof(self), self.GetLength())
 
     def OutputString(self):
         DumpString = '''// B1 10 当前任务信息 //tagMCTaskInfo:
-                                Cmd:%s,
-                                SubCmd:%s,
+                                TaskGroup:%d,
                                 TaskID:%d,
-                                CurValue:%d
+                                CurValue:%d,
+                                State:%d
                                 '''\
                                 %(
-                                self.Cmd,
-                                self.SubCmd,
+                                self.TaskGroup,
                                 self.TaskID,
-                                self.CurValue
+                                self.CurValue,
+                                self.State
+                                )
+        return DumpString
+
+
+class  tagMCTaskInfo(Structure):
+    Head = tagHead()
+    TaskCount = 0    #(BYTE TaskCount)
+    TaskList = list()    #(vector<tagMCTask> TaskList)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB1
+        self.Head.SubCmd = 0x10
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.TaskCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.TaskCount):
+            temTaskList = tagMCTask()
+            _pos = temTaskList.ReadData(_lpData, _pos)
+            self.TaskList.append(temTaskList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB1
+        self.Head.SubCmd = 0x10
+        self.TaskCount = 0
+        self.TaskList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        for i in range(self.TaskCount):
+            length += self.TaskList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.TaskCount)
+        for i in range(self.TaskCount):
+            data = CommFunc.WriteString(data, self.TaskList[i].GetLength(), self.TaskList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                TaskCount:%d,
+                                TaskList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.TaskCount,
+                                "..."
                                 )
         return DumpString
 
 
 m_NAtagMCTaskInfo=tagMCTaskInfo()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTaskInfo.Cmd,m_NAtagMCTaskInfo.SubCmd))] = m_NAtagMCTaskInfo
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTaskInfo.Head.Cmd,m_NAtagMCTaskInfo.Head.SubCmd))] = m_NAtagMCTaskInfo
 
 
 #------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 69631ac..1f5314f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -4432,10 +4432,11 @@
 Def_PDict_TreeLVUPRemainTime = "TreeLVUPRemainTime" # 仙树升级剩余时间,秒
 Def_PDict_TreeLVUPRefreshTime = "TreeLVUPRefreshTime" # 仙树升级上次刷新时间戳
 
-#任务-简化版任务,有且仅有一个进行中的任务
-Def_PDict_TaskIDLast = "TaskIDLast" # 上一次完成的任务ID
-Def_PDict_TaskID = "TaskID" # 当前进行中的任务ID
-Def_PDict_TaskValue = "TaskValue" # 当前进行中的任务进度
+#任务,每个任务组有且仅有一个进行中的任务
+Def_PDict_TaskIDLast = "TaskIDLast_%s" # 上一次完成的任务ID,参数(任务组)
+Def_PDict_TaskID = "TaskID_%s" # 当前进行中的任务ID,参数(任务组)
+Def_PDict_TaskValue = "TaskValue_%s" # 当前进行中的任务进度,参数(任务组)
+Def_PDict_TaskState = "TaskState_%s" # 当前进行中的任务状态 0-无;1-进行中;2-已完成,参数(任务组)
 
 #福地
 Def_PDict_MineWorkerCount = "MineWorkerCount" # 已雇佣工人数
@@ -6194,6 +6195,18 @@
 TaskType_Arena, # 挑战竞技场x次 5
 ) = range(1, 1 + 5)
 
+# 任务分组
+TaskGroupList = (
+TaskGroup_Main, # 主线 0
+) = range(1)
+
+# 任务状态
+TaskStateList = (
+TaskState_None, # 无 0
+TaskState_Doing, # 进行中 1
+TaskState_Finish, # 已完成 2
+) = range(3)
+
 # 充值点券处理类型
 (
 CoinType_Gold, # 直接充仙玉 0
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 9b233d2..f880c1f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -44660,19 +44660,17 @@
 #------------------------------------------------------
 # B1 10 当前任务信息 #tagMCTaskInfo
 
-class  tagMCTaskInfo(Structure):
+class  tagMCTask(Structure):
     _pack_ = 1
     _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ("TaskID", c_int),    # 任务ID
+                  ("TaskGroup", c_ubyte),    # 任务组,0-主线
+                  ("TaskID", c_int),    # 当前任务ID,可能为0,表示该分组暂时没有任务
                   ("CurValue", c_int),    # 当前进度值
+                  ("State", c_ubyte),    # 任务状态 1-进行中 2-已完成
                   ]
 
     def __init__(self):
         self.Clear()
-        self.Cmd = 0xB1
-        self.SubCmd = 0x10
         return
 
     def ReadData(self, stringData, _pos=0, _len=0):
@@ -44681,36 +44679,98 @@
         return _pos + self.GetLength()
 
     def Clear(self):
-        self.Cmd = 0xB1
-        self.SubCmd = 0x10
+        self.TaskGroup = 0
         self.TaskID = 0
         self.CurValue = 0
+        self.State = 0
         return
 
     def GetLength(self):
-        return sizeof(tagMCTaskInfo)
+        return sizeof(tagMCTask)
 
     def GetBuffer(self):
         return string_at(addressof(self), self.GetLength())
 
     def OutputString(self):
         DumpString = '''// B1 10 当前任务信息 //tagMCTaskInfo:
-                                Cmd:%s,
-                                SubCmd:%s,
+                                TaskGroup:%d,
                                 TaskID:%d,
-                                CurValue:%d
+                                CurValue:%d,
+                                State:%d
                                 '''\
                                 %(
-                                self.Cmd,
-                                self.SubCmd,
+                                self.TaskGroup,
                                 self.TaskID,
-                                self.CurValue
+                                self.CurValue,
+                                self.State
+                                )
+        return DumpString
+
+
+class  tagMCTaskInfo(Structure):
+    Head = tagHead()
+    TaskCount = 0    #(BYTE TaskCount)
+    TaskList = list()    #(vector<tagMCTask> TaskList)
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB1
+        self.Head.SubCmd = 0x10
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.TaskCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.TaskCount):
+            temTaskList = tagMCTask()
+            _pos = temTaskList.ReadData(_lpData, _pos)
+            self.TaskList.append(temTaskList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB1
+        self.Head.SubCmd = 0x10
+        self.TaskCount = 0
+        self.TaskList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        for i in range(self.TaskCount):
+            length += self.TaskList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.TaskCount)
+        for i in range(self.TaskCount):
+            data = CommFunc.WriteString(data, self.TaskList[i].GetLength(), self.TaskList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                TaskCount:%d,
+                                TaskList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.TaskCount,
+                                "..."
                                 )
         return DumpString
 
 
 m_NAtagMCTaskInfo=tagMCTaskInfo()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTaskInfo.Cmd,m_NAtagMCTaskInfo.SubCmd))] = m_NAtagMCTaskInfo
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTaskInfo.Head.Cmd,m_NAtagMCTaskInfo.Head.SubCmd))] = m_NAtagMCTaskInfo
 
 
 #------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Task.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Task.py
index d94b64d..fc5d6cf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Task.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Task.py
@@ -29,20 +29,33 @@
 def OnExec(curPlayer, playerList):
     
     if len(playerList) == 0:
+        GameWorld.DebugAnswer(curPlayer, "重置主线: Task 0")
         GameWorld.DebugAnswer(curPlayer, "设置任务: Task 任务ID 进度")
         return
     
     taskID = playerList[0]
+    if not taskID:
+        taskGroup = ChConfig.TaskGroup_Main
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskIDLast % taskGroup, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskID % taskGroup, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue % taskGroup, 0)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskState % taskGroup, 0)
+        PlayerTask.__giveNewTask(curPlayer, taskGroup)
+        return
+    
     taskValue = playerList[1] if len(playerList) > 1 else 0
-    if taskID:
-        ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
-        if not ipyData:
-            GameWorld.DebugAnswer(curPlayer, "该任务ID不存在:%s" % taskID)
-            return
-        
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskID, taskID)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue, taskValue)
-    PlayerTask.SyncTaskInfo(curPlayer)
-    GameWorld.DebugAnswer(curPlayer, "设置任务ID:%s  进度:%s" % (taskID, taskValue))
+    ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
+    if not ipyData:
+        GameWorld.DebugAnswer(curPlayer, "该任务ID不存在:%s" % taskID)
+        return
+    taskGroup = ipyData.GetTaskGroup()
+    needValue = ipyData.GetNeedValue()
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskID % taskGroup, taskID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue % taskGroup, taskValue)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskState % taskGroup, ChConfig.TaskState_Doing)
+    PlayerTask.SetTaskValue(curPlayer, ipyData, taskValue)
+    
+    curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup)
+    GameWorld.DebugAnswer(curPlayer, "设置任务ID:%s  进度:%s/%s" % (taskID, curValue, needValue))
     return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 6b3d8ba..02784f3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -89,6 +89,7 @@
 
                 "Task":(
                         ("WORD", "TaskID", 1),
+                        ("BYTE", "TaskGroup", 0),
                         ("BYTE", "TaskType", 0),
                         ("list", "TaskConds", 0),
                         ("DWORD", "NeedValue", 0),
@@ -2378,10 +2379,11 @@
         return
         
     def GetTaskID(self): return self.attrTuple[0] # 任务ID WORD
-    def GetTaskType(self): return self.attrTuple[1] # 任务类型 BYTE
-    def GetTaskConds(self): return self.attrTuple[2] # 任务条件[...] list
-    def GetNeedValue(self): return self.attrTuple[3] # 所需任务值 DWORD
-    def GetAwardItemList(self): return self.attrTuple[4] # 奖励物品列表 [[物品ID,个数,是否拍品], ...] list
+    def GetTaskGroup(self): return self.attrTuple[1] # 任务组别 0-主线 BYTE
+    def GetTaskType(self): return self.attrTuple[2] # 任务类型 BYTE
+    def GetTaskConds(self): return self.attrTuple[3] # 任务条件[...] list
+    def GetNeedValue(self): return self.attrTuple[4] # 所需任务值 DWORD
+    def GetAwardItemList(self): return self.attrTuple[5] # 奖励物品列表 [[物品ID,个数,是否拍品], ...] list
 
 # 境界修仙之路
 class IPY_RealmXXZL():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
index 0211847..73826b8 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
@@ -49,6 +49,7 @@
 import PlayerArena
 import PlayerFaQi
 import PlayerTJG
+import PlayerTask
 
 
 # 功能开启需执行的函数{功能ID:执行函数, ...} 函数需返回是否激活成功, 功能开启有需要处理功能逻辑的这里增加函数调用配置即可
@@ -133,9 +134,11 @@
             continue
         
         limitMissionID = ipyData.GetLimitMissionID()
-        if limitMissionID and not curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_MissionFinish % limitMissionID):
-            continue
-        
+        if limitMissionID:
+            if not curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_MissionFinish % limitMissionID) \
+                and not PlayerTask.IsTaskFinish(curPlayer, limitMissionID):
+                continue
+            
         limitVIPLV = ipyData.GetLimitVIPLV()
         if limitVIPLV and curPlayer.GetVIPLv() < limitVIPLV:
             continue
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py
index ace7d8a..40b36eb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py
@@ -9,7 +9,7 @@
 # @date 2023-12-20
 # @version 1.0
 #
-# 详细描述: 玩家任务,简化版任务,有且仅有一个进行中的任务
+# 详细描述: 玩家任务
 #
 #-------------------------------------------------------------------------------
 #"""Version = 2023-12-20 12:30"""
@@ -22,38 +22,39 @@
 import ChPyNetSendPack
 import ItemControler
 import IPY_GameWorld
+import GameFuncComm
 import ShareDefine
 import ChConfig
 
 def OnPlayerLogin(curPlayer):
-    __giveNewTask(curPlayer)
-    SyncTaskInfo(curPlayer)
+    if not __giveNewTask(curPlayer, ChConfig.TaskGroup_Main):
+        SyncTaskInfo(curPlayer)
     return
 
-def __giveNewTask(curPlayer):
+def __giveNewTask(curPlayer, taskGroup=ChConfig.TaskGroup_Main):
     ## 给新任务
-    taskIDList = GetTaskIDList()
+    taskIDList = GetTaskIDList(taskGroup)
     if not taskIDList:
         return
     playerID = curPlayer.GetPlayerID()
-    taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID)
-    lastTaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskIDLast)
+    taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+    lastTaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskIDLast % taskGroup)
     newTaskID = 0
     if not taskID and not lastTaskID:
         newTaskID = taskIDList[0]
-        GameWorld.DebugLog("给第一个任务: newTaskID=%s" % (newTaskID), playerID)
+        GameWorld.DebugLog("给第一个任务: taskGroup=%s,newTaskID=%s" % (taskGroup, newTaskID), playerID)
         
     elif not taskID and lastTaskID:
         # 没有当前任务,给下一个任务
         if lastTaskID not in taskIDList:
-            GameWorld.ErrLog("找不到上一次完成的任务ID! lastTaskID=%s" % lastTaskID, playerID)
+            GameWorld.ErrLog("找不到上一次完成的任务ID! taskGroup=%s,lastTaskID=%s" % (taskGroup, lastTaskID), playerID)
             return
         lastIndex = taskIDList.index(lastTaskID)
         if lastIndex >= len(taskIDList) - 1:
-            GameWorld.DebugLog("已经完成了所有任务: lastTaskID=%s" % (lastTaskID), playerID)
+            GameWorld.DebugLog("已经完成了所有任务: lastTaskID=%s,lastTaskID=%s" % (lastTaskID, lastTaskID), playerID)
             return
         newTaskID = taskIDList[lastIndex + 1]
-        GameWorld.DebugLog("给下一个任务: newTaskID=%s,lastTaskID=%s" % (newTaskID, lastTaskID), playerID)
+        GameWorld.DebugLog("给下一个任务: lastTaskID=%s,newTaskID=%s,lastTaskID=%s" % (lastTaskID, newTaskID, lastTaskID), playerID)
         
     if not newTaskID:
         return
@@ -62,7 +63,6 @@
         return
     taskType = ipyData.GetTaskType()
     conds = ipyData.GetTaskConds()
-    needValue = ipyData.GetNeedValue()
     taskValue = 0
     
     if taskType == ChConfig.TaskType_LV:
@@ -74,102 +74,181 @@
         grade = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [mapID])
         taskValue = 1 if grade > 0 else 0
         
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskIDLast, taskID)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskID, newTaskID)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue, taskValue)
-    GameWorld.DebugLog("接到新任务: newTaskID=%s,taskValue=%s/%s" % (newTaskID, taskValue, needValue), playerID)
-    return
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskID % taskGroup, newTaskID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue % taskGroup, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskState % taskGroup, ChConfig.TaskState_Doing)
+    GameWorld.DebugLog("接到新任务: taskGroup=%s,newTaskID=%s" % (taskGroup, newTaskID), playerID)
+    return SetTaskValue(curPlayer, ipyData, taskValue)
 
-def GetTaskIDList():
-    ## 获取所有的任务ID列表
-    key = "TaskIDList"
-    taskIDList = IpyGameDataPY.GetConfigEx(key)
-    if not taskIDList:
-        taskIDList = []
+def GetTaskIDList(taskGroup):
+    ## 获取某个任务分组所有任务ID列表
+    key = "TaskIDListDict"
+    taskIDListDict = IpyGameDataPY.GetConfigEx(key)
+    if not taskIDListDict:
+        taskIDListDict = {}
         ipyDataMgr = IpyGameDataPY.IPY_Data()
         for index in xrange(ipyDataMgr.GetTaskCount()):
             ipyData = ipyDataMgr.GetTaskByIndex(index)
-            taskIDList.append(ipyData.GetTaskID())
-        IpyGameDataPY.SetConfigEx(key, taskIDList)
-        GameWorld.Log("任务ID列表: %s" % taskIDList)
-    return taskIDList
+            taskGroup = ipyData.GetTaskGroup()
+            taskID = ipyData.GetTaskID()
+            if taskGroup not in taskIDListDict:
+                taskIDListDict[taskGroup] = []
+            taskIDList = taskIDListDict[taskGroup]
+            if taskID not in taskIDList:
+                taskIDList.append(taskID)
+        IpyGameDataPY.SetConfigEx(key, taskIDListDict)
+        GameWorld.Log("任务ID列表: %s" % taskIDListDict)
+    return taskIDListDict.get(taskGroup, [])
 
-def UpdTaskValue(curPlayer, taskType, setValue):
+def UpdTaskValue(curPlayer, taskType, setValue, conds=None):
     ## 更新任务进度
-    taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID)
-    if not taskID:
-        return
-    ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
-    if not ipyData:
-        return
-    if ipyData.GetTaskType() != taskType:
-        return
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue, setValue)
-    SyncTaskInfo(curPlayer)
-    GameWorld.DebugLog("更新任务进度: taskType=%s,taskID=%s,setValue=%s" % (taskType, taskID, setValue), curPlayer.GetPlayerID())
+    for taskGroup in ChConfig.TaskGroupList:
+        taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+        if not taskID:
+            continue
+        ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
+        if not ipyData:
+            continue
+        if ipyData.GetTaskType() != taskType:
+            continue
+        if not __CheckTaskCondition(ipyData, conds):
+            continue
+        SetTaskValue(curPlayer, ipyData, setValue)
     return
 
-def AddTaskValue(curPlayer, taskType, addValue=1, conds=[]):
+def AddTaskValue(curPlayer, taskType, addValue=1, conds=None):
     ## 增加任务进度
-    taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID)
-    if not taskID:
-        return
-    ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
-    if not ipyData:
-        return
-    if ipyData.GetTaskType() != taskType:
-        return
+    for taskGroup in ChConfig.TaskGroupList:
+        taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+        if not taskID:
+            continue
+        ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
+        if not ipyData:
+            continue
+        if ipyData.GetTaskType() != taskType:
+            continue
+        if not __CheckTaskCondition(ipyData, conds):
+            continue
+        curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup) + addValue
+        SetTaskValue(curPlayer, ipyData, curValue)
+    return
+
+def __CheckTaskCondition(ipyData, conds=None):
+    ## 检查任务条件是否满足
+    taskType = ipyData.GetTaskType()
     if taskType == ChConfig.TaskType_FBPass:
         taskConds = ipyData.GetTaskConds()
-        if len(conds) != 2 or len(taskConds) != 2:
+        if not conds or len(conds) != 2 or len(taskConds) != 2:
             return
         if conds[0] != taskConds[0]:
             return
         if conds[1] < taskConds[1]:
             return
-    finishNeedValue = ipyData.GetNeedValue()
-    curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue)
-    if curValue >= finishNeedValue:
+        
+    return True
+
+def SetTaskValue(curPlayer, taskIpyData, value=0):
+    ## 设置当前任务进度值,统一处理任务状态、触发额外逻辑等
+    if not taskIpyData:
         return
-    updValue = min(curValue + addValue, ShareDefine.Def_UpperLimit_DWord)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue, updValue)
-    SyncTaskInfo(curPlayer)
-    GameWorld.DebugLog("增加任务进度: taskType=%s,taskID=%s,addValue=%s,updValue=%s" % (taskType, taskID, addValue, updValue), curPlayer.GetPlayerID())
+    playerID = curPlayer.GetPlayerID()
+    taskGroup = taskIpyData.GetTaskGroup()
+    taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+    if taskIpyData.GetTaskID() != taskID:
+        return
+    curState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup)
+    if curState == ChConfig.TaskState_Finish:
+        return
+    taskType = taskIpyData.GetTaskType()
+    finishNeedValue = taskIpyData.GetNeedValue()
+    value = min(value, finishNeedValue, ShareDefine.Def_UpperLimit_DWord)
+    GameWorld.DebugLog("更新任务进度: taskGroup=%s,taskType=%s,taskID=%s,value=%s/%s" 
+                       % (taskGroup, taskType, taskID, value, finishNeedValue), playerID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue % taskGroup, value)
+    if value >= finishNeedValue:
+        __OnTaskFinish(curPlayer, taskGroup, taskID, taskIpyData)
+        
+    SyncTaskInfo(curPlayer, taskGroup)
+    return True
+
+def __OnTaskFinish(curPlayer, taskGroup, taskID, taskIpyData):
+    GameWorld.DebugLog("任务完成: taskGroup=%s,taskID=%s" % (taskGroup, taskID), curPlayer.GetPlayerID())
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskState % taskGroup, ChConfig.TaskState_Finish)
+    GameFuncComm.DoFuncOpenLogic(curPlayer, [taskID])
     return
+
+def IsTaskFinish(curPlayer, taskID):
+    ## 任务是否已完成
+    ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
+    if not ipyData:
+        return
+    taskGroup = ipyData.GetTaskGroup()
+    nowTaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+    if nowTaskID and curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup) == ChConfig.TaskState_Finish:
+        finishTaskID = nowTaskID
+    else:
+        finishTaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskIDLast % taskGroup)
+        
+    if taskID == finishTaskID:
+        return True
+    
+    taskIDList = GetTaskIDList(taskGroup)
+    if finishTaskID not in taskIDList or taskID not in taskIDList:
+        return
+    return taskIDList.index(finishTaskID) >= taskIDList.index(taskID)
 
 def GetTaskAward(curPlayer, taskID):
     ## 领取任务奖励
     playerID = curPlayer.GetPlayerID()
-    curTaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID)
-    if taskID != curTaskID:
-        GameWorld.DebugLog("非当前任务: curTaskID=%s" % curTaskID, playerID)
-        return
     ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
     if not ipyData:
         return
+    taskGroup = ipyData.GetTaskGroup()
+    curTaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+    if taskID != curTaskID:
+        GameWorld.DebugLog("非当前任务: curTaskID=%s" % curTaskID, playerID)
+        return
     needValue = ipyData.GetNeedValue()
     awardItemList = ipyData.GetAwardItemList()
-    curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue)
-    if curValue < needValue:
-        GameWorld.DebugLog("任务进度不足无法领奖: taskID=%s,curValue=%s < %s" % (taskID, curValue, needValue), playerID)
+    curState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup)
+    curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup)
+    if curState != ChConfig.TaskState_Finish:
+        GameWorld.DebugLog("任务未完成无法领奖: taskID=%s,curValue=%s/%s,curState=%s" % (taskID, curValue, needValue, curState), playerID)
         return
     if not ItemControler.CheckPackSpaceEnough(curPlayer, awardItemList):
         return
     
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskIDLast, taskID)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskID, 0)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskIDLast % taskGroup, taskID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskID % taskGroup, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskValue % taskGroup, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TaskState % taskGroup, 0)
     
     for itemID, itemCount, isAuctionItem in awardItemList:
         ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem])
         
-    __giveNewTask(curPlayer)
-    SyncTaskInfo(curPlayer)
+    if not __giveNewTask(curPlayer, taskGroup):
+        SyncTaskInfo(curPlayer, taskGroup)
     return
 
-def SyncTaskInfo(curPlayer):
+def SyncTaskInfo(curPlayer, taskGroup=None):
+    syncGroupList = [taskGroup] if taskGroup != None else ChConfig.TaskGroupList
+    if not syncGroupList:
+        return
+    
+    taskList = []
+    for taskGroup in syncGroupList:
+        task = ChPyNetSendPack.tagMCTask()
+        task.TaskGroup = taskGroup
+        task.TaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+        task.CurValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup)
+        task.State = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup)
+        taskList.append(task)
+        
+    if not taskList:
+        return
+    
     clientPack = ChPyNetSendPack.tagMCTaskInfo()
-    clientPack.TaskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID)
-    clientPack.CurValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue)
+    clientPack.TaskList = taskList
+    clientPack.TaskCount = len(clientPack.TaskList)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return

--
Gitblit v1.8.0