diff --git a/Assets/PerfectWorld/Scripts/Task/ATaskTemplMan.cs b/Assets/PerfectWorld/Scripts/Task/ATaskTemplMan.cs index 46446806a2..fcbff250e5 100644 --- a/Assets/PerfectWorld/Scripts/Task/ATaskTemplMan.cs +++ b/Assets/PerfectWorld/Scripts/Task/ATaskTemplMan.cs @@ -44,6 +44,8 @@ namespace BrewMonster.Scripts.Task private elementdataman m_pEleDataMan; #if _TASK_CLIENT + // char m_szDynPackPath[512]; + bool m_bDynTasksVerified; protected special_award m_SpecialAward; #endif @@ -517,5 +519,42 @@ namespace BrewMonster.Scripts.Task #endif } + + // process part +#if _TASK_CLIENT + // void GetTitleTasks(TaskInterface pTask, TaskTemplLst lst); + // void GetAvailableTasks(TaskInterface* pPlayer, TaskTemplLst& lst); + // void ManualTrigTask(TaskInterface* pTask, unsigned long ulTask); + // void ForceGiveUpTask(TaskInterface* pTask, unsigned long ulTask); + // void ForceRemoveFinishTask(TaskInterface* pTask, unsigned long ulTask); + public bool IsDynTasksVerified() { return m_bDynTasksVerified; } + // void SetDynTasksVerified(bool b) { m_bDynTasksVerified = b; } + // void OnDynTasksTimeMark(TaskInterface* pTask, unsigned long ulTimeMark, unsigned short version); + // void OnDynTasksData(TaskInterface* pTask, const void* data, size_t sz, bool ended); + // void OnStorageData(TaskInterface* pTask, const void* data); + // void OnSpecialAward(const special_award* p,TaskInterface* pTask); + // void VerifyDynTasksPack(const char* szPath); + // const special_award* GetSpecialAward() const { return &m_SpecialAward; } + public void ClearSpecailAward() + { + // memset(&m_SpecialAward, 0, sizeof(m_SpecialAward)); + m_SpecialAward = new special_award(); + } + // void SortTasksCanSeekOut(); + // void UpdateTasksSeekOutDiff(TaskInterface* pTask); + // bool IsTaskToPush(int id); + // void ClearTasksToPush() { m_TasksToPush.clear(); } + // bool HasTaskToPush() { return !m_TasksToPush.empty(); } +#else + void CheckDeathTrig(TaskInterface* pTask); + void OnTaskCheckAllTimeLimits(unsigned long ulCurTime); + void OnTaskGetDynTasksTimeMark(TaskInterface* pTask); + void OnTaskGetDynTasksData(TaskInterface* pTask); + void OnTaskGetSpecialAward(TaskInterface* pTask); + void OnTaskRemoveFinishTask(TaskInterface* pTask, unsigned long ulTask); + void OnTaskUpdateStorage(TaskInterface* pTask, unsigned long ulCurTime); + bool UpdateStorage(TaskInterface* pTask, StorageTaskList* pLst, unsigned long ulCurTime, unsigned long idStorage); + bool UpdateOneStorageDebug(TaskInterface* pTask, unsigned long ulCurTime, int idStorage, bool bUseDayAsSeed); +#endif } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs b/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs index 73221fb451..076b1b2bcb 100644 --- a/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs +++ b/Assets/PerfectWorld/Scripts/Task/CECTaskInterface.cs @@ -486,81 +486,307 @@ namespace BrewMonster.Scripts.Task return m_pActiveListBuf; } - private void InitActiveTaskList() + // 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; + // } + + void InitActiveTaskList() { ActiveTaskList pLst = GetActiveTaskList(); - if (pLst == null) return; - + FinishedTaskList pFnsh = GetFinishedTaskList(); + // TaskFinishTimeList* pFnshTime = static_cast(GetFinishedTimeList()); + TaskFinishTimeList pFnshTime = new TaskFinishTimeList(GetFinishedTimeList()); + TaskFinishCountList pFnshCount = new TaskFinishCountList(GetFinishedCntList()); + ActiveTaskEntry[] pEntries = pLst.m_TaskEntries; ATaskTemplMan pMan = GetTaskTemplMan(); - if (pMan == null) return; - // reset counters + if (!CheckVersion() || !pLst.IsValid() || !pFnsh.IsValid() || !pFnshTime.IsValid()) + { + pLst.RemoveAll(); + pFnsh.RemoveAll(); + pFnshTime.RemoveAll(); + // TaskInterface::WriteLog(0, 0, 0, "InitLst, list is invalid"); + } + + if(!pFnshCount.IsValid()) + { + pFnshCount.RemoveAll(); + // TaskInterface::WriteLog(0, 0, 0, "InitLst, finish count list is invalid"); + } + + if (pFnsh.m_FnshHeader.m_Version == 0){ + List list_old = new (); + // list_old.reserve(pFnsh->m_FnshHeader.m_uTaskCount); + list_old.Capacity = pFnsh.m_FnshHeader.m_uTaskCount; // C# equivalent of reserve + // FnshedTaskListOld* pListOld = (FnshedTaskListOld*)pFnsh; + FnshedTaskListOld pListOld = new FnshedTaskListOld(pFnsh.m_Buf); + + for (int i = 0; i < pFnsh.m_FnshHeader.m_uTaskCount; i++) + { + list_old.Add(pListOld.m_aTaskList[i]); + } + + var FnshHeader = pFnsh.m_FnshHeader; + FnshHeader.m_Version = 1; + pFnsh.m_FnshHeader = FnshHeader; + + for (int i = 0; i < pFnsh.m_FnshHeader.m_uTaskCount; i++) + { + pFnsh.m_aTaskList[i].m_uTaskId = (ushort)(list_old[i].m_uTaskId & 0x7fff); + pFnsh.m_aTaskList[i].m_Mask = (byte)(list_old[i].m_uTaskId >> 15); + } + } + + #if _TASK_CLIENT + + // Debug output of finished tasks, for developer use -> not converted to C# + // FILE* fp = fopen("logs\\Tasks.log", "wb"); + // + // if (fp) + // { + // unsigned short magic = 0xfeff; + // fwrite(&magic, sizeof(magic), 1, fp); + // + // for (unsigned long n = 0; n < pFnsh->m_FnshHeader.m_uTaskCount; n++) + // { + // ATaskTempl* pTempl = GetTaskTemplMan()->GetTaskTemplByID(pFnsh->m_aTaskList[n].m_uTaskId); + // + // fwprintf( + // fp, + // L"task = %d, name = %s\r\n", + // pFnsh->m_aTaskList[n].m_uTaskId, + // pTempl ? pTempl->GetName() : L""); + // } + // + // for (unsigned short m = 0; m < pFnshTime->m_uCount; m++) + // { + // ATaskTempl* pTempl = GetTaskTemplMan()->GetTaskTemplByID(pFnshTime->m_aList[m].m_uTaskId); + // unsigned long his_time = pFnshTime->m_aList[m].m_ulTimeMark; + // his_time -= unsigned long(TaskInterface::GetTimeZoneBias() * 60); + // + // if ((long)(his_time) < 0) + // his_time = 0; + // + // tm t = *gmtime((time_t*)&his_time); + // wchar_t buf[256]; + // swprintf(buf, L"%d-%02d-%02d-%02d-%02d-%02d", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); + // + // fwprintf( + // fp, + // L"task = %d, deliver time = %s, name = %s\r\n", + // pFnshTime->m_aList[m].m_uTaskId, + // buf, + // pTempl ? pTempl->GetName() : L""); + // } + // + // fclose(fp); + // } + + if (!GetTaskTemplMan().IsDynTasksVerified()) + { + // ��ȡ��̬�����ʱ���ǩ + _notify_svr(this, ClientNotificationConstants.TASK_CLT_NOTIFY_DYN_TIMEMARK, 0); + } + else + { + // ������⽱����Ϣ + GetTaskTemplMan().ClearSpecailAward(); + _notify_svr(this, ClientNotificationConstants.TASK_CLT_NOTIFY_SPECIAL_AWARD, 0); + + // ��ȡ�ֿ����� + _notify_svr(this, ClientNotificationConstants.TASK_CLT_NOTIFY_STORAGE, 0); + } + + #else + uint ulCurTime = GetCurTime(); + const ATaskTempl pTempl; + pLst.m_Version = TASK_ENTRY_DATA_CUR_VER; + bool bTimeMarkUpdated = pLst.IsTimeMarkUpdate(); pLst.m_uTopShowTaskCount = 0; pLst.m_uTopHideTaskCount = 0; pLst.m_uTitleTaskCount = 0; + #endif - byte i = 0; - while (i < pLst.m_uTaskCount) + // unsigned char i = 0; + + for (int i=0; i < pLst.m_uTaskCount; i++) { - ActiveTaskEntry entry = pLst.m_TaskEntries[i]; - if (entry == null) - { - i++; - continue; - } + ActiveTaskEntry entry = pEntries[i]; - // repair sibling linkage - if (entry.m_NextSblIndex != (char)0xff) + if (!entry.IsValid((char)i, (char)pLst.m_uTaskCount)) { - ActiveTaskEntry entryNextSbl = pLst.m_TaskEntries[entry.m_NextSblIndex]; - if (entryNextSbl == null || entryNextSbl.m_PrevSblIndex != (char)i) - { - entry.m_NextSblIndex = (char)0xff; - } + pLst.RemoveAll(); + // TaskInterface::WriteLog(0, 0, 0, "InitLst, active list is invalid"); + break; } - - // 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; + int i1 = 0; + + while (i1 < pLst.m_uTaskCount) + { + ActiveTaskEntry entry = pEntries[i1]; + + if (entry.m_NextSblIndex != 0xff) { + ActiveTaskEntry entryNextSbl = pEntries[entry.m_NextSblIndex]; + if (entryNextSbl.m_PrevSblIndex != i1) entry.m_NextSblIndex = (char)0xff; + } + if (entry.m_ParentIndex == 0xff) + entry.m_ulTemplAddr = pMan.GetTopTaskByID(entry.m_ID).m_FixedData.m_ID; + else + { + ATaskTempl pParent = pLst.m_TaskEntries[entry.m_ParentIndex].GetTempl(); + + if (pParent != null) + entry.m_ulTemplAddr = pParent.GetConstSubById(entry.m_ID).m_FixedData.m_ID; + else + entry.m_ulTemplAddr = 0; + } + #if _TASK_CLIENT + + #elif _TASK_CLIENT + + // if (entry.m_ulTemplAddr != 0) + // { + // // TaskInterface::WriteLog(0, entry.m_ID, 0, "InitLst, Cant Find Task"); + // + // pLst.ClearTask(this, entry, false); + // continue; + // } + // + // // ������������û��ɣ������ + // if (entry.m_ChildIndex == 0xff + // && entry.GetTempl().m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMNone + // && !entry.IsFinished()) + // { + // // TaskInterface::WriteLog(0, entry.m_ID, 0, "InitLst, Task is Impossible"); + // pLst.ClearTask(this, entry, false); + // continue; + // } + + #endif + + if (entry.m_uCapTaskId != 0) + { + entry.m_ulCapTemplAddr = GetTaskTemplMan().GetTopTaskByID(entry.m_uCapTaskId).m_FixedData.m_ID; + if (entry.m_ulCapTemplAddr != 0) + { + entry.m_uCapTaskId = 0; + // TaskInterface::WriteLog(0, entry.m_uCapTaskId, 0, "InitLst, Cant Find CapTask"); + } + } + else + entry.m_ulCapTemplAddr = 0; + + #if _TASK_CLIENT + + #else + + // if (bTimeMarkUpdated != 0) + // { + // var pTempl = entry.GetTempl(); + // + // if (!pTempl.m_FixedData.m_bAbsTime && !pTempl.m_FixedData.m_bPQTask && !pTempl.m_FixedData.m_bPQSubTask) + // entry.m_ulTaskTime = ulCurTime - entry.m_ulTaskTime; + // } + #endif + + #if _TASK_CLIENT + #elif _TASK_CLIENT + // ��ʼ������������е����ء���ʾ������� + // if (entry.m_ParentIndex == 0xff) + // { + // if (entry.GetTempl()->m_bHidden) + // pLst->m_uTopHideTaskCount++; + // else if (entry.GetTempl()->m_bDisplayInTitleTaskUI) + // pLst->m_uTitleTaskCount++; + // else pLst->m_uTopShowTaskCount++; + // + // } + #endif + + i1++; + } + #if _TASK_CLIENT + #elif _TASK_CLIENT + // pLst->SetTimeMarkUpdate(); + // pLst->UpdateTaskMask(*GetTaskMask()); + #endif + + pLst.UpdateUsedCount(); } public bool CheckTaskForbid(uint task_id){ return false; } @@ -1296,7 +1522,7 @@ namespace BrewMonster.Scripts.Task void _notify_svr(TaskInterface pTask, byte uReason, ushort uTaskID) { - + TaskClient._notify_svr(pTask, uReason, uTaskID); } public bool IsTaskReadyToConfirm(int iTaskID) @@ -1433,6 +1659,11 @@ namespace BrewMonster.Scripts.Task // g_pGame->GetGameSession()->c2s_CmdTaskNotify(pBuf, sz); UnityGameSession.c2s_CmdTaskNotify(pBuf, sz); } + + public byte[] GetFinishedCntList() + { + return m_pFinishedCountListBuf; + } } diff --git a/Assets/PerfectWorld/Scripts/Task/TaskClient.cs b/Assets/PerfectWorld/Scripts/Task/TaskClient.cs index ea4a0ef74f..450c1aa685 100644 --- a/Assets/PerfectWorld/Scripts/Task/TaskClient.cs +++ b/Assets/PerfectWorld/Scripts/Task/TaskClient.cs @@ -290,7 +290,7 @@ namespace BrewMonster.Scripts.Task && pos[2] >= min.z && pos[2] <= max.z; } - private static void _notify_svr(TaskInterface pTask, byte uReason, ushort uTaskID) + public static void _notify_svr(TaskInterface pTask, byte uReason, ushort uTaskID) { ATaskTempl._notify_svr(pTask, uReason, uTaskID); } diff --git a/Assets/PerfectWorld/Scripts/Task/TaskProcess.cs b/Assets/PerfectWorld/Scripts/Task/TaskProcess.cs index 88153334cf..47fd691e2b 100644 --- a/Assets/PerfectWorld/Scripts/Task/TaskProcess.cs +++ b/Assets/PerfectWorld/Scripts/Task/TaskProcess.cs @@ -32,7 +32,7 @@ namespace BrewMonster.Scripts.Task public char m_uState; // Task state public uint m_ulTaskTime; // Timestamp public ushort m_uCapTaskId; // Captain task ID - public uint m_ulTemplAddr; // Template address + public uint m_ulTemplAddr; // Template address -> In C++ this is a pointer, here we use uint to store the ID of the template public uint m_ulCapTemplAddr; // Captain task template address }; @@ -180,34 +180,34 @@ namespace BrewMonster.Scripts.Task // } // bool HasParent() const { return m_ParentIndex != 0xff; } // bool HasChildren() const { return m_ChildIndex != 0xff; } - // bool IsValid(unsigned char uIndex, unsigned char uMaxCount) const - // { - // if (m_ParentIndex != 0xff) - // { - // if (m_ParentIndex >= uIndex || m_ParentIndex >= uMaxCount) - // return false; - // } - // - // if (m_PrevSblIndex != 0xff) - // { - // if (m_PrevSblIndex >= uIndex || m_PrevSblIndex >= uMaxCount) - // return false; - // } - // - // if (m_NextSblIndex != 0xff) - // { - // if (m_NextSblIndex <= uIndex || m_NextSblIndex >= uMaxCount) - // return false; - // } - // - // if (m_ChildIndex != 0xff) - // { - // if (m_ChildIndex <= uIndex || m_ChildIndex >= uMaxCount) - // return false; - // } - // - // return true; - // } + public bool IsValid(char uIndex, char uMaxCount) + { + if (m_ParentIndex != 0xff) + { + if (m_ParentIndex >= uIndex || m_ParentIndex >= uMaxCount) + return false; + } + + if (m_PrevSblIndex != 0xff) + { + if (m_PrevSblIndex >= uIndex || m_PrevSblIndex >= uMaxCount) + return false; + } + + if (m_NextSblIndex != 0xff) + { + if (m_NextSblIndex <= uIndex || m_NextSblIndex >= uMaxCount) + return false; + } + + if (m_ChildIndex != 0xff) + { + if (m_ChildIndex <= uIndex || m_ChildIndex >= uMaxCount) + return false; + } + + return true; + } }; public class ActiveTaskList @@ -309,7 +309,17 @@ namespace BrewMonster.Scripts.Task } // void UpdateTaskMask(unsigned long& ulMask) const; - // void UpdateUsedCount(); + public void UpdateUsedCount() + { + m_uUsedCount = 0; + for (int i = 0; i < m_uTaskCount; i++) + { + ATaskTempl pTempl = m_TaskEntries[i].GetTempl(); + if (pTempl == null) continue; + if (pTempl.m_pParent != null) continue; + m_uUsedCount += pTempl.m_uDepth; + } + } void RealignTask(ActiveTaskEntry pEntry, byte uReserve) { // TODO: implement RealignTask logic @@ -505,13 +515,23 @@ namespace BrewMonster.Scripts.Task // // return NULL; // } - // void RemoveAll() - // { - // unsigned short ver = m_Version; - // memset(this, 0, sizeof(*this)); - // m_Version = ver; - // } - // bool IsValid() const { return m_uTaskCount <= TASK_ACTIVE_LIST_MAX_LEN; } + public void RemoveAll() + { + ushort version = m_Version; // Preserve the version + Array.Clear(header, 0, header.Length); // Clear the header array + m_Version = version; // Restore the version + m_uTaskCount = 0; // Reset task count + m_uUsedCount = 0; // Reset used count + m_uTopShowTaskCount = 0; // Reset top show task count + m_uTopHideTaskCount = 0; // Reset top hide task count + m_uTitleTaskCount = 0; // Reset title task count + for (int i = 0; i < m_TaskEntries.Length; i++) // Clear all task entries + { + m_TaskEntries[i] = null; + } + } + + public bool IsValid() { return m_uTaskCount <= TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN; } // bool IsTimeMarkUpdate() const { return (m_uListState & TLIST_STATE_UPDATE_TIME_MARK) != 0; } // void SetTimeMarkUpdate() { m_uListState |= TLIST_STATE_UPDATE_TIME_MARK; } // void ClearTimeMarkUpdate() { m_uListState &= ~TLIST_STATE_UPDATE_TIME_MARK; } diff --git a/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs b/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs index 9e46c1af91..8ae2907f7d 100644 --- a/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs +++ b/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs @@ -356,6 +356,12 @@ namespace BrewMonster.Scripts.Task header.m_Reserved = m_Buf[3]; return header; } + set + { + Array.Copy(BitConverter.GetBytes(value.m_uTaskCount), 0, m_Buf, 0, 2); + m_Buf[2] = value.m_Version; + m_Buf[3] = value.m_Reserved; + } } @@ -461,4 +467,135 @@ namespace BrewMonster.Scripts.Task return m_FnshHeader.m_uTaskCount <= TaskInterfaceConstants.TASK_FINISHED_LIST_MAX_LEN; } } + + [ StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct TaskFinishCountEntry + { + public ushort TaskId; + public uint FinishCount; + public uint FinishTime; + public uint Unused2; + } + + [ StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct TaskFinishCountList + { + public ushort m_uCount; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN)] + public TaskFinishCountEntry[] m_aList; + + public TaskFinishCountList(byte[] data) + { + int offset = 0; + m_uCount = BitConverter.ToUInt16(data, offset); + offset += 2; + + m_aList = new TaskFinishCountEntry[TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN]; + int entrySize = Marshal.SizeOf(); + for (int i=0; i < m_uCount; i++) + { + m_aList[i] = GPDataTypeHelper.FromBytes(data[offset..]); + offset += entrySize; + } + } + + public uint Search(uint ulID, uint ulTime) + { + // TODO: Implement logic to search + return 0; + } + + public void ResetAt(uint ulID) + { + // TODO: Implement logic to reset at + } + + public void AddOrUpdate(uint ulID, uint ulFinishTime) + { + + } + + public void RemoveAll() + { + m_uCount = 0; + m_aList = Array.Empty(); + } + + public bool IsValid() { return m_uCount <= TaskInterfaceConstants.TASK_FINISH_COUNT_MAX_LEN; } + }; + + public struct FnshedTaskEntryOld + { + public ushort m_uTaskId; + }; + + [ StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct FnshedTaskListOld + { + // union + // { + // struct + // { + // FnshedTaskListHeader m_FnshHeader; + // FnshedTaskEntryOld m_aTaskList[TASK_FINISHED_LIST_MAX_LEN]; + // }; + // unsigned char m_Buf[TASK_FINISHED_LIST_BUF_SIZE_OLD]; + // }; + + public FnshedTaskListHeader m_FnshHeader + { + get + { + var FnshHeader = new FnshedTaskListHeader + { + m_uTaskCount = BitConverter.ToUInt16(m_Buf, 0), + m_Version = m_Buf[2], + m_Reserved = m_Buf[3] + }; + return FnshHeader; + } + set { + Array.Copy(BitConverter.GetBytes(value.m_uTaskCount), 0, m_Buf, 0, 2); + m_Buf[2] = value.m_Version; + m_Buf[3] = value.m_Reserved; + } + } + + // [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_FINISHED_LIST_MAX_LEN)] + public FnshedTaskEntryOld[] m_aTaskList + { + get + { + FnshedTaskEntryOld[] taskList = new FnshedTaskEntryOld[TaskInterfaceConstants.TASK_FINISHED_LIST_MAX_LEN]; + for (int i=0; i < m_FnshHeader.m_uTaskCount; i++) + { + int size = Marshal.SizeOf(); + int startIndex = i * size + 4; // 4 bytes for m_FnshHeader + int endIndex = startIndex + size; + taskList[i] = GPDataTypeHelper.FromBytes(m_Buf[startIndex..endIndex]); + } + return taskList; + } + set + { + for (int i=0; i < value.Length && i < TaskInterfaceConstants.TASK_FINISHED_LIST_MAX_LEN; i++) + { + int size = Marshal.SizeOf(); + int startIndex = i * size + 4; // 4 bytes for m_FnshHeader + byte[] entryBytes = GPDataTypeHelper.ToBytes(value[i]); + Array.Copy(entryBytes, 0, m_Buf, startIndex, size); + } + } + } + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE_OLD)] + public byte[] m_Buf; + + public FnshedTaskListOld(byte[] data) + { + m_Buf = new byte[TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE]; + Array.Copy(data, m_Buf, TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE_OLD); + } + }; } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Task/TaskTempl.cs b/Assets/PerfectWorld/Scripts/Task/TaskTempl.cs index 9d719f0a22..938d39a6dd 100644 --- a/Assets/PerfectWorld/Scripts/Task/TaskTempl.cs +++ b/Assets/PerfectWorld/Scripts/Task/TaskTempl.cs @@ -1306,6 +1306,22 @@ namespace BrewMonster.Scripts.Task public ushort m_uCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN)] public TaskFinishTimeEntry[] m_aList; + + public TaskFinishTimeList(byte[] data) + { + int offset = 0; + m_uCount = BitConverter.ToUInt16(data, offset); + offset += sizeof(ushort); + + m_aList = new TaskFinishTimeEntry[TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN]; + for (int i = 0; i < TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN; i++) + { + m_aList[i].m_uTaskId = BitConverter.ToUInt16(data, offset); + offset += sizeof(ushort); + m_aList[i].m_ulTimeMark = BitConverter.ToUInt32(data, offset); + offset += sizeof(uint); + } + } public void ReadFromBuffer(byte[] data) { @@ -1350,7 +1366,7 @@ namespace BrewMonster.Scripts.Task m_uCount++; } - void RemoveAll() + public void RemoveAll() { m_uCount = 0; for (int i = 0; i < TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN; i++) @@ -1359,7 +1375,7 @@ namespace BrewMonster.Scripts.Task m_aList[i].m_ulTimeMark = 0; } } - bool IsValid() { return m_uCount <= TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN; } + public bool IsValid() { return m_uCount <= TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN; } }; diff --git a/Assets/PerfectWorld/Scripts/Task/UI/TaskTreeView.cs b/Assets/PerfectWorld/Scripts/Task/UI/TaskTreeView.cs index 07a85ded67..e502b0d71e 100644 --- a/Assets/PerfectWorld/Scripts/Task/UI/TaskTreeView.cs +++ b/Assets/PerfectWorld/Scripts/Task/UI/TaskTreeView.cs @@ -110,8 +110,10 @@ namespace BrewMonster.Scripts.Task.UI public TaskTreeViewItem GetItemByData(uint taskType) { + if (m_aTreeViewItems == null) { + m_aTreeViewItems = new TaskTreeViewItem[this.transform.childCount]; m_aTreeViewItems = GetComponentsInChildren(true); } diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs index f5f8dd72c1..a3bbe6e075 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs @@ -1429,342 +1429,6 @@ namespace BrewMonster.UI if (!IsShow()) Show(true); } - bool c(int idFunction, int iService, object pData) - { - AUIDialog pShow1 = null, pShow2 = null; - NPC_ESSENCE? pCurNPCEssence = GetGameUIMan().m_pCurNPCEssence; - - if (idFunction == (int)SERVICE_TYPE.NPC_SELL || idFunction == (int)SERVICE_TYPE.NPC_BUY) - { - //Button pButton; - - //pShow1 = m_pAUIManager.GetDialog("Win_Shop"); - //pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - - //GetHostPlayer().PrepareNPCService(iService); - //GetGameUIMan().m_pDlgShop.UpdateShop(1); - - //if (pCurNPCEssence && pCurNPCEssence.id_repair_service) - //{ - // pShow1.GetDlgItem("Btn_Repair").Show(true); - // pShow1.GetDlgItem("Btn_RepairAll").Show(true); - //} - //else - //{ - // pShow1.GetDlgItem("Btn_Repair").Show(false); - // pShow1.GetDlgItem("Btn_RepairAll").Show(false); - //} - - //pButton = (Button)pShow2.GetDlgItem("Btn_NormalItem"); - //pButton.SetPushed(true); - //pButton = (Button)pShow2.GetDlgItem("Btn_QuestItem"); - //pButton.SetPushed(false); - //GetGameUIMan().m_pDlgInventory.SetShowItem(CDlgInventory::INVENTORY_ITEM_NORMAL); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_INSTALL) - { - pShow1 = m_pAUIManager.GetDialog("Win_Enchase"); - pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_UNINSTALL) - { - pShow1 = m_pAUIManager.GetDialog("Win_Disenchase"); - pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_HEAL) - { - UnityGameSession.c2s_CmdNPCSevHeal(); - GetGameUIMan().EndNPCService(); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_TRANSMIT) - { - //pShow1 = m_pAUIManager.GetDialog("Win_WorldMapTravel"); - //((CDlgWorldMap)pShow1).BuildTravelMap(DATA_TYPE.DT_NPC_TRANSMIT_SERVICE, pData); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_SKILL) - { - //string strText = m_pLst_Main.GetText(m_pLst_Main.GetCurSel()); - //string strHead = GetStringFromTable(249); - //string strComp = (strHead + GetStringFromTable(7107)); - //if (0 == a_stricmp(strText, strComp)) - //{ - // pShow1 = m_pAUIManager.GetDialog("Win_ELFLearn"); - // ((CDlgELFLearn*)pShow1).SetNPCName(pCurNPCEssence.name); - // pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - // GetHostPlayer().PrepareNPCService(iService); - // pShow1.SetData(DATA_TYPE.DT_NPC_SKILL_SERVICE); - //} - //else - //{ - // pShow1 = m_pAUIManager.GetDialog("Win_Teach"); - // GetHostPlayer().PrepareNPCService(iService); - // pShow1.SetData((uint)DATA_TYPE.DT_NPC_SKILL_SERVICE, ""); - // GetGameUIMan().UpdateTeach(0); - //} - } - else if (idFunction == (int)SERVICE_TYPE.NPC_MAKE) - { - //NPC_MAKE_SERVICE pMake = (NPC_MAKE_SERVICE)pData; - //if (pMake.produce_type == 2) - // pShow1 = m_pAUIManager.GetDialog("Win_Produce1"); - //else - // pShow1 = m_pAUIManager.GetDialog("Win_Produce"); - //GetGameUIMan().m_pDlgProduce = (CDlgProduce*)pShow1; - //GetHostPlayer().PrepareNPCService(iService); - //pShow1.SetDataPtr(pMake, "ptr_NPC_MAKE_SERVICE"); - //if (pMake.produce_type == 1 || - // pMake.produce_type == 3 || - // pMake.produce_type == 4 || - // pMake.produce_type == 5) - // GetGameUIMan().m_pDlgProduce.ClearMaterial(); - //pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - //GetGameUIMan().m_pDlgProduce.UpdateProduce(1, 0); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_DECOMPOSE) - { - //pShow1 = m_pAUIManager.GetDialog("Win_Split"); - //pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - //pShow1.SetDataPtr(pData, "ptr_NPC_DECOMPOSE_SERVICE"); - - //PAUIPROGRESS pProgress; - //PAUIIMAGEPICTURE pImage; - - //pImage = (PAUIIMAGEPICTURE)pShow1.GetDlgItem("Item_a"); - //pImage.ClearCover(); - //pImage.SetDataPtr(NULL); - - //pImage = (PAUIIMAGEPICTURE)pShow1.GetDlgItem("Item_b"); - //pImage.ClearCover(); - //pImage.SetDataPtr(NULL); - - //pProgress = (PAUIPROGRESS)pShow1.GetDlgItem("Prgs_1"); - //pProgress.SetProgress(0); - - //pShow1.GetDlgItem("Btn_Start").Enable(false); - //pShow1.GetDlgItem("Btn_Cancel").Enable(true); - //pShow1.GetDlgItem("Txt_no1").SetText(_AL("")); - //pShow1.GetDlgItem("Txt_no2").SetText(_AL("")); - //pShow1.GetDlgItem("Txt_Gold").SetText(_AL("")); - //pShow1.GetDlgItem("Txt_SkillName").SetText(_AL("")); - //pShow1.GetDlgItem("Txt_SkillLevel").SetText(_AL("")); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_WAR_TOWERBUILD) - { - pShow1 = m_pAUIManager.GetDialog("Win_WarTower"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_RESETPROP) - { - pShow1 = m_pAUIManager.GetDialog("Win_ResetProp"); - pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_PETNAME) - { - pShow1 = m_pAUIManager.GetDialog("Win_PetRename"); - pShow2 = m_pAUIManager.GetDialog("Win_PetList"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_PETLEARNSKILL) - { - //CECPetCorral* pPetCorral = GetHostPlayer().GetPetCorral(); - //CECPetData* pPet = pPetCorral.GetActivePet(); - //if (!pPet) - //{ - // GetGameUIMan().MessageBox("", GetStringFromTable(814), MB_OK, A3DCOLORRGB(255, 255, 255)); - // GetGameUIMan().EndNPCService(); - //} - //else - //{ - // pShow1 = m_pAUIManager.GetDialog("Win_Teach"); - // GetHostPlayer().PrepareNPCService(iService); - // pShow1.SetData(DT_NPC_PETLEARNSKILL_SERVICE); - // GetGameUIMan().UpdateTeach(0); - //} - } - else if (idFunction == (int)SERVICE_TYPE.NPC_PETFORGETSKILL) - { - //CECPetCorral* pPetCorral = GetHostPlayer().GetPetCorral(); - //CECPetData* pPet = pPetCorral.GetActivePet(); - //if (!pPet) - //{ - // GetGameUIMan().MessageBox("", GetStringFromTable(814), MB_OK, A3DCOLORRGB(255, 255, 255)); - // GetGameUIMan().EndNPCService(); - //} - //else - // pShow1 = m_pAUIManager.GetDialog("Win_PetRetrain"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_EQUIPBIND) - { - //pShow1 = m_pAUIManager.GetDialog("Win_EquipBind"); - //pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - //pShow1.SetData((DWORD)pData, "ptr_NPC_EQUIPBIND_SERVICE"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_EQUIPDESTROY) - { - pShow1 = m_pAUIManager.GetDialog("Win_EquipDestroy"); - pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_EQUIPUNDESTROY) - { - pShow1 = m_pAUIManager.GetDialog("Win_EquipUndestroy"); - pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_IDENTIFY) - { - //PAUIIMAGEPICTURE pImage; - - //pShow1 = m_pAUIManager.GetDialog("Win_Identify"); - //pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - //pShow1.SetDataPtr(pData, "ptr_NPC_IDENTIFY_SERVICE"); - - //pImage = (PAUIIMAGEPICTURE)pShow1.GetDlgItem("Item"); - //pImage.ClearCover(); - //pImage.SetDataPtr(NULL); - - //pShow1.GetDlgItem("Txt").SetText(_AL("")); - //pShow1.GetDlgItem("Txt_Gold").SetText(_AL("")); - //pShow1.GetDlgItem("Btn_Confirm").Enable(false); - //pShow1.GetDlgItem("Btn_Cancel").Enable(true); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_GIVE_TASK) - { - talk_proc.option opt = new talk_proc.option(); - opt = (talk_proc.option)pData; - int idTask = (int)opt.param; - //if (EC_Game.GetConfigs().IsMiniClient() && CECUIConfig.Instance().GetGameUI().IsTaskDisabledInMiniClient(idTask)) - //{ - // GetGameUIMan().MessageBox("", GetStringFromTable(10714), MB_OK, A3DCOLORRGBA(255, 255, 255, 160)); - //} - //else - { - UnityGameSession.c2s_CmdNPCSevAcceptTask(idTask, 0, 0); - } - GetGameUIMan().EndNPCService(); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_COMPLETE_TASK) - { - AWARD_DATA ad = new AWARD_DATA(); - talk_proc.option opt = (talk_proc.option)pData; - CECTaskInterface pTask = GetHostPlayer().GetTaskInterface(); - - pTask.GetAwardCandidates(opt.param, ref ad); - if (ad.m_ulCandItems > 1) - { - pShow1 = m_pAUIManager.GetDialog("Win_Award"); - //CDlgAward pAward = (pShow1) as CDlgAward; - //if (pAward) pAward.UpdateAwardItem(opt.param, true); - } - else - { - UnityGameSession.c2s_CmdNPCSevReturnTask((int)opt.param, 0); - GetGameUIMan().EndNPCService(); - } - } - else if (idFunction == (int)SERVICE_TYPE.NPC_GIVE_TASK_MATTER) - { - talk_proc.option opt = (talk_proc.option)pData; - UnityGameSession.c2s_CmdNPCSevTaskMatter((int)opt.param); - GetGameUIMan().EndNPCService(); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_STORAGE) - { - //if (GetHostPlayer().TrashBoxHasPsw()) - //{ - // pShow1 = m_pAUIManager.GetDialog("Win_InputString"); - // pShow1.GetDlgItem("DEFAULT_Txt_Input").SetText(_AL("")); - //} - //else - // g_pGame.GetGameSession().c2s_CmdNPCSevOpenTrash(""); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_STORAGE_PASSWORD) - { - pShow1 = m_pAUIManager.GetDialog("Win_InputString3"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_ACCOUNT_STORAGE) - { - //if (CECCrossServer::Instance().IsOnSpecialServer()) - //{ - // GetGameUIMan().ShowErrorMsg(10130); - // GetGameUIMan().EndNPCService(); - //} - //else g_pGame.GetGameSession().c2s_CmdNPCSevOpenAccountBox(); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_ENGRAVE) - { - pShow1 = m_pAUIManager.GetDialog("Win_Engrave"); - pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - } - else if (idFunction == (int)SERVICE_TYPE.NPC_RANDPROP) - { - pShow1 = m_pAUIManager.GetDialog("Win_RandProp"); - pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); - GetHostPlayer().PrepareNPCService(iService); - pShow1.SetDataPtr(pData, "ptr_NPC_RANDPROP_SERVICE"); - } - else if (idFunction == (int)SERVICE_TYPE.TALK_RETURN) - { - OnCommand_back("back"); - return true; // To avoid to close NPC dialog. - } - else if (idFunction == (int)SERVICE_TYPE.TALK_EXIT) - { - GetGameUIMan().EndNPCService(); - - int idCurFinishTask = GetGameUIMan().m_idCurFinishTask; - if (GetData() == NPC_DIALOG.NPC_DIALOG_TASK_TALK && idCurFinishTask > 0) - { - GetHostPlayer().GetTaskInterface().OnUIDialogEnd((uint)idCurFinishTask); - GetGameUIMan().m_idCurFinishTask = -1; - } - } - else if (idFunction == (int)SERVICE_TYPE.TALK_GIVEUP_TASK) - { - talk_proc.option opt = (talk_proc.option)pData; - GetHostPlayer().GetTaskInterface().GiveUpTask(opt.param); - GetGameUIMan().EndNPCService(); - } - else - { - //GetHostPlayer().GetPack(IVTRTYPE_PACK).UnfreezeAllItems(); - GetGameUIMan().EndNPCService(); - } - - if (pShow1) - { - DATA_TYPE DataType = new DATA_TYPE(); - elementdataman pDataMan = ElementDataManProvider.GetElementDataMan(); - - pDataMan.get_data_ptr((uint)iService, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); - - pShow1.Show(true); - - if (pShow2) - { - //POINT ptPos = pShow1.GetPos(); - //if (ptPos.x == 0 && ptPos.y == 0) - //{ - // SIZE s1 = pShow1.GetSize(); - // SIZE s2 = pShow2.GetSize(); - // A3DVIEWPORTPARAM* p = m_pA3DEngine.GetActiveViewport().GetParam(); - // int x, y = (p.Height - max(s1.cy, s2.cy)) / 2; - - // x = (p.Width - s1.cx - s2.cx) / 2; - - // // old : pShow1.SetPos(x, y); - // pShow1.SetPosEx(x, y); - - // x += s1.cx; - - // // old : pShow2.SetPos(x, y); - // pShow2.SetPosEx(x, y); - //} - - pShow2.Show(true); - } - } - Show(false); - - return true; - } - public void OnCommand_back(string szCommand) { @@ -3084,6 +2748,13 @@ namespace BrewMonster.UI { AUIDialog pShow1 = null, pShow2 = null; NPC_ESSENCE? pCurNPCEssence = GetGameUIMan().m_pCurNPCEssence; + + // Check if the integer matches any enum value + if (Enum.IsDefined(typeof(SERVICE_TYPE), idFunction)) + { + SERVICE_TYPE k = (SERVICE_TYPE)idFunction; + BMLogger.Log($" PopupCorrespondingServiceDialog: {k}"); + } if (idFunction == (int)SERVICE_TYPE.NPC_SELL || idFunction == (int)SERVICE_TYPE.NPC_BUY) {