From 453e31ebec1ae159c08bc88e81ff24e14162af49 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 28 五月 2025 15:49:30 +0800
Subject: [PATCH] 92 【主界面】主线任务-服务端

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py     |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py     |  320 +++++++++++++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Task.py      |   83 +++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py       |  116 ++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py         |   31 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeMoney.py |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py       |    7 
 PySysDB/PySysDBPY.h                                                                          |   12 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py  |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py              |   30 ++
 10 files changed, 609 insertions(+), 5 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 4e8a348..f607472 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -144,6 +144,18 @@
 	list		LVAttrValueList;	//每级额外属性值(非累积)
 };
 
+//任务表
+
+struct	tagTask
+{
+	WORD		_TaskID;	//任务ID
+	BYTE		TaskGroup;	//任务组别 0-主线
+	BYTE		TaskType;	//任务类型
+	list		TaskConds;	//任务条件[...]
+	DWORD		NeedValue;	//所需任务值
+	list		AwardItemList;	//奖励物品列表 [[物品ID,个数,是否拍品], ...]
+};
+
 //境界修仙之路
 
 struct	tagRealmXXZL
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index c0ea223..4fe0290 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -4535,6 +4535,12 @@
 Def_PDict_TreeLVUPRemainTime = "TreeLVUPRemainTime" # 仙树升级剩余时间,秒
 Def_PDict_TreeLVUPRefreshTime = "TreeLVUPRefreshTime" # 仙树升级上次刷新时间戳
 
+#任务,每个任务组有且仅有一个进行中的任务
+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" # 已雇佣工人数
 Def_PDict_MineWorkerEnergyUsed = "MineWorkerEnergyUsed" # 今日已消耗体力
@@ -6328,6 +6334,30 @@
 TTLTaskType_CrossBoss, # 跨服boss击杀x次 18
 ) = range(1, 1 + 18)
 
+# 任务类型定义
+TaskTypeList = (
+TaskType_FBPass, # 副本过关到xxx 1
+TaskType_TreeLV, # 仙树达到X级 2
+TaskType_EquipDecompose, # 分解装备x次 3
+TaskType_CutTree, # 消耗X个战锤  4
+TaskType_LV, # 等级提升至x级 5
+TaskType_RealmLV, # 境界达到X级 6
+TaskType_KillNPC, # 击败X只怪物 7
+TaskType_GetMoney, # 累计获得xx货币 8
+) = range(1, 1 + 8)
+
+# 任务分组
+TaskGroupList = (
+TaskGroup_Main, # 主线 0
+) = range(1)
+
+# 任务状态
+TaskStateList = (
+TaskState_None, # 无 0
+TaskState_Doing, # 进行中 1
+TaskState_CanGet, # 可领取 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 f520be2..a2bc72e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -56302,6 +56302,122 @@
 
 
 #------------------------------------------------------
+# B1 10 当前任务信息 #tagMCTaskInfo
+
+class  tagMCTask(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("TaskGroup", c_ubyte),    # 任务组,0-主线
+                  ("TaskID", c_int),    # 当前任务ID,可能为0,表示该分组暂时没有任务
+                  ("CurValue", c_int),    # 当前进度值
+                  ("State", c_ubyte),    # 任务状态 1-进行中 2-可领取
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        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.TaskGroup = 0
+        self.TaskID = 0
+        self.CurValue = 0
+        self.State = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCTask)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B1 10 当前任务信息 //tagMCTaskInfo:
+                                TaskGroup:%d,
+                                TaskID:%d,
+                                CurValue:%d,
+                                State:%d
+                                '''\
+                                %(
+                                self.TaskGroup,
+                                self.TaskID,
+                                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.Head.Cmd,m_NAtagMCTaskInfo.Head.SubCmd))] = m_NAtagMCTaskInfo
+
+
+#------------------------------------------------------
 # B1 15 天道树信息 #tagMCTiandaoTreeInfo
 
 class  tagMCTiandaoTreeInfo(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeMoney.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeMoney.py
index fab2d01..ba72856 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeMoney.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeMoney.py
@@ -16,8 +16,12 @@
 
 import Lang
 import PlayerControl
+import ShareDefine
 import ChConfig
 import GameWorld
+
+moneyNameDict = ShareDefine.MoneyNameDict
+
 ## GM命令执行入口
 #  @param curPlayer 当前玩家
 #  @param list 参数列表 [ <钱币类型><数量>]
@@ -37,13 +41,15 @@
         GameWorld.DebugAnswer(curPlayer, Lang.GBText("参数不正确"))
         return
     #钱币类型范围
-    if moneyType < 1 or moneyType > 4 :
+    if moneyType not in [1, 2, 3, 4] and moneyType not in ShareDefine.MoneyNameDict:
         GameWorld.DebugAnswer(curPlayer, Lang.GBText("钱币类型不正确"))
         return
+    
     #0文不处理
     if moneyCount <= 0 :
         return
     PlayerControl.GiveMoney(curPlayer, moneyType, moneyCount, ChConfig.Def_GiveMoney_GM, {ChConfig.Def_Give_Reason_SonKey:"MakeMoney"})
+    GameWorld.DebugAnswer(curPlayer, "货币%s%s=%s" % (moneyType, moneyNameDict.get(moneyType, moneyType), PlayerControl.GetMoneyReal(curPlayer, moneyType)))
     return
 
         
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
new file mode 100644
index 0000000..c164703
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Task.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.Task
+#
+# @todo:任务
+# @author hxp
+# @date 2025-05-28
+# @version 1.0
+#
+# 详细描述: 任务
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-05-28 16:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import IpyGameDataPY
+import PlayerControl
+import PlayerTask
+import ChConfig
+
+## GM命令执行入口
+#  @param curPlayer 当前玩家
+#  @param playerList 参数列表 [ missionID]
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(curPlayer, paramList):
+    
+    if len(paramList) == 0:
+        GameWorld.DebugAnswer(curPlayer, "重置主线: Task 0")
+        GameWorld.DebugAnswer(curPlayer, "设置任务: Task 任务ID 进度")
+        __ShowTask(curPlayer)
+        return
+    
+    taskID = paramList[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 = paramList[1] if len(paramList) > 1 else 0
+    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
+
+def __ShowTask(curPlayer):
+    taskCount = 0
+    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
+        curState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup)
+        curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup)
+        needValue = ipyData.GetNeedValue()
+        stateStr = "可领" if curState == 2 else "进行中"
+        GameWorld.DebugAnswer(curPlayer, "任务ID:%s 进度:%s/%s 状态:%s(%s)" % (taskID, curValue, needValue, curState, stateStr))
+        taskCount += 1
+        
+    if not taskCount:
+        GameWorld.DebugAnswer(curPlayer, "当前没有任务!")       
+        
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 0f88690..0a9894f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -144,6 +144,15 @@
                         ("list", "LVAttrValueList", 0),
                         ),
 
+                "Task":(
+                        ("WORD", "TaskID", 1),
+                        ("BYTE", "TaskGroup", 0),
+                        ("BYTE", "TaskType", 0),
+                        ("list", "TaskConds", 0),
+                        ("DWORD", "NeedValue", 0),
+                        ("list", "AwardItemList", 0),
+                        ),
+
                 "RealmXXZL":(
                         ("WORD", "TaskID", 1),
                         ("BYTE", "TaskType", 0),
@@ -2823,6 +2832,20 @@
     def GetEatItemAttrValueList(self): return self.attrTuple[7] # 每X个培养丹增加属性值=EatCntEverytime list
     def GetLVAttrTypeList(self): return self.attrTuple[8] # 每级额外属性类(非累积) list
     def GetLVAttrValueList(self): return self.attrTuple[9] # 每级额外属性值(非累积) list
+
+# 任务表
+class IPY_Task():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetTaskID(self): return self.attrTuple[0] # 任务ID WORD
+    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():
@@ -6696,6 +6719,7 @@
         self.__LoadFileData("RolePoint", onlyCheck)
         self.__LoadFileData("LingQiAttr", onlyCheck)
         self.__LoadFileData("LingQiTrain", onlyCheck)
+        self.__LoadFileData("Task", onlyCheck)
         self.__LoadFileData("RealmXXZL", onlyCheck)
         self.__LoadFileData("Realm", onlyCheck)
         self.__LoadFileData("RealmLVUPTask", onlyCheck)
@@ -7258,6 +7282,13 @@
         self.CheckLoadData("LingQiTrain")
         return self.ipyLingQiTrainCache[index]
 
+    def GetTaskCount(self):
+        self.CheckLoadData("Task")
+        return self.ipyTaskLen
+    def GetTaskByIndex(self, index):
+        self.CheckLoadData("Task")
+        return self.ipyTaskCache[index]
+
     def GetRealmXXZLCount(self):
         self.CheckLoadData("RealmXXZL")
         return self.ipyRealmXXZLLen
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index e5d973f..c240c41 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -156,7 +156,7 @@
 import PlayerZhanling
 import PlayerTree
 import PlayerLianTi
-#import PlayerTask
+import PlayerTask
 import PlayerYinji
 import PlayerLove
 import GameObj
@@ -984,7 +984,7 @@
         PlayerGubao.OnPlayerLogin(curPlayer)
         PlayerShentong.OnPlayerLogin(curPlayer)
         PlayerZhanling.OnPlayerLogin(curPlayer)
-        #PlayerTask.OnPlayerLogin(curPlayer)
+        PlayerTask.OnPlayerLogin(curPlayer)
         PlayerTree.OnPlayerLogin(curPlayer)
         PlayerMineArea.OnPlayerLogin(curPlayer)
         PlayerGuaji.OnPlayerLogin(curPlayer)
@@ -5731,6 +5731,9 @@
     #打包直购礼包奖励
     elif rewardType == ChConfig.Def_RewardType_DailyPackBuyGift:
         PlayerGoldGift.GetDailyPackBuyGift(curPlayer, dataEx)
+    #任务奖励
+    elif rewardType == ChConfig.Def_RewardType_Task:
+        PlayerTask.GetTaskAward(curPlayer, dataEx)
     #战令奖励
     elif rewardType == ChConfig.Def_RewardType_Zhanling:
         PlayerZhanling.GetZhanlingReward(curPlayer, dataEx, dataExStr)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index 3d2fbb1..f8b3385 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -104,6 +104,7 @@
 import PlayerGubao
 import PlayerShentong
 import PlayerCharm
+import PlayerTask
 import PlayerFace
 import ChPlayer
 import GMShell
@@ -3556,6 +3557,7 @@
     # 除钻石及绑钻外,未指定操作类型的不记录
     
     EventShell.EventRespons_OnMoneyChange(curPlayer, priceType)
+    PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_GetMoney, value, [priceType])
     
     if priceType not in [IPY_GameWorld.TYPE_Price_Gold_Money, IPY_GameWorld.TYPE_Price_Gold_Paper, ShareDefine.TYPE_Price_PayCoin] \
         and giveType == ChConfig.Def_GiveMoney_Unknown:
@@ -4430,6 +4432,7 @@
             aftBaseCON = curPlayer.GetBaseCON()
             if aftLV > befLV:
                 curPlayer.SetLV(aftLV, False) # 这里不再通知GameServer
+                PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_LV, aftLV)
                 PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_HeroLV, aftLV)
                 PlayerActivity.DoAddActivityByLV(curPlayer, befLV, aftLV)
                 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py
new file mode 100644
index 0000000..c068b95
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTask.py
@@ -0,0 +1,320 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerTask
+#
+# @todo:玩家任务
+# @author hxp
+# @date 2025-05-28
+# @version 1.0
+#
+# 详细描述: 玩家任务
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-05-28 16:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import IpyGameDataPY
+import PlayerControl
+import NetPackCommon
+import ChPyNetSendPack
+import ItemControler
+import IPY_GameWorld
+import GameFuncComm
+import ShareDefine
+import ChConfig
+
+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)
+            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 OnPlayerLogin(curPlayer):
+    __fixRefreshTask(curPlayer)
+    if not __giveNewTask(curPlayer, ChConfig.TaskGroup_Main):
+        SyncTaskInfo(curPlayer)
+    return
+
+def __fixRefreshTask(curPlayer):
+    ## 纠正刷新任务值状态等,一般用于修改任务配置等,玩家登录检查
+    
+    playerID = curPlayer.GetPlayerID()
+    fixGroupList = []
+    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
+        
+        curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup)
+        curState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup)
+        if curState == ChConfig.TaskState_CanGet:
+            continue
+        
+        needFix = False
+        
+        needValue = ipyData.GetNeedValue()
+        taskValue = __GetTaskValue(curPlayer, ipyData)
+        
+        # 可能修改条件配置后,导致任务值不一致,需要修正
+        if taskValue and taskValue != curValue:
+            GameWorld.Log("需要修正任务进度: taskID=%s,curValue=%s,taskValue=%s" % (taskID, curValue, taskValue), playerID)
+            curValue = taskValue
+            needFix = True
+            
+        # 可能修改降低了所需任务值,需要修正下完成状态
+        if curValue >= needValue and curState != ChConfig.TaskState_CanGet:
+            GameWorld.Log("需要修正任务状态: taskID=%s,curValue=%s,needValue=%s,curState=%s" % (taskID, curValue, needValue, curState), playerID)
+            needFix = True
+            
+        if not needFix:
+            continue
+                
+        SetTaskValue(curPlayer, ipyData, taskValue, False)
+        fixGroupList.append(taskGroup)
+        
+    if fixGroupList:
+        SyncTaskInfo(curPlayer, fixGroupList)
+        
+    return
+
+def __giveNewTask(curPlayer, taskGroup=ChConfig.TaskGroup_Main):
+    ## 给新任务
+    taskIDList = GetTaskIDList(taskGroup)
+    if not taskIDList:
+        return
+    playerID = curPlayer.GetPlayerID()
+    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("给第一个任务: taskGroup=%s,newTaskID=%s" % (taskGroup, newTaskID), playerID)
+        
+    elif not taskID and lastTaskID:
+        # 没有当前任务,给下一个任务
+        if lastTaskID not in taskIDList:
+            GameWorld.ErrLog("找不到上一次完成的任务ID! taskGroup=%s,lastTaskID=%s" % (taskGroup, lastTaskID), playerID)
+            return
+        lastIndex = taskIDList.index(lastTaskID)
+        if lastIndex >= len(taskIDList) - 1:
+            GameWorld.DebugLog("已经完成了所有任务: taskGroup=%s,lastTaskID=%s" % (taskGroup, lastTaskID), playerID)
+            return
+        newTaskID = taskIDList[lastIndex + 1]
+        GameWorld.DebugLog("给下一个任务: taskGroup=%s,newTaskID=%s,lastTaskID=%s" % (taskGroup, newTaskID, lastTaskID), playerID)
+        
+    if not newTaskID:
+        return
+    ipyData = IpyGameDataPY.GetIpyGameData("Task", newTaskID)
+    if not ipyData:
+        return
+    taskValue = __GetTaskValue(curPlayer, ipyData)
+    
+    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 __GetTaskValue(curPlayer, ipyData):
+    ## 获取任务类型当前进度值,一般直接 UpdTaskValue 的类型会用到
+    taskValue = 0 # 默认0
+    taskType = ipyData.GetTaskType()
+    conds = ipyData.GetTaskConds()
+    
+    if taskType == ChConfig.TaskType_LV:
+        taskValue = curPlayer.GetLV()
+        
+    elif taskType == ChConfig.TaskType_FBPass:
+        if len(conds) != 2:
+            return 0
+        mapID, lineID = conds
+        passLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
+        taskValue = 1 if passLineID >= lineID else 0
+        
+    elif taskType == ChConfig.TaskType_TreeLV:
+        taskValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)
+        
+    elif taskType == ChConfig.TaskType_RealmLV:
+        taskValue = curPlayer.GetOfficialRank()
+        
+    return taskValue
+
+def UpdTaskValue(curPlayer, taskType):
+    ## 更新任务进度
+    for taskGroup in ChConfig.TaskGroupList:
+        ipyData = __GetDoingTaskIpyData(curPlayer, taskGroup, taskType)
+        if not ipyData:
+            continue
+        curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup)
+        taskValue = __GetTaskValue(curPlayer, ipyData)
+        if taskValue <= curValue:
+            # 有增长才更新
+            continue
+        SetTaskValue(curPlayer, ipyData, taskValue)
+    return
+
+def AddTaskValue(curPlayer, taskType, addValue=1, conds=None):
+    ## 增加任务进度
+    for taskGroup in ChConfig.TaskGroupList:
+        ipyData = __GetDoingTaskIpyData(curPlayer, taskGroup, taskType)
+        if not ipyData:
+            continue
+        if not __CheckTaskCondition(ipyData, conds):
+            continue
+        curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup) + addValue
+        SetTaskValue(curPlayer, ipyData, curValue)
+    return
+
+def __GetDoingTaskIpyData(curPlayer, taskGroup, taskType):
+    ## 获取正在进行中的任务ipyData
+    taskID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskID % taskGroup)
+    if not taskID:
+        return
+    curState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup)
+    if curState != ChConfig.TaskState_Doing:
+        return
+    ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
+    if not ipyData:
+        return
+    if ipyData.GetTaskType() != taskType:
+        return
+    return ipyData
+
+def __CheckTaskCondition(ipyData, conds=None):
+    ## 检查任务条件是否满足
+    taskType = ipyData.GetTaskType()
+    
+    # 获得货币
+    if taskType == ChConfig.TaskType_GetMoney:
+        taskConds = ipyData.GetTaskConds()
+        if not conds or len(conds) != len(taskConds):
+            return
+        if conds[0] != taskConds[0]:
+            return
+        
+    return True
+
+def SetTaskValue(curPlayer, taskIpyData, value=0, isNotify=True):
+    ## 设置当前任务进度值,统一处理任务状态、触发额外逻辑等
+    if not taskIpyData:
+        return
+    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_CanGet:
+        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)
+        
+    if isNotify:
+        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_CanGet)
+    return
+
+def IsTaskFinish(curPlayer, taskID):
+    ## 任务是否已完成 - 规定领奖才算完成
+    ipyData = IpyGameDataPY.GetIpyGameData("Task", taskID)
+    if not ipyData:
+        return
+    taskGroup = ipyData.GetTaskGroup()
+    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()
+    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()
+    curState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskState % taskGroup)
+    curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TaskValue % taskGroup)
+    if curState != ChConfig.TaskState_CanGet:
+        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 % 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])
+        
+    if not __giveNewTask(curPlayer, taskGroup):
+        SyncTaskInfo(curPlayer, [taskGroup])
+        
+    GameFuncComm.DoFuncOpenLogic(curPlayer, [taskID])
+    return
+
+def SyncTaskInfo(curPlayer, taskGroupList=None):
+    syncGroupList = taskGroupList if taskGroupList != 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.TaskList = taskList
+    clientPack.TaskCount = len(clientPack.TaskList)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py
index 906fea0..e104f94 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py
@@ -22,7 +22,7 @@
 import ChPyNetSendPack
 import PlayerControl
 import IPY_GameWorld
-#import PlayerTask
+import PlayerTask
 import ChConfig
 
 import time
@@ -194,7 +194,7 @@
     GameWorld.DebugLog("执行仙树升级! updTreeLV=%s" % updTreeLV, playerID)
     SyncTreeInfo(curPlayer)
     
-    #PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_TreeLV)
+    PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_TreeLV)
     return True
 
 def SyncTreeInfo(curPlayer):

--
Gitblit v1.8.0