Files
test/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs
T
2025-12-02 14:28:00 +07:00

1440 lines
49 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts.Player;
using CSNetwork.GPDataType;
using PerfectWorld.Scripts.Task;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using CSNetwork;
using UnityEngine;
namespace BrewMonster.Scripts.Task
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Kill_Player_Requirements
{
public const uint MAX_OCCPU_MASK = ((uint)1 << TaskInterfaceConstants.MAX_OCCUPATIONS) - 1u;
public uint m_ulOccupations;
public int m_iMinLevel;
public int m_iMaxLevel;
public int m_iGender;
public int m_iForce;
public Kill_Player_Requirements()
{
m_iMinLevel = 10;
m_iMaxLevel = 100;
m_iGender = 0;
m_iForce = 0;
m_ulOccupations = MAX_OCCPU_MASK;
}
public bool IsMeetAllOccupation()
{
return m_ulOccupations == MAX_OCCPU_MASK;
}
public bool CheckRequirements(int iOccupation, int iLevel, bool bGender, int iForce)
{
bool bForce = false;
// У2ΪŮ // In editor: 1 is male, 2 is female
int iGender = bGender ? 2 : 1;
// 0ûҪ // In editor: 0 means no force requirement
if (m_iForce == 0)
{
bForce = true;
}
// ʾҪ // Otherwise indicates there is a force requirement
else
{
// ͻҹֱõһλʾ // Map force ids to bit positions
int iForceMask = 0;
if (iForce == 0)
{
return false;
}
else if (iForce == 1004)
{
iForceMask = 1 << 0;
}
else if (iForce == 1005)
{
iForceMask = 1 << 1;
}
else if (iForce == 1006)
{
iForceMask = 1 << 2;
}
bForce = (m_iForce & iForceMask) != 0;
}
return ((m_ulOccupations & (1u << iOccupation)) != 0)
&& m_iMinLevel <= iLevel
&& m_iMaxLevel >= iLevel
&& (m_iGender != 0 ? m_iGender == iGender : true)
&& bForce;
}
}
#if _TASK_CLIENT
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Task_State_info
{
public uint m_ulTimeLimit;
public uint m_ulTimePassed;
public uint m_ulNPCToProtect;
public uint m_ulProtectTime;
public uint m_ulWaitTime;
public uint m_ulErrCode;
public uint m_ulGoldWanted;
public uint m_ulReachLevel;
public uint m_ulReachReincarnation;
public uint m_ulReachRealm;
public uint m_ulPremLevelMin;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct m_MonsterWanted_s
{
public uint m_ulMonsterId;
public uint m_ulMonstersToKill;
public uint m_ulMonstersKilled;
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_MONSTER_WANTED)]
public m_MonsterWanted_s[] m_MonsterWanted;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct m_ItemsWanted_s
{
public uint m_ulItemId;
public uint m_ulItemsToGet;
public uint m_ulItemsGained;
public uint m_ulMonsterId;
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_ITEM_WANTED)]
public m_ItemsWanted_s[] m_ItemsWanted;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TASK_INFO_PLAYER
{
public uint m_ulPlayersToKill;
public uint m_ulPlayersKilled;
public Kill_Player_Requirements m_Requirements;
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_PLAYER_WANTED)]
public TASK_INFO_PLAYER[] m_PlayerWanted;
// abase::vector<wchar_t*> m_TaskCharArr (assumed 3 pointers: start, finish, end_of_storage; 32-bit layout)
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct abase_vector_wchar_t_ptr
{
public uint _start;
public uint _finish;
public uint _end_of_storage;
}
public abase_vector_wchar_t_ptr m_TaskCharArr;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Task_Award_Preview
{
public uint m_ulGold;
public uint m_ulExp;
public uint m_ulRealmExp;
public uint m_ulSP;
public bool m_bHasItem;
public bool m_bItemKnown;
public uint m_ulItemTypes;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_ITEM_AWARD)]
public uint[] m_ItemsId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.MAX_ITEM_AWARD)]
public uint[] m_ItemsNum;
public int m_iForceActivity;
public int m_iForceContrib;
public int m_iForceRepu;
}
#endif
public class TaskInterfaceConstants
{
// Task Prerequisite Error Code
public const int TASK_PREREQU_FAIL_INDETERMINATE = 1;
public const int TASK_PREREQU_FAIL_NOT_ROOT = 2;
public const int TASK_PREREQU_FAIL_SAME_TASK = 3;
public const int TASK_PREREQU_FAIL_NO_SPACE = 4;
public const int TASK_PREREQU_FAIL_FULL = 5;
public const int TASK_PREREQU_FAIL_CANT_REDO = 6;
public const int TASK_PREREQU_FAIL_BELOW_LEVEL = 7;
public const int TASK_PREREQU_FAIL_ABOVE_LEVEL = 8;
public const int TASK_PREREQU_FAIL_NO_ITEM = 9;
public const int TASK_PREREQU_FAIL_BELOW_REPU = 10;
public const int TASK_PREREQU_FAIL_CLAN = 11;
public const int TASK_PREREQU_FAIL_WRONG_GENDER = 12;
public const int TASK_PREREQU_FAIL_NOT_IN_OCCU = 13;
public const int TASK_PREREQU_FAIL_WRONG_PERIOD = 14;
public const int TASK_PREREQU_FAIL_PREV_TASK = 15;
public const int TASK_PREREQU_FAIL_MAX_RCV = 16;
public const int TASK_PREREQU_FAIL_NO_DEPOSIT = 17;
public const int TASK_PREREQU_FAIL_NO_TASK = 18;
public const int TASK_PREREQU_FAIL_NOT_CAPTAIN = 19;
public const int TASK_PREREQU_FAIL_ILLEGAL_MEM = 20;
public const int TASK_PREREQU_FAIL_WRONG_TIME = 21;
public const int TASK_PREREQU_FAIL_NO_SUCH_SUB = 22;
public const int TASK_PREREQU_FAIL_MUTEX_TASK = 23;
public const int TASK_PREREQU_FAIL_NOT_IN_ZONE = 24;
public const int TASK_PREREQU_FAIL_WRONG_SUB = 25;
public const int TASK_PREREQU_FAIL_OUTOF_DIST = 26;
public const int TASK_PREREQU_FAIL_GIVEN_ITEM = 27;
public const int TASK_PREREQU_FAIL_LIVING_SKILL = 28;
public const int TASK_PREREQU_FAIL_SPECIAL_AWARD = 29;
public const int TASK_PREREQU_FAIL_GM = 30;
public const int TASK_PREREQU_FAIL_GLOBAL_KEYVAL = 31;
public const int TASK_PREREQU_FAIL_SHIELD_USER = 32;
public const int TASK_PREREQU_FAIL_ALREADY_HAS_PQ = 33;
public const int TASK_PREREQU_FAIL_MAX_ACC_CNT = 34;
public const int TASK_PREREQU_FAIL_RMB_NOT_ENOUGH = 35;
public const int TASK_PREREQU_FAIL_NOT_COUPLE = 36;
public const int TASK_PREREQU_FAIL_ERR_CHAR_TIME = 37;
public const int TASK_PREREQU_FAIL_NOT_IVTRSLOTNUM = 38; // version 81
public const int TASK_PREREQU_FAIL_BELOW_FACTION_CONTRIB = 39; // version 87
public const int TASK_PREREQU_FAIL_BELOW_RECORD_TASKS_NUM = 40; // version 91
public const int TASK_PREREQU_FAIL_OVER_RECEIVE_PER_DAY = 41;
public const int TASK_PREREQU_FAIL_TRANSFORM_MASK = 42;
public const int TASK_PREREQU_FAIL_FORCE = 43;
public const int TASK_PREREQU_FAIL_FORCE_REPUTATION = 44;
public const int TASK_PREREQU_FAIL_FORCE_CONTRIBUTION = 45;
public const int TASK_PREREQU_FAIL_EXP = 46;
public const int TASK_PREREQU_FAIL_SP = 47;
public const int TASK_PREREQU_FAIL_FORCE_AL = 48;
public const int TASK_PREREQU_FAIL_WEDDING_OWNER = 49;
public const int TASK_PREREQU_FAIL_CROSSSERVER_NO_ACOUNT_LIMIT = 50;
public const int TASK_PREREQU_FAIL_CROSSSERVER_NO_MARRIAGE = 51;
public const int TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE = 52;
public const int TASK_PREREQU_FAIL_KING = 53;
public const int TASK_PREREQU_FAIL_IN_TEAM = 54;
public const int TASK_PREREQU_FAIL_TITLE = 55;
public const int TASK_PREREQU_FAIL_HISTORYSTAGE = 56;
public const int TASK_PREREQU_FAIL_NO_GIFTCARD_TASK = 57;
public const int TASK_PREREQU_FAIL_BELOW_REINCARNATION = 57;
public const int TASK_PREREQU_FAIL_ABOVE_REINCARNATION = 58;
public const int TASK_PREREQU_FAIL_BELOW_REALMLEVEL = 59;
public const int TASK_PREREQU_FAIL_ABOVE_REALMLEVEL = 60;
public const int TASK_PREREQU_FAIL_REALM_EXP_FULL = 61;
public const int TASK_PREREQU_FAIL_CARD_COUNT_COLLECTION = 62;
public const int TASK_PREREQU_FAIL_MAX_ROLE_CNT = 63;
public const int TASK_PREREQU_FAIL_CARD_COUNT_RANK = 64;
public const int TASK_PREREQU_FAIL_TASK_FORBID = 65;
public const int TASK_PREREQU_FAIL_NO_NAVIGATE_INSHPAED = 66;
public const int TASK_AWARD_FAIL_GIVEN_ITEM = 150;
public const int TASK_AWARD_FAIL_NEW_TASK = 151;
public const int TASK_AWARD_FAIL_REPUTATION = 152;
public const int TASK_AWARD_FAIL_GLOBAL_KEYVAL = 153;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_ACOUNT_LIMIT = 154;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_ACOUNT_STORAGE = 155;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_DIVORCE = 156;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_FACTION_RALATED = 157;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_FORCE_RALATED = 158;
public const int TASK_AWARD_FAIL_CROSSSERVER_NO_DIVIEND = 159;
public const int TASK_AWARD_FAIL_LEVEL_CHECK = 160;
// Task messages
public const int TASK_MSG_NEW = 1;
public const int TASK_MSG_SUCCESS = 2;
public const int TASK_MSG_FAIL = 3;
public const int TASK_ACTIVE_LIST_HEADER_LEN = 8;
public const int TASK_ACTIVE_LIST_MAX_LEN = 175;
public const int TASK_FINISHED_LIST_MAX_LEN = 2040;
public const int TASK_DATA_BUF_MAX_LEN = 32;
public const int TASK_FINISH_TIME_MAX_LEN = 1700;
public const int TASK_FINISH_COUNT_MAX_LEN = 730;
// 库任务 // Library tasks
public const int TASK_MAX_DELIVER_COUNT = 5;
public const int TASK_STORAGE_COUNT = 32;
public const int TASK_STORAGE_LEN = 10;
public const int TASK_STORAGE_WHELL_SCALE = 10000; // 10000.f originally
// 当前激活的任务列表缓冲区大小 // Current active task list buffer size
public const int TASK_ACTIVE_LIST_BUF_SIZE = (TASK_ACTIVE_LIST_MAX_LEN * TASK_DATA_BUF_MAX_LEN + TASK_ACTIVE_LIST_HEADER_LEN);
// 已完成的任务列表缓冲区大小 // Completed task list buffer size
public const int TASK_FINISHED_LIST_BUF_SIZE = 8192;
public const int TASK_FINISHED_LIST_BUF_SIZE_OLD = 4096;
// 任务全局数据大小 // Task global data size
public const int TASK_GLOBAL_DATA_SIZE = 256;
// 任务完成时间 // Task completion time
public const int TASK_FINISH_TIME_LIST_BUF_SIZE = 10240;
//任务完成次数 // Task completion count
public const int TASK_FINISH_COUNT_LIST_BUF_SIZE = 10240;
// 库任务 // Library tasks
public const int TASK_STORAGE_LIST_BUF_SIZE = 1024;
// Masks
public const int TASK_MASK_KILL_MONSTER = 0x00000001;
public const int TASK_MASK_COLLECT_ITEM = 0x00000002;
public const int TASK_MASK_TALK_TO_NPC = 0x00000004;
public const int TASK_MASK_REACH_SITE = 0x00000008;
public const int TASK_MASK_ANSWER_QUESTION = 0x00000010;
public const int TASK_MASK_TINY_GAME = 0x00000020;
public const int TASK_MASK_KILL_PQ_MONSTER = 0x00000040;
public const int TASK_MASK_KILL_PLAYER = 0x00000080;
public const int MAX_MONSTER_WANTED = 3; // 受ActiveTaskEntry大小限制,最大3 // Limited by ActiveTaskEntry size, max 3
public const int MAX_PLAYER_WANTED = MAX_MONSTER_WANTED;
public const int MAX_ITEM_WANTED = 10;
public const int MAX_ITEM_AWARD = 64;
public const int MAX_MONSTER_SUMMONED = 32; // 最大召唤出的怪物数量 // Maximum number of summoned monsters
public const int MAX_OCCUPATIONS = 12; // 职业 // Occupations
public const int TASK_MSG_CHANNEL_LOCAL = 0;
public const int TASK_MSG_CHANNEL_WORLD = 1;
public const int TASK_MSG_CHANNEL_BROADCAST = 9;
public const int TASK_TEAM_RELATION_MARRIAGE = 1;
public const int TASK_AWARD_MAX_CHANGE_VALUE = 255;
public const int TASK_AWARD_MAX_DISPLAY_VALUE = 64;
public const int TASK_AWARD_MAX_DISPLAY_EXP_CNT = 32; // 表达式的个数 // Number of expressions
public const int TASK_AWARD_MAX_DISPLAY_CHAR_LEN = 64; // 表达式的长度 // Length of expression
public const int TASK_WORLD_CONTRIBUTION_SPEND_PER_DAY = 30; // 免费玩家每日消费贡献度上限 // Daily contribution spend cap for free players
}
public class CECTaskInterface : TaskInterface
{
// public const int TASK_MAX_DELIVER_COUNT = 5;
// public const int TASK_STORAGE_COUNT = 32;
// public const int TASK_STORAGE_LEN = 10;
// public const float TASK_STORAGE_WHELL_SCALE = 10000;
//
// public const int TASK_ACTIVE_LIST_HEADER_LEN = 8;
// public const int TASK_ACTIVE_LIST_MAX_LEN = 175;
// public const int TASK_FINISHED_LIST_MAX_LEN = 2040;
// public const int TASK_DATA_BUF_MAX_LEN = 32;
// public const int TASK_FINISH_TIME_MAX_LEN = 1700;
// public const int TASK_FINISH_COUNT_MAX_LEN = 730;
// µ±Ç°¼¤»îµÄÈÎÎñÁÐ±í»º³åÇø´óС
public int TASK_ACTIVE_LIST_BUF_SIZE =>
(TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN * TaskInterfaceConstants.TASK_DATA_BUF_MAX_LEN + TaskInterfaceConstants.TASK_ACTIVE_LIST_HEADER_LEN);
CECHostPlayer m_pHost;
ActiveTaskList m_pActiveListBuf; // Active task list buffer
// private byte[] m_pActiveListRawBuf; // raw buffer backing for active list (converted from C++)
byte[] m_pFinishedListBuf; // Finished task list buffer
byte[] m_pFinishedTimeListBuf; // Finished time list buffer
byte[] m_pFinishedCountListBuf;// Finished count list buffer
byte[] m_pStorageTaskListBuf; // Storage tasks list buffer
private Dictionary<int, bool> m_TasksToConfirm = new Dictionary<int, bool>();
private readonly System.Collections.Generic.Dictionary<uint, bool> m_emotionTask = new System.Collections.Generic.Dictionary<uint, bool>();
private bool m_bForceNavigateFinish;
private int m_tmFinishDlgShown;
public CECTaskInterface()
{
}
public CECTaskInterface(CECHostPlayer pHost)
{
m_pHost = pHost;
m_pActiveListBuf = null;
m_pFinishedListBuf = null;
m_pFinishedTimeListBuf = null;
m_pFinishedCountListBuf = null;
m_pStorageTaskListBuf = null;
}
// Initialize object
public bool Init(byte[] pActiveListBuf, int iActiveListLen, byte[] pFinishedListBuf,
int iFinishedListLen, byte[] pFinishedTimeListBuf, int iFinishedTimeListLen,
byte[] pFinishedCountListBuf, int iFinishedCountListLen, byte[] pStorageTaskListBuf, int iStorageTaskListLen)
{
// basic argument check (converted from ASSERT)
if (pActiveListBuf == null || pFinishedListBuf == null || pFinishedTimeListBuf == null || pFinishedCountListBuf == null)
{
return false;
}
m_pActiveListBuf = new ActiveTaskList();
m_pActiveListBuf.ReadFromBuffer(pActiveListBuf);
m_pFinishedListBuf = new byte[TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE];
{
int copy = Mathf.Min(iFinishedListLen, TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE);
if (copy > 0) System.Buffer.BlockCopy(pFinishedListBuf, 0, m_pFinishedListBuf, 0, copy);
}
m_pFinishedTimeListBuf = new byte[TaskInterfaceConstants.TASK_FINISH_TIME_LIST_BUF_SIZE];
{
int copy = Mathf.Min(iFinishedTimeListLen, TaskInterfaceConstants.TASK_FINISH_TIME_LIST_BUF_SIZE);
if (copy > 0) System.Buffer.BlockCopy(pFinishedTimeListBuf, 0, m_pFinishedTimeListBuf, 0, copy);
}
m_pFinishedCountListBuf = new byte[TaskInterfaceConstants.TASK_FINISH_COUNT_LIST_BUF_SIZE];
{
int copy = Mathf.Min(iFinishedCountListLen, TaskInterfaceConstants.TASK_FINISH_COUNT_LIST_BUF_SIZE);
if (copy > 0) System.Buffer.BlockCopy(pFinishedCountListBuf, 0, m_pFinishedCountListBuf, 0, copy);
}
m_pStorageTaskListBuf = new byte[TaskInterfaceConstants.TASK_STORAGE_LIST_BUF_SIZE];
{
int copy = Mathf.Min(iStorageTaskListLen, TaskInterfaceConstants.TASK_STORAGE_LIST_BUF_SIZE);
if (copy > 0) System.Buffer.BlockCopy(pStorageTaskListBuf, 0, m_pStorageTaskListBuf, 0, copy);
}
// Clear rest buffer // 清理剩余缓冲区
// No-op in C# because arrays are zero-initialized.
ATaskTemplMan pTaskMan = GetTaskTemplMan();
pTaskMan.Release();
#if UNITY_EDITOR
if (TaskTest.Instance &&
TaskTest.Instance.WasLoadTaskData &&
pTaskMan.TaskLoadedCount > 100)
{
Debug.Log($" [TaskInterface] Using TaskTest loaded data with {pTaskMan.TaskLoadedCount} tasks.");
}
else
{
//string task_data_path = Path.Combine(Application.streamingAssetsPath, "data/tasks.data");
//pTaskMan.LoadTasksFromPack(task_data_path, true);
}
#else
string task_data_path = Path.Combine(Application.streamingAssetsPath, "data/tasks.data");
pTaskMan.LoadTasksFromPack(task_data_path, true);
#endif
pTaskMan.LoadNPCInfoFromPack("data\\task_npc.data");
pTaskMan.VerifyDynTasksPack("userdata\\dyn_tasks.data");
InitActiveTaskList();
m_bForceNavigateFinish = false;
return true;
}
public void CheckPQEnterWorldInit()
{
return;
ActiveTaskList pList = GetActiveTaskList();
List<ActiveTaskEntry> aEntries = new List<ActiveTaskEntry>(pList.m_TaskEntries);
for(var i = 0; i < pList.m_uTaskCount; i++)
{
var CurEntry = aEntries[i];
if (CurEntry.m_ulTemplAddr == 0)
continue;
ATaskTempl pTempl = CurEntry.GetTempl();
if (pTempl == null || !pTempl.m_FixedData.m_bPQTask)
continue;
pTempl.IncValidCount();
// _notify_svr(this, TASK_CLT_NOTIFY_PQ_CHECK_INIT, CurEntry.m_ID);
}
}
public static void WriteLog(int nPlayerId, int nTaskId, int nType, string szLog)
{
//do something?
}
public bool IsDeliverLegal()
{
// return !m_pHost.IsTrading() && m_pHost.GetBoothState() == 0 && !m_pHost.IsDead();
return true;
// TODO: implement
return m_pHost.IsTrading() && m_pHost.GetBoothState() == 0 && !m_pHost.IsDead();
}
public int GetCommonItemCount(uint ulCommonItem)
{
// CECInventory pPack = m_pHost.GetPack();
// return pPack != null ? pPack.GetItemTotalNum((int)ulCommonItem) : 0;
var inv = m_pHost?.GetInventory(InventoryConst.IVTRTYPE_PACK);
return inv != null ? inv.GetItemTotalNum((int)ulCommonItem) : 0;
}
public int GetTaskItemCount(uint ulTaskItem)
{
// CECInventory* pPack = m_pHost.GetTaskPack();
// return pPack ? pPack.GetItemTotalNum((int)ulTaskItem) : 0;
var inv = m_pHost?.GetInventory(InventoryConst.IVTRTYPE_TASKPACK);
return inv != null ? inv.GetItemTotalNum((int)ulTaskItem) : 0;
}
public ATaskTemplMan GetTaskTemplMan()
{
return EC_Game.GetTaskTemplateMan();
}
public ActiveTaskList GetActiveTaskList()
{
return m_pActiveListBuf;
}
private void InitActiveTaskList()
{
ActiveTaskList pLst = GetActiveTaskList();
if (pLst == null) return;
ATaskTemplMan pMan = GetTaskTemplMan();
if (pMan == null) return;
// reset counters
pLst.m_uTopShowTaskCount = 0;
pLst.m_uTopHideTaskCount = 0;
pLst.m_uTitleTaskCount = 0;
byte i = 0;
while (i < pLst.m_uTaskCount)
{
ActiveTaskEntry entry = pLst.m_TaskEntries[i];
if (entry == null)
{
i++;
continue;
}
// repair sibling linkage
if (entry.m_NextSblIndex != (char)0xff)
{
ActiveTaskEntry entryNextSbl = pLst.m_TaskEntries[entry.m_NextSblIndex];
if (entryNextSbl == null || entryNextSbl.m_PrevSblIndex != (char)i)
{
entry.m_NextSblIndex = (char)0xff;
}
}
// resolve template for top-level entries; children left unresolved in C#
if (entry.m_ParentIndex == (char)0xff)
{
// entry.m_ulTemplAddr = 0u;
entry.m_ulTemplAddr = pMan.GetTopTaskByID(entry.m_ID) != null ? 1u : 0u;
ATaskTempl topTempl = pMan.GetTopTaskByID(entry.m_ID);
if (topTempl != null)
{
if (topTempl.m_FixedData.m_bHidden)
pLst.m_uTopHideTaskCount++;
else if (topTempl.m_FixedData.m_bDisplayInTitleTaskUI)
pLst.m_uTitleTaskCount++;
else
pLst.m_uTopShowTaskCount++;
}
}
else
{
entry.m_ulTemplAddr = 0u;
}
// cap template best-effort (no pointer in managed)
if (entry.m_uCapTaskId != 0)
{
ATaskTempl cap = pMan.GetTopTaskByID(entry.m_uCapTaskId);
entry.m_ulCapTemplAddr = 0u;
if (cap == null)
{
entry.m_uCapTaskId = 0;
}
}
else
{
entry.m_ulCapTemplAddr = 0u;
}
i++;
}
// approximate used count
pLst.m_uUsedCount = pLst.m_uTaskCount;
}
public bool CheckTaskForbid(uint task_id){ return false; }
public bool IsAtCrossServer()
{
// TODO: cross server
// return CECCrossServer.Instance().IsOnSpecialServer();
return false;
}
public uint GetPlayerLevel()
{
return (uint)m_pHost.GetBasicProps().iLevel;
}
public uint GetGoldNum()
{
return (uint)m_pHost.GetMoneyAmount();
}
public int GetGlobalValue(int lKey)
{
return EC_Game.GetGameRun().GetCommonData(lKey);
}
// C++: long CECTaskInterface::GetGlobalValue(long lKey)
public long GetGlobalValue(long key)
{
// NOTE: Engine exposes only int common data; cast to long
return EC_Game.GetGameRun().GetCommonData((int)key);
}
public byte GetShapeMask()
{
return m_pHost.GetShapeMask();
}
public int GetPos(float[] pos)
{
A3DVECTOR3 vPos = m_pHost.GetPos();
if (pos != null && pos.Length >= 3)
{
pos[0] = vPos.x;
pos[1] = vPos.y;
pos[2] = vPos.z;
}
var world = World.CECWorld.Instance;
//TODO: world.GetInstanceID()
return world != null ? 0 /*world.GetInstanceID()*/ : 0;
}
public bool CheckSimpleTaskFinshConditon(uint task_id)
{
ATaskTempl pTempl = GetTaskTemplMan().GetTaskTemplByID(task_id);
if (pTempl == null) return false;
if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMSimpleClientTask && pTempl.m_FixedData.m_uiEmotion != 0)
{
if (m_emotionTask != null && m_emotionTask.TryGetValue(task_id, out bool finished))
return finished;
return false;
}
else if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMSimpleClientTaskForceNavi)
{
return GetForceNavigateFinishFlag();
}
return true;
}
public int GetFactionConsumeContrib()
{
return m_pHost.GetContribInfo().consume_contrib;
}
public int GetFactionExpContrib()
{
return m_pHost.GetContribInfo().exp_contrib;
}
public bool HasTask(uint ulTaskId)
{
ActiveTaskList pLst = GetActiveTaskList();
if (pLst == null) return false;
for (int i = 0; i < pLst.m_uTaskCount; i++)
{
ActiveTaskEntry entry = pLst.m_TaskEntries[i];
if ((uint)entry.m_ID == ulTaskId && entry.GetTempl() != null)
return true;
}
return false;
}
// ===== Additional TaskInterface methods ported from C++ =====
public uint GetMaxHistoryLevel()
{
// TODO: Use reincarnation tome when available (GetReincarnationTome().max_level)
return (uint)m_pHost.GetBasicProps().iLevel;
}
public uint GetReincarnationCount()
{
// TODO: Hook to host reincarnation count when available
return 0u;
}
public bool IsRealmExpFull()
{
// TODO: Implement via host API when available
return false;
}
public uint GetReputation()
{
// TODO: Expose reputation on host; return 0 for now
return 0u;
}
public int GetFactionRole()
{
// TODO: Expose faction role id on host
return 0;
}
public bool IsInFaction(uint factionId)
{
// TODO: Expose faction id on host; cannot verify now
return false;
}
public bool IsMale()
{
return m_pHost.m_iGender == GENDER.GENDER_MALE;
}
public uint GetPlayerOccupation()
{
return (uint)m_pHost.m_iProfession;
}
public uint GetCurPeriod()
{
// Maps to "second level" in basic props (realm level)
return (uint)m_pHost.GetBasicProps().iLevel2;
}
public bool IsGM()
{
// TODO: Expose GM flag on host
return false;
}
public bool IsShieldUser()
{
// TODO: Expose ShieldUser flag on host
return false;
}
public bool IsMarried()
{
// TODO: Expose spouse id on host
return false;
}
public bool IsWeddingOwner()
{
// TODO: Expose wedding scene info and compare with host id
return false;
}
public uint GetInvEmptySlot()
{
var inv = m_pHost?.GetInventory(InventoryConst.IVTRTYPE_PACK);
return inv != null ? (uint)inv.GetEmptySlotNum() : 0u;
}
public int GetFactionContrib()
{
return m_pHost.GetContribInfo().cumulate_contrib;
}
public int GetForce()
{
// TODO: Expose force id on host
return 0;
}
public int GetForceReputation()
{
// TODO: Expose force reputation on host
return 0;
}
public int GetForceContribution()
{
// TODO: Expose force contribution on host
return 0;
}
public int GetExp()
{
return m_pHost.GetBasicProps().iExp;
}
public int GetSP()
{
return m_pHost.GetBasicProps().iSP;
}
public int GetForceActivityLevel()
{
// TODO: Expose force activity level on host
return -1;
}
public bool IsKing()
{
// TODO: Expose king status on host
return false;
}
public bool IsInTeam()
{
// TODO: Implement team system and check membership
return false;
}
public uint GetAccountTotalCash()
{
// TODO: Expose account total cash on host/session
return 0u;
}
#if _TASK_CLIENT
// Prepare award preview based on task and state
public void GetTaskAwardPreview(uint ulTaskId, ref Task_Award_Preview p, bool bActiveTask=true)
{
// Zero and init output
p = default;
if (p.m_ItemsId == null) p.m_ItemsId = new uint[TaskInterfaceConstants.MAX_ITEM_AWARD];
if (p.m_ItemsNum == null) p.m_ItemsNum = new uint[TaskInterfaceConstants.MAX_ITEM_AWARD];
// Gather context
ActiveTaskList pLst = GetActiveTaskList();
uint ulCurTime = GetCurTime();
ATaskTempl pTempl = null;
AWARD_DATA ad = default;
uint ulMulti = 1u;
// Resolve template and dynamic award when active
if (bActiveTask && pLst != null)
{
for (int i = 0; i < pLst.m_uTaskCount; i++)
{
ActiveTaskEntry CurEntry = pLst.m_TaskEntries[i];
if (CurEntry.m_ID != ulTaskId || CurEntry.m_ulTemplAddr == 0) continue;
pTempl = CurEntry.GetTempl();
// TODO: CalcAwardData/CalcAwardMulti not implemented yet in C#; use fixed success award and multiplier 1
if (pTempl != null)
{
ad = pTempl.m_FixedData.m_Award_S;
ulMulti = 1u;
}
if (ulMulti == 0u) return;
break;
}
}
// Fallback to top template when inactive
else
{
pTempl = GetTaskTemplMan().GetTopTaskByID(ulTaskId);
if (pTempl == null) return;
ad = pTempl.m_FixedData.m_Award_S;
}
// Fill basic award fields
unchecked
{
p.m_ulGold = ad.m_ulGoldNum * ulMulti;
p.m_ulExp = ad.m_ulExp * ulMulti;
p.m_ulSP = ad.m_ulSP * ulMulti;
}
p.m_iForceActivity = ad.m_iForceActivity;
p.m_iForceContrib = ad.m_iForceContribution;
p.m_iForceRepu = ad.m_iForceReputation;
p.m_ulRealmExp = ad.m_ulRealmExp;
// Apply level coefficient if configured (coefficient table not available; skip scaling)
if (ad.m_bUseLevCo)
{
uint ulLev = GetPlayerLevel();
if (ulLev == 0) ulLev = 1;
uint ulUpper = 0;
if (pTempl != null && pTempl.GetTopTask() != null)
ulUpper = pTempl.GetTopTask().m_FixedData.m_ulPremise_Lev_Max;
if (ulUpper != 0 && ulLev > ulUpper) ulLev = ulUpper;
// NOTE: Original code multiplies by _lev_co[ulLev-1]. Not available here; keep as-is.
}
// Candidate items handling
if (ad.m_ulCandItems == 1 && ad.m_CandItems != null && ad.m_CandItems.Length > 0)
{
p.m_bHasItem = true;
p.m_bItemKnown = true;
AWARD_ITEMS_CAND ic = ad.m_CandItems[0];
if (ic.m_bRandChoose)
{
p.m_bItemKnown = false;
}
else
{
for (int j = 0; j < ic.m_ulAwardItems; j++)
{
ITEM_WANTED wi = ic.m_AwardItems[j];
if (!wi.m_bCommonItem) continue;
else if (wi.m_fProb != 1.0f)
{
p.m_bItemKnown = false;
break;
}
else
{
// Period conversion not implemented; assume valid
if (p.m_ulItemTypes < TaskInterfaceConstants.MAX_ITEM_AWARD)
{
p.m_ItemsId[p.m_ulItemTypes] = wi.m_ulItemTemplId;
p.m_ItemsNum[p.m_ulItemTypes] = wi.m_ulItemNum;
p.m_ulItemTypes++;
}
}
}
}
}
else if (ad.m_ulCandItems > 1)
{
p.m_bHasItem = true;
}
// Done
return;
}
public uint GetTaskCount()
{
ActiveTaskList pLst = GetActiveTaskList();
uint ulCount = 0;
if (pLst == null) return 0u;
for (int i = 0; i < pLst.m_uTaskCount; i++)
{
ActiveTaskEntry CurEntry = pLst.m_TaskEntries[i];
ATaskTempl pTempl = CurEntry.GetTempl();
if (pTempl != null
&& !pTempl.m_FixedData.m_bDisplayInTitleTaskUI
&& CurEntry.m_ParentIndex == (char)0xff)
{
if (!pTempl.m_FixedData.m_bHidden || pTempl.m_FixedData.m_bShowPrompt)
{
ulCount++;
}
}
}
return ulCount;
}
public uint GetTaskId(uint ulIndex)
{
ActiveTaskList pLst = GetActiveTaskList();
byte uTopCount = 0;
int uCount = 0;
if (pLst == null) return 0u;
while (uCount < pLst.m_uTaskCount)
{
ActiveTaskEntry CurEntry = pLst.m_TaskEntries[uCount];
ATaskTempl pTempl = CurEntry.GetTempl();
if (pTempl != null
&& !pTempl.m_FixedData.m_bDisplayInTitleTaskUI
&& CurEntry.m_ParentIndex == (char)0xff)
{
if (!pTempl.m_FixedData.m_bHidden || pTempl.m_FixedData.m_bShowPrompt)
{
if (ulIndex == uTopCount)
return CurEntry.m_ID;
else
uTopCount++;
}
}
uCount++;
}
return 0u;
}
public uint CanDeliverTask(uint ulTaskId)
{
ATaskTempl pTempl = GetTaskTemplMan().GetTopTaskByID(ulTaskId);
if (pTempl == null) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NO_TASK;
if (!IsDeliverLegal()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_INDETERMINATE;
// return pTempl.CheckPrerequisite(this, static_cast<ActiveTaskList*>(GetActiveTaskList()), GetCurTime(), true, true, false);
return pTempl.CheckPrerequisite(this, GetActiveTaskList(), GetCurTime(), true, true, false);
// if (!pTempl.CheckReachLevel(this)) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_LEVEL;
// uint keyCheck = pTempl.CheckGlobalKeyValue(this, false);
// if (keyCheck != 0u) return keyCheck;
return 0u;
}
public void ShowPunchBagMessage(bool bSucced,bool bMax,uint MonsterTemplID,int dps,int dph)
{
// TODO : implement UI message box
// CECGameUIMan* pGameUI = g_pGame->GetGameRun()->GetUIManager()->GetInGameUIMan();
//
// if (pGameUI == NULL) return;
//
// elementdataman *pDataMan = g_pGame->GetElementDataMan();
//
// DATA_TYPE dt;
// MONSTER_ESSENCE *pMonster = (MONSTER_ESSENCE *)pDataMan->get_data_ptr(MonsterTemplID, ID_SPACE_ESSENCE, dt);
//
// ACString strNpcName;
// if( dt == DT_MONSTER_ESSENCE )
// {
// if( pMonster)
// strNpcName = pMonster->name;
// }
//
// ACString str;
// if (!bSucced)
// {
// str.Format(pGameUI->GetStringFromTable(303),strNpcName);
// pGameUI->MessageBox("",str,MB_OK,A3DCOLORRGBA(255, 255, 255, 160));
// }
//
// else if (bMax)
// {
// str.Format(pGameUI->GetStringFromTable(304),dph);
// pGameUI->MessageBox("",str,MB_OK,A3DCOLORRGBA(255, 255, 255, 160));
// }
// else
// {
// str.Format(pGameUI->GetStringFromTable(305),dph);
// pGameUI->MessageBox("",str,MB_OK,A3DCOLORRGBA(255, 255, 255, 160));
// }
}
#endif
private bool GetForceNavigateFinishFlag()
{
return m_bForceNavigateFinish;
}
public void GetTaskStateInfo(uint ulTaskId, ref Task_State_info pInfo, bool bActiveTask=true)
{
// 清零并准备输出结构 // Zero and prepare output struct
pInfo = default;
if (pInfo.m_MonsterWanted == null)
pInfo.m_MonsterWanted = new Task_State_info.m_MonsterWanted_s[TaskInterfaceConstants.MAX_MONSTER_WANTED];
if (pInfo.m_ItemsWanted == null)
pInfo.m_ItemsWanted = new Task_State_info.m_ItemsWanted_s[TaskInterfaceConstants.MAX_ITEM_WANTED];
if (pInfo.m_PlayerWanted == null)
pInfo.m_PlayerWanted = new Task_State_info.TASK_INFO_PLAYER[TaskInterfaceConstants.MAX_PLAYER_WANTED];
ActiveTaskList pLst = GetActiveTaskList();
uint ulCurTime = GetCurTime(); // 当前时间 // current time
ATaskTempl pTempl = null;
ActiveTaskEntry foundEntry = default;
bool hasFoundEntry = false;
if (bActiveTask)
{
// 在激活任务列表中查找 // Search in active task list
for (int i = 0; i < pLst.m_uTaskCount; i++)
{
ActiveTaskEntry CurEntry = pLst.m_TaskEntries[i];
if (CurEntry.m_ID != ulTaskId || CurEntry.m_ulTemplAddr == 0) continue;
pTempl = CurEntry.GetTempl();
foundEntry = CurEntry;
hasFoundEntry = true;
// 检查任务是否可以完成 // Check if task can be completed
if (pTempl != null && pTempl.CanFinishTask(this, CurEntry, ulCurTime))
{
pInfo.m_ulErrCode = pTempl.RecursiveCheckAward(this, pLst, CurEntry, ulCurTime, -1);
if (pInfo.m_ulErrCode == TaskInterfaceConstants.TASK_AWARD_FAIL_LEVEL_CHECK)
{
ATaskTempl pParent = pTempl;
while (pParent != null && pParent.m_FixedData.m_ulPremise_Lev_Min == 0)
pParent = pParent.m_pParent;
if (pParent != null)
pInfo.m_ulPremLevelMin = pParent.m_FixedData.m_ulPremise_Lev_Min;
}
}
pInfo.m_ulTimePassed = ulCurTime > CurEntry.m_ulTaskTime ? (ulCurTime - CurEntry.m_ulTaskTime) : 0;
if (pTempl != null && pTempl.m_FixedData.m_ulPremise_Lev_Min != 0)
{
if (pTempl.m_FixedData.m_bPremCheckMaxHistoryLevel != 0 && GetPlayerLevel() < pTempl.m_FixedData.m_ulPremise_Lev_Min)
{
pInfo.m_ulErrCode = TaskInterfaceConstants.TASK_AWARD_FAIL_LEVEL_CHECK;
pInfo.m_ulPremLevelMin = pTempl.m_FixedData.m_ulPremise_Lev_Min;
}
}
break;
}
}
else
{
pTempl = GetTaskTemplMan().GetTopTaskByID(ulTaskId);
}
if (pTempl == null)
return;
// 基本任务要求 // Basic task requirements
if (pTempl.m_FixedData.m_ulTimeLimit != 0) pInfo.m_ulTimeLimit = pTempl.m_FixedData.m_ulTimeLimit;
if (pTempl.m_FixedData.m_ulGoldWanted != 0) pInfo.m_ulGoldWanted = pTempl.m_FixedData.m_ulGoldWanted;
// 任务类型分支 // Task method branches
if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMCollectNumArticle)
{
for (int j = 0; j < pTempl.m_FixedData.m_ulItemsWanted; j++)
{
var iw = pTempl.m_FixedData.m_ItemsWanted[j];
pInfo.m_ItemsWanted[j].m_ulItemId = iw.m_ulItemTemplId;
pInfo.m_ItemsWanted[j].m_ulItemsToGet = iw.m_ulItemNum;
pInfo.m_ItemsWanted[j].m_ulItemsGained = ATaskTempl._get_item_count(this, iw.m_ulItemTemplId, iw.m_bCommonItem);
}
}
else if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMKillNumMonster)
{
int ulItemCount = 0;
int ulMonsterCount = 0;
for (int j = 0; j < pTempl.m_FixedData.m_ulMonsterWanted; j++)
{
var mw = pTempl.m_FixedData.m_MonsterWanted[j];
if (mw.m_ulDropItemId != 0)
{
pInfo.m_ItemsWanted[ulItemCount].m_ulMonsterId = mw.m_ulMonsterTemplId;
pInfo.m_ItemsWanted[ulItemCount].m_ulItemId = mw.m_ulDropItemId;
pInfo.m_ItemsWanted[ulItemCount].m_ulItemsToGet = mw.m_ulDropItemCount;
pInfo.m_ItemsWanted[ulItemCount].m_ulItemsGained = ATaskTempl._get_item_count(this, mw.m_ulDropItemId, mw.m_bDropCmnItem);
ulItemCount++;
}
else
{
pInfo.m_MonsterWanted[ulMonsterCount].m_ulMonsterId = mw.m_ulMonsterTemplId;
pInfo.m_MonsterWanted[ulMonsterCount].m_ulMonstersToKill = mw.m_ulMonsterNum;
if (bActiveTask && hasFoundEntry)
{
pInfo.m_MonsterWanted[ulMonsterCount].m_ulMonstersKilled = foundEntry.m_wMonsterNum[j];
}
ulMonsterCount++;
}
}
}
else if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMKillPlayer)
{
int ulItemCount = 0;
int ulPlayerCount = 0;
for (int j = 0; j < pTempl.m_FixedData.m_ulPlayerWanted; j++)
{
var pw = pTempl.m_FixedData.m_PlayerWanted[j];
if (pw.m_ulDropItemId != 0)
{
pInfo.m_ItemsWanted[ulItemCount].m_ulItemId = pw.m_ulDropItemId;
pInfo.m_ItemsWanted[ulItemCount].m_ulItemsToGet = pw.m_ulDropItemCount;
pInfo.m_ItemsWanted[ulItemCount].m_ulItemsGained = ATaskTempl._get_item_count(this, pw.m_ulDropItemId, pw.m_bDropCmnItem);
ulItemCount++;
}
else
{
pInfo.m_PlayerWanted[ulPlayerCount].m_ulPlayersToKill = pw.m_ulPlayerNum;
if (bActiveTask && hasFoundEntry)
{
pInfo.m_PlayerWanted[ulPlayerCount].m_ulPlayersKilled = foundEntry.m_wMonsterNum[j];
}
pInfo.m_PlayerWanted[ulPlayerCount].m_Requirements = pw.m_Requirements;
ulPlayerCount++;
}
}
}
else if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMProtectNPC)
{
pInfo.m_ulNPCToProtect = pTempl.m_FixedData.m_ulNPCToProtect;
pInfo.m_ulProtectTime = pTempl.m_FixedData.m_ulProtectTimeLen;
}
else if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMWaitTime)
{
pInfo.m_ulWaitTime = pTempl.m_FixedData.m_ulWaitTime;
}
else if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMGlobalValOK)
{
pTempl.GetGlobalTaskChar(this, pInfo.m_TaskCharArr);
}
else if (pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMReachLevel)
{
pInfo.m_ulReachLevel = pTempl.m_FixedData.m_ulReachLevel;
pInfo.m_ulReachReincarnation = pTempl.m_FixedData.m_ulReachReincarnationCount;
pInfo.m_ulReachRealm = pTempl.m_FixedData.m_ulReachRealmLevel;
}
return;
}
public uint GetCurTime()
{
// use this to avoid task hack by changing the system time
return (uint)EC_Game.GetServerAbsTime();
}
private const string SYMBOL_HOSTNAME = "$name";
public string FormatTaskTalk(string taskTalk)
{
string ret = taskTalk ?? string.Empty;
if (taskTalk == null) return ret;
string strName = m_pHost.GetName(); // assumes string; use ToString() if needed
return ret.Replace(SYMBOL_HOSTNAME, $"&{strName}&");
}
public bool GetAwardCandidates(uint ulTaskId, ref AWARD_DATA pAward)
{
ActiveTaskList pLst = GetActiveTaskList() as ActiveTaskList;
ActiveTaskEntry pEntry = pLst.GetEntry(ulTaskId);
if (pEntry == null || pEntry.m_ulTemplAddr == 0) return false;
uint ulCurTime = GetCurTime();
pEntry.GetTempl().CalcAwardData(
this,
ref pAward,
pEntry,
pEntry.m_ulTaskTime,
ulCurTime);
return true;
}
public uint GetTaskFinishedTime(uint value) { return 0; }
bool IsCaptain()
{
// TO DO: fix later
//CECTeam pTeam = m_pHost.GetTeam();
//if (!pTeam)
// return false;
//return pTeam.GetLeaderID() == m_pHost.GetCharacterID();
return true;
}
public bool CanFinishTask(uint ulTaskId)
{
ActiveTaskEntry pEntry = (GetActiveTaskList() as ActiveTaskList).GetEntry(ulTaskId);
if (pEntry == null)
return false;
ATaskTempl pTempl = pEntry.GetTempl();
if (pTempl == null)
return false;
if (pTempl.m_FixedData.m_bMarriage && !IsCaptain())
return false;
return pTempl.CanFinishTask(this, pEntry, GetCurTime());
}
public bool CanShowTask(uint ulTaskId)
{
ATaskTempl pTempl = GetTaskTemplMan().GetTopTaskByID(ulTaskId);
return pTempl != null && pTempl.CanShowTask(this);
}
public void SetFinishDlgShowTime(int t) { m_tmFinishDlgShown = t; }
public void OnUIDialogEnd(uint ulTask)
{
SetFinishDlgShowTime(0);
ActiveTaskList pLst = GetActiveTaskList() as ActiveTaskList;
ActiveTaskEntry pEntry = pLst.GetEntry(ulTask);
if (pEntry == null || pEntry.m_ulTemplAddr == 0) return;
//ATaskTempl pTempl = (pEntry.m_ulTemplAddr) as ATaskTempl;
ATaskTempl pTempl = GetTaskTemplMan().GetTaskTemplByID(pEntry.m_ulTemplAddr);
switch (pTempl.m_FixedData.m_enumMethod)
{
case (uint)TaskCompletionMethod.enumTMReachSite:
pTempl.IncValidCount();
_notify_svr(this, 3, (ushort)ulTask); //TASK_CLT_NOTIFY_REACH_SITE = 3
break;
}
}
public void GiveUpTask(uint ulTaskId)
{
ActiveTaskEntry pEntry = (GetActiveTaskList() as ActiveTaskList).GetEntry(ulTaskId);
if (pEntry == null || pEntry.GetTempl() == null) return;
_notify_svr(this, 2, (ushort)(pEntry.GetTempl().GetTopTask().GetID())); //TASK_CLT_NOTIFY_CHECK_GIVEUP = 2
}
void _notify_svr(TaskInterface pTask, byte uReason, ushort uTaskID)
{
}
public bool IsTaskReadyToConfirm(int iTaskID)
{
if (m_TasksToConfirm == null) return false;
bool ret;
if (m_TasksToConfirm.TryGetValue(iTaskID, out ret)) return ret;
return false;
}
public bool CheckVersion()
{
// return static_cast<ActiveTaskList*>(GetActiveTaskList())->m_Version == TASK_ENTRY_DATA_CUR_VER;
return GetActiveTaskList().m_Version == TaskTemplConstants.TASK_ENTRY_DATA_CUR_VER;
}
public StorageTaskList GetStorageTaskList()
{
StorageTaskList ret = new StorageTaskList();
ret.ReadByte(m_pStorageTaskListBuf);
return ret;
}
public uint GetTaskMask()
{
return 0;
}
public byte[] GetFinishedTimeList()
{
return m_pFinishedTimeListBuf;
}
void SetForceNavigateFinishFlag(bool bFinish) { m_bForceNavigateFinish = bFinish;} //
public void OnNewTask(int iTaskID)
{
ATaskTempl pTempl = GetTaskTemplMan().GetTaskTemplByID((uint)iTaskID);
if (pTempl != null
&& pTempl.m_FixedData.m_enumMethod== (uint)TaskCompletionMethod.enumTMSimpleClientTaskForceNavi)
{
SetForceNavigateFinishFlag(false);
// TODO: trigger navigation event
// m_pHost.OnNaviageEvent(iTaskID,CECNavigateCtrl::EM_PREPARE);
}
}
public void OnTaskConfirmUpdate()
{
// TODO: update task confirm UI
// CECGameUIMan* pGameUI = g_pGame->GetGameRun()->GetUIManager()->GetInGameUIMan();
// if (pGameUI) pGameUI->UpdateTaskConfirm();
}
public void UpdateConfirmTasksMap()
{
m_TasksToConfirm.Clear();
TaskClient.OnTaskCheckStatus(this);
OnTaskConfirmUpdate();
}
public void OnCompleteTask(int iTaskID)
{
ATaskTempl pTempl = GetTaskTemplMan().GetTaskTemplByID((uint)iTaskID);
if (pTempl != null &&
pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMSimpleClientTaskForceNavi)
{
//TODO: trigger navigation end event
// m_pHost.OnNaviageEvent(iTaskID,CECNavigateCtrl::EM_END);
SetForceNavigateFinishFlag(false);
}
}
public void TakeAwayCommonItem(uint ulTemplId, uint ulNum) {}
public void TakeAwayTaskItem(uint ulTemplId, uint ulNum) {}
public void TakeAwayGold(uint ulNum) {}
public void TakeAwayFactionConsumeContrib(int ulNum){}
public void OnGiveupTask(int iTaskID)
{
ATaskTempl pTempl = GetTaskTemplMan().GetTaskTemplByID((uint)iTaskID);
if (pTempl != null &&
pTempl.m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMSimpleClientTaskForceNavi)
{
// TODO: trigger navigation end event
// m_pHost.OnNaviageEvent(iTaskID,CECNavigateCtrl::EM_END);
SetForceNavigateFinishFlag(false);
}
}
public void UpdateTaskUI(uint idTask, int reason)
{
// TODO: update task UI
// CECGameUIMan* pGameUI = g_pGame->GetGameRun()->GetUIManager()->GetInGameUIMan();
// if (pGameUI)
// {
// pGameUI->UpdateTask(idTask, reason);
// }
}
public bool IsTitleDataReady()
{
return m_pHost.IsTitleDataReady();
}
public FinishedTaskList GetFinishedTaskList()
{
FinishedTaskList ret = new FinishedTaskList();
ret.ReadFromBytes(m_pFinishedListBuf);
return ret;
}
public int GetPlayerId()
{
return m_pHost.GetCharacterID();
}
public void PopChatMessage(int iIndex,int dwNum=0)
{
switch((FixedMsg)iIndex)
{
case FixedMsg.FIXMSG_TASK_LIMIT_INCREASED:
// TODO: show chat message
// g_pGame->GetGameRun()->AddFixedChannelMsg(FIXMSG_TASK_LIMIT_INCREASED,GP_CHAT_SYSTEM);
// EC_Game.GetGameRun().AddFixedChannelMsg(FIXMSG_TASK_LIMIT_INCREASED,GP_CHAT_SYSTEM);
break;
default:
break;
}
}
public void NotifyServer(byte[] pBuf, uint sz)
{
// g_pGame->GetGameSession()->c2s_CmdTaskNotify(pBuf, sz);
UnityGameSession.c2s_CmdTaskNotify(pBuf, sz);
}
}
}