using System; using System.Runtime.InteropServices; using BrewMonster.Network; using BrewMonster.Scripts.Task; using PerfectWorld.Scripts.Task; namespace BrewMonster.Scripts.Task { public partial class ATaskTempl { public uint GetID() { return m_FixedData.m_ID; } // Process Part public uint CheckPrerequisite( TaskInterface pTask, ActiveTaskList pList, uint ulCurTime, bool bCheckPrevTask = true, bool bCheckTeam = true, bool bCheckBudge = true, bool bCheckLevel = true) { uint ulRet = 0u; // �����Ǹ��ڵ� // English: Not the root node if (m_pParent != null) { ulRet = (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NOT_ROOT; goto ret_here; } if (bCheckBudge) { ulRet = CheckBudget(pList); if (ulRet != 0u) goto ret_here; } // else if (pList->GetEntry(m_ID)) // English: Already has the same task else if (pTask.HasTask(m_FixedData.m_ID)) { ulRet = (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_SAME_TASK; goto ret_here; } // �Ƿ����� // English: Is task forbidden if (pTask.CheckTaskForbid(m_FixedData.m_ID)) { ulRet = (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_TASK_FORBID; goto ret_here; } // ��ΪPQ�����ж������Ƿ��Ѿ���PQ���� // English: If current is PQ task, ensure no existing PQ task if (m_FixedData.m_bPQTask) { for (byte i = 0; i < pList.m_uTaskCount; i++) { var CurEntry = pList.m_TaskEntries[i]; if (CurEntry == null) continue; ATaskTempl pTempl = CurEntry.GetTempl(); if (pTempl != null && pTempl.m_FixedData.m_bPQTask) { ulRet = (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ALREADY_HAS_PQ; goto ret_here; } } } ulRet = CheckGivenItems(pTask); if (ulRet != 0u) goto ret_here; // �Ƿ����㷢��ʱ�� // English: Check if within delivery timetable ulRet = CheckTimetable(ulCurTime); if (ulRet != 0u) goto ret_here; // ����ʱ���� // English: Check deliver time ulRet = CheckDeliverTime(pTask, ulCurTime); if (ulRet != 0u) goto ret_here; ulRet = CheckFnshLst(pTask, ulCurTime); if (ulRet != 0u) goto ret_here; // �Ƿ�ﵽ�˺�������ɴ��� // English: Check daily deliver count limit ulRet = CheckDeliverCount(pTask); if (ulRet != 0u) goto ret_here; // �Ƿ�ﵽ��ֵ��� // English: Check RMB/account balance ulRet = CheckAccountRMB(pTask); if (ulRet != 0u) goto ret_here; // �Ƿ������ɫ������¼ʱ������ // English: Check character time requirements ulRet = CheckCharTime(pTask); if (ulRet != 0u) goto ret_here; // Check Level // English: Level constraints if (bCheckLevel) { ulRet = CheckLevel(pTask); if (ulRet != 0u) goto ret_here; } // ת������ // English: Reincarnation constraints ulRet = CheckReincarnation(pTask); if (ulRet != 0u) goto ret_here; // ����ȼ� // English: Realm level constraints ulRet = CheckRealmLevel(pTask); if (ulRet != 0u) goto ret_here; // ���羭���Ƿ����� // English: Realm exp full check ulRet = CheckRealmExpFull(pTask); if (ulRet != 0u) goto ret_here; // ���� // English: Reputation check ulRet = CheckRepu(pTask); if (ulRet != 0u) goto ret_here; // Ѻ�� // English: Deposit check ulRet = CheckDeposit(pTask); if (ulRet != 0u) goto ret_here; // ������Ʒ // English: Items check ulRet = CheckItems(pTask); if (ulRet != 0u) goto ret_here; // ���� // English: Faction check ulRet = CheckFaction(pTask); if (ulRet != 0u) goto ret_here; // �Ա� // English: Gender check ulRet = CheckGender(pTask); if (ulRet != 0u) goto ret_here; // ְҵ // English: Occupation check ulRet = CheckOccupation(pTask); if (ulRet != 0u) goto ret_here; // �����ض�ʱ�� // English: Specific period check ulRet = CheckPeriod(pTask); if (ulRet != 0u) goto ret_here; // �Ƿ�GM // English: GM check ulRet = CheckGM(pTask); if (ulRet != 0u) goto ret_here; // �Ƿ���������û� // English: Shielded user check ulRet = CheckShieldUser(pTask); if (ulRet != 0u) goto ret_here; // �������� // English: Previous task check if (bCheckPrevTask) { ulRet = CheckPreTask(pTask); if (ulRet != 0u) goto ret_here; } // �������� // English: Mutex task check ulRet = CheckMutexTask(pTask, ulCurTime); if (ulRet != 0u) goto ret_here; // ���򴥷� // English: In-zone trigger check ulRet = CheckInZone(pTask); if (ulRet != 0u) goto ret_here; // ������� // English: Team task check if (bCheckTeam) { ulRet = CheckTeamTask(pTask); if (ulRet != 0u) goto ret_here; } // ���� // English: Spouse check ulRet = CheckSpouse(pTask); if (ulRet != 0u) goto ret_here; ulRet = CheckWeddingOwner(pTask); if (ulRet != 0u) goto ret_here; // ���� // English: Marriage check ulRet = CheckMarriage(pTask); if (ulRet != 0u) goto ret_here; // ����������� // English: Living skill check ulRet = CheckLivingSkill(pTask); if (ulRet != 0u) goto ret_here; // �������� // English: Special award activity check ulRet = CheckSpecialAward(pTask); if (ulRet != 0u) goto ret_here; // ȫ��key/value // English: Global key/value ulRet = CheckGlobalKeyValue(pTask, false); if (ulRet != 0u) goto ret_here; if (m_FixedData.m_bCompareItemAndInventory) { ulRet = CheckIvtrEmptySlot(pTask); if (ulRet != 0u) goto ret_here; } // ���ɹ��׶� // English: Faction contribution check ulRet = CheckFactionContrib(pTask); if (ulRet != 0u) goto ret_here; // ��¼��ɽ��������ɸ��� // English: Recorded tasks number check ulRet = CheckRecordTasksNum(pTask); if (ulRet != 0u) goto ret_here; // ����״̬ // English: Transform mask check ulRet = CheckTransform(pTask); if (ulRet != 0u) goto ret_here; // ���� // English: Force check ulRet = CheckForce(pTask); if (ulRet != 0u) goto ret_here; // �������� // English: Force reputation check ulRet = CheckForceReputation(pTask); if (ulRet != 0u) goto ret_here; // ����ս�� // English: Force contribution check ulRet = CheckForceContribution(pTask); if (ulRet != 0u) goto ret_here; // ����ֵ // English: EXP check ulRet = CheckExp(pTask); if (ulRet != 0u) goto ret_here; // Ԫ��ֵ // English: SP check ulRet = CheckSP(pTask); if (ulRet != 0u) goto ret_here; // ������Ծ�ȼ� // English: Force activity level check ulRet = CheckForceActivityLevel(pTask); if (ulRet != 0u) goto ret_here; // ���� // English: King check ulRet = CheckKing(pTask); if (ulRet != 0u) goto ret_here; // ������� // English: Not in team check ulRet = CheckNotInTeam(pTask); if (ulRet != 0u) goto ret_here; // �ƺ� // English: Title check ulRet = CheckTitle(pTask); if (ulRet != 0u) goto ret_here; // ��ʷ�ƽ��׶� // English: History stage check ulRet = CheckHistoryStage(pTask); if (ulRet != 0u) goto ret_here; // �ռ����� // English: Card collection count check ulRet = CheckCardCollection(pTask); if (ulRet != 0u) goto ret_here; // ����ijƷ��ӵ������ // English: Specific card rank count check ulRet = CheckCardRankCount(pTask); if (ulRet != 0u) goto ret_here; // �����󣬲��ܽ�ȡǿ���ƶ����� // English: No navigate when in transform shape ulRet = CheckInTransformShape(pTask); if (ulRet != 0u) goto ret_here; ret_here: // TODO: pTask.GetPlayerId() not available in managed interface; use 0 string log = $"CheckPrerequisite: ret = {ulRet}"; CECTaskInterface.WriteLog(0, (int)m_FixedData.m_ID, 1, log); return ulRet; } #if _TASK_CLIENT // bool CanShowTask (TaskInterface* pTask) const; // bool HasShowCond() const; public void GetGlobalTaskChar(TaskInterface pTask, Task_State_info.abase_vector_wchar_t_ptr TaskCharArr) { // Build display strings for global expressions // 生成用于显示的全局表达式字符串 for (int i = 0; i < (int)m_FixedData.m_ulTaskCharCnt; i++) { // Read one UTF-16 row from m_pTaskChar and convert to C# string // 从 m_pTaskChar 读取一行 UTF-16 并转换为 C# 字符串 int colCount = BrewMonster.Scripts.Task.TaskTemplConstants.TASK_AWARD_MAX_DISPLAY_CHAR_LEN; ushort[] row = new ushort[colCount]; for (int j = 0; j < colCount; j++) { row[j] = m_FixedData.m_pTaskChar[i, j]; } string src = ModelRenderer.Scripts.Common.ByteToStringUtils.UshortArrayToUnicodeString(row); if (string.IsNullOrEmpty(src)) { continue; } // Parse '%' placeholders like %1, %2... and replace with computed values // 解析形如 %1, %2 的占位符并替换为计算结果 var sb = new System.Text.StringBuilder(); int idx = 0; char percent = '%'; // Percent sign // ����% (percent sign) while (idx < src.Length) { int pos = src.IndexOf(percent, idx); if (pos >= 0) { // Append text before '%' // 追加 '%' 之前的文本 sb.Append(src, idx, pos - idx); int j = pos + 1; int startDigits = j; while (j < src.Length && char.IsDigit(src[j])) j++; string digits = (j > startDigits) ? src.Substring(startDigits, j - startDigits) : string.Empty; int nVal; // If there's a valid index after '%', compute the global expression value // ��ȡ���õ�ȫ�ֱ���ʽ�к� (get referenced global expression index) if (!string.IsNullOrEmpty(digits) && int.TryParse(digits, out nVal) && nVal != 0) { // Compute one global expression // ����ȫ�ֱ���ʽ int nRet = (int)CalcOneGlobalExp(pTask, nVal - 1); // Convert number to string and append // ת�����ַ��������ַ��� sb.Append(nRet.ToString()); // Skip all digits after '%' // 跳过 '%' 后面的所有数字 idx = j; continue; } else { // No valid number found; keep the '%' // 未找到合法数字;保留 '%' sb.Append(percent); idx = pos + 1; } } else { // No more '%' found; append the rest // δ�ҵ�ȫ�ֱ�������ʽ����ֱ����ʾ�������� sb.Append(src, idx, src.Length - idx); break; } } string result = sb.ToString(); if (!string.IsNullOrEmpty(result)) { // Original: TaskCharArr.push_back(pszNewchar); // 原逻辑:将结果指针压入向量(此处托管环境不直接推入原生向量) // NOTE: If needed, map 'result' into UI/managed list here. } } } private float CalcOneGlobalExp(TaskInterface pTask, int nIndex) { // Evaluate one global expression row // 计算一行全局表达式 if (nIndex < 0 || nIndex >= (int)m_FixedData.m_ulExpCnt) { return 0f; } try { int colCount = BrewMonster.Scripts.Task.TaskTemplConstants.TASK_AWARD_MAX_DISPLAY_CHAR_LEN; float result = 0f; for (int i = 0; i < colCount; i++) { TASK_EXPRESSION expr = m_FixedData.m_pExpArr[nIndex, i]; if (expr.type == -1) break; // Sentinel terminator // 结束标记 // Fallback evaluation: accumulate values // 回退求值:累加表达式值 result += expr.value; } return result; } catch (System.Exception ex) { CECTaskInterface.WriteLog(0, (int)m_FixedData.m_ID, 0, $"CalcOneGlobalExp, Expression run err: {ex.Message}"); return 0f; } } // bool CanShowInExclusiveUI (TaskInterface* pTask, unsigned long ulCurTime) const; public void OnServerNotify( TaskInterface pTask, ActiveTaskEntry pEntry, ref task_notify_base pNotify, uint sz) { uint ulTime = 0, ulCaptainTask = 0; ActiveTaskList pLst = null; ATaskTempl pSub = new ATaskTempl(); task_sub_tags sub_tags = new task_sub_tags(); // memset(&sub_tags, 0, sizeof(sub_tags)); uint i=0; svr_monster_killed pKilled = null; svr_player_killed pKilledPlayer = null; StorageTaskList pStorage = pTask.GetStorageTaskList(); svr_treasure_map pTreasure = null; var m_enumMethod = m_FixedData.m_enumMethod; switch (pNotify.reason) { case TaskTemplConstants.TASK_SVR_NOTIFY_PLAYER_KILLED: { if (sz != Marshal.SizeOf()) break; if (m_enumMethod != (uint)TaskCompletionMethod.enumTMKillPlayer) break; pKilledPlayer = new svr_player_killed(pNotify); int iIndex = pKilledPlayer.index; if (iIndex < TaskInterfaceConstants.MAX_MONSTER_WANTED) { pEntry.m_wMonsterNum[iIndex] = pKilledPlayer.player_num; } } break; case TaskTemplConstants.TASK_SVR_NOTIFY_TREASURE_MAP: if (m_enumMethod == (uint)TaskCompletionMethod.enumTMReachTreasureZone) { pTreasure = new svr_treasure_map(pNotify); pEntry.m_iUsefulData1 = pTreasure.treasure_index; } break; case TaskTemplConstants.TASK_SVR_NOTIFY_MONSTER_KILLED: if (sz != Marshal.SizeOf()) break; if (m_enumMethod != (uint)TaskCompletionMethod.enumTMKillNumMonster) break; pKilled = new svr_monster_killed(pNotify); for (i = 0; i < m_FixedData.m_ulMonsterWanted; i++) { MONSTER_WANTED mw = m_FixedData.m_MonsterWanted[i]; if (mw.m_ulMonsterTemplId == pKilled.monster_id) { pEntry.m_wMonsterNum[i] = pKilled.monster_num; if (pKilled.dps > 0 && pKilled.dph > 0) { pTask.ShowPunchBagMessage(true,pKilled.dps >= mw.m_iDPS && pKilled.dph >= mw.m_iDPH,pKilled.monster_id,pKilled.dps,pKilled.dph); } break; } } break; case TaskTemplConstants.TASK_SVR_NOTIFY_NEW: var svr_new_task = new svr_new_task(pNotify); if (svr_new_task.valid_size((int)sz) ) break; pLst = pTask.GetActiveTaskList(); svr_new_task.get_data( ref ulTime, ref ulCaptainTask, ref sub_tags ); GetTaskTemplMan().RemoveActiveStorageTask(pStorage, m_FixedData.m_ID); if (sub_tags.sub_task > 0) { pSub = GetConstSubById(sub_tags.sub_task); if (pSub == null) break; } else pSub = null; if (CheckBudget(pLst) > 0) break; DeliverTask( pTask, pLst, null, ulCaptainTask, pTask.GetTaskMask(), ulTime, pSub, ref sub_tags, new TaskGlobalData(), 0); if (m_FixedData.m_lAvailFrequency != (int)TaskAwardFreq.enumTAFNormal && !m_FixedData.m_bAccountTaskLimit && !m_FixedData.m_bRoleTaskLimit) { // static_cast(pTask->GetFinishedTimeList())->AddOrUpdate( // m_ID, // ulTime); var TaskFinishTimeList = new TaskFinishTimeList(); TaskFinishTimeList.ReadFromBuffer(pTask.GetFinishedTimeList()); TaskFinishTimeList.AddOrUpdate(m_FixedData.m_ID, ulTime); } // TODO: Log new task acceptance // if (CanShowPrompt() && !m_bDisplayInTitleTaskUI) TaskInterface::ShowTaskMessage(m_ID, TASK_MSG_NEW); // �������׷�ٷ��������������ʱ�� if (!m_FixedData.m_bHidden && !m_FixedData.m_bDisplayInTitleTaskUI) // TaskInterface::TraceTask(m_ID); // TODO: Log task trace // pTask.TraceTask(m_FixedData.m_ID); if (m_FixedData.m_bDisplayInTitleTaskUI) // TODO: Update title UI // TaskInterface::UpdateTitleUI(m_ID); if ((m_enumMethod == (uint)TaskCompletionMethod.enumTMSimpleClientTask) && m_FixedData.m_uiEmotion > 0) // TODO: Pop emotion UI // TaskInterface::PopEmotionUI(m_ID,m_uiEmotion,true); pTask.OnNewTask((int)m_FixedData.m_ID); break; case TaskTemplConstants.TASK_SVR_NOTIFY_COMPLETE: var svr_task_complete = new svr_task_complete(pNotify); if (svr_task_complete.valid_size((int)sz)) break; svr_task_complete.get_data( ref ulTime, ref sub_tags ); pEntry.m_uState = (char)svr_task_complete.sub_tags.state; if (!pEntry.IsSuccess()) { #if TASK_TEMPL_EDITOR RecursiveCheckPunchMonster(this); #endif } // TODO: Log task completion // if (CanShowPrompt() && !m_bDisplayInTitleTaskUI) TaskInterface::ShowTaskMessage( // m_ID, // (pEntry->IsSuccess() && !pEntry->IsGiveUp()) ? TASK_MSG_SUCCESS : TASK_MSG_FAIL); RecursiveAward( pTask, pTask.GetActiveTaskList(), pEntry, ulTime, -1, ref sub_tags); pTask.UpdateConfirmTasksMap(); // TODO: Show task completion trace // pTask.UpdateTaskEmotionAction(m_FixedData.m_ID); if ((m_enumMethod == (uint)TaskCompletionMethod.enumTMSimpleClientTask) && m_FixedData.m_uiEmotion > 0) // TODO: Pop emotion UI // PopEmotionUI(m_ID,m_uiEmotion,false); if (m_FixedData.m_bDisplayInTitleTaskUI) // TODO: Update title UI // UpdateTitleUI(m_ID); pTask.OnCompleteTask((int)m_FixedData.m_ID); break; case TaskTemplConstants.TASK_SVR_NOTIFY_GIVE_UP: pLst = pTask.GetActiveTaskList(); pLst.ClearTask(pTask, pEntry, false); // TODO: Log task give up // if (m_bDisplayInTitleTaskUI) TaskInterface::UpdateTitleUI(m_ID); // if ((m_enumMethod == enumTMSimpleClientTask) && m_uiEmotion) // TaskInterface::PopEmotionUI(m_ID,m_uiEmotion,false); pTask.OnGiveupTask((int)m_FixedData.m_ID); break; case TaskTemplConstants.TASK_SVR_NOTIFY_FINISHED: pEntry.SetFinished(); break; case TaskTemplConstants.TASK_SVR_NOTIFY_DIS_GLOBAL_VAL: // DisplayTaskCharInfo(pTask, pEntry); break; default: // assert(false); break; } // Update task UI after processing server notification pTask.UpdateTaskUI(pNotify.task, pNotify.reason); } public static void _notify_svr(TaskInterface pTask, byte uReason, ushort uTaskID) { task_notify_base notify = new task_notify_base(); notify.reason = uReason; notify.task = uTaskID; pTask.NotifyServer( ref notify, (uint)Marshal.SizeOf()); } #else // void NotifyClient (TaskInterface* pTask, const ActiveTaskEntry* pEntry, unsigned char uReason, unsigned long ulCurTime, unsigned long ulParam = 0, int dps = 0, int dph = 0) const; // bool CheckGlobalRequired (TaskInterface* pTask, unsigned long ulSubTaskId, const TaskPreservedData* pPreserve, const TaskGlobalData* pGlobal, unsigned short reason) const; // bool CheckKillMonster (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, unsigned long ulTemplId, unsigned long ulLev, bool bTeam, float fRand, int dps, int dph) const; // bool CheckKillPlayer (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, int iOccupation, int iLevel, bool bGender, int iForce, float fRand) const; // void CheckCollectItem (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, bool bAtNPC, int nChoice) const; // void CheckMonsterKilled (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, bool bAtNPC, int nChoice) const; // void CheckMining (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry) const; // void CheckWaitTime (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, unsigned long ulCurTime, bool bAtNPC, int nChoice) const; // void GiveUpOneTask (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, bool bForce) const; // void OnSetFinished (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, bool bNotifyMem = true) const; // bool DeliverAward (TaskInterface* pTask, ActiveTaskList* pList, ActiveTaskEntry* pEntry, int nChoice, bool bNotifyTeamMem = true, TaskGlobalData* pGlobal = NULL) const; // void RemoveAcquiredItem (TaskInterface* pTask, bool bClearTask, bool bSuccess) const; // void TakeAwayGivenItems (TaskInterface* pTask) const; // bool OnDeliverTeamMemTask (TaskInterface* pTask, TaskGlobalData* pGlobal) const; // unsigned long CheckDeliverTask (TaskInterface* pTask, unsigned long ulSubTaskId, TaskGlobalData* pGlobal, bool bNotifyErr = true, bool bMemTask = false, unsigned long ulCapId = 0) const; // bool HasGlobalData() const; #endif #if _TASK_CLIENT // void SyncTaskType(); // ʹ����������������游���� // bool GetShowGfxFlag() { return m_bShowGfxFinished;} // const wchar_t* GetDescription() const { assert(m_pwstrDescript); return (wchar_t*)m_pwstrDescript; } // const wchar_t* GetOkText() const { assert(m_pwstrOkText); return (wchar_t*)m_pwstrOkText; } // const wchar_t* GetNoText() const { assert(m_pwstrNoText); return (wchar_t*)m_pwstrNoText; } public ushort[] GetTribute() { return m_pwstrTribute; } // public talk_proc GetDeliverTaskTalk() { return m_DelvTaskTalk; } public talk_proc GetUnqualifiedTalk() { return m_UnqualifiedTalk; } public talk_proc GetDeliverItemTalk() { return m_DelvItemTalk; } public talk_proc GetUnfinishedTalk() { return m_ExeTalk; } public talk_proc GetAwardTalk() { return m_AwardTalk; } // public uint GetDeliverNPC() { return m_FixedData.m_ulDelvNPC; } public uint GetAwardNPC() { return m_FixedData.m_ulAwardNPC; } // // void SaveToTextFile(FILE* fp); // bool SaveToTextFile(const char* szPath); // void SaveToBinFile(FILE* fp) { SaveBinary(fp); } // void SaveDescription(FILE* fp); // void SaveDescriptionBin(FILE* fp); // void SaveTribute(FILE* fp); // void SaveTributeBin(FILE* fp); // void SaveAllText(FILE* fp); // int MarshalKillMonster(char* pData); // int MarshalCollectItems(char* pData); // int MarshalDynTask(char* pData); // int MarshalSpecialAwardData(char* pData); // // ATaskTempl& operator= (const ATaskTempl& src); // bool operator == (const ATaskTempl& src) const // { // return *(ATaskTemplFixedData*)this == *(const ATaskTemplFixedData*)&src; // } #endif public bool _compare_key_value(TaskInterface pTask, COMPARE_KEY_VALUE CompKeyVal) { long lleftValue = CompKeyVal.lLeftNum; if (CompKeyVal.nLeftType == 0) { lleftValue = pTask.GetGlobalValue(CompKeyVal.lLeftNum); } long lRightValue = CompKeyVal.lRightNum; if (CompKeyVal.nRightType == 0) { lRightValue = pTask.GetGlobalValue(CompKeyVal.lRightNum); } switch(CompKeyVal.nCompOper) { case 0: { if (lleftValue > lRightValue) return true; } break; case 1: { if (lleftValue == lRightValue) return true; } break; case 2: { if (lleftValue < lRightValue) return true; } break; default: break; } return false; } // Early out: skip if this phase does not require key-value comparison public uint CheckGlobalKeyValue(TaskInterface pTask, bool bFinCheck) { if ((bFinCheck && !m_FixedData.m_bFinNeedComp) || (!bFinCheck && !m_FixedData.m_bPremNeedComp)) { return 0; } // Initialize comparison flags bool bFlag1 = false; bool bFlag2 = false; if (bFinCheck) { // Finish-conditions branch: evaluate two key-value comparisons bFlag1 = _compare_key_value(pTask, m_FixedData.m_Fin1KeyValue); bFlag2 = _compare_key_value(pTask, m_FixedData.m_Fin2KeyValue); // Evaluate logical mode: 0 = OR, 1 = AND if ((m_FixedData.m_nFinExp1AndOrExp2 == 0 && (bFlag1 || bFlag2)) || (m_FixedData.m_nFinExp1AndOrExp2 == 1 && (bFlag1 && bFlag2))) { return 0; } } else { // Premise-conditions branch: evaluate two key-value comparisons bFlag1 = _compare_key_value(pTask, m_FixedData.m_Prem1KeyValue); bFlag2 = _compare_key_value(pTask, m_FixedData.m_Prem2KeyValue); // Evaluate logical mode: 0 = OR, 1 = AND if ((m_FixedData.m_nPremExp1AndOrExp2 == 0 && (bFlag1 || bFlag2)) || (m_FixedData.m_nPremExp1AndOrExp2 == 1 && (bFlag1 && bFlag2))) { return 0; } } // Failure: global key-value prerequisite not satisfied return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_GLOBAL_KEYVAL; } public bool CheckReachLevel(BrewMonster.Scripts.Task.TaskInterface pTask) { bool bLevel = true, bReincarnationCount = true, bRealmLevel = true; if (m_FixedData.m_ulReachLevel != 0) bLevel = pTask.GetPlayerLevel() >= m_FixedData.m_ulReachLevel; if (m_FixedData.m_ulReachReincarnationCount != 0) bReincarnationCount = GetReincarnationCount(pTask) >= m_FixedData.m_ulReachReincarnationCount; if (m_FixedData.m_ulReachRealmLevel != 0) bRealmLevel = GetRealmLevel(pTask) >= m_FixedData.m_ulReachRealmLevel; return bLevel && bReincarnationCount && bRealmLevel; } private static uint GetReincarnationCount(BrewMonster.Scripts.Task.TaskInterface pTask) { return 0u; } private static uint GetRealmLevel(BrewMonster.Scripts.Task.TaskInterface pTask) { var host = BrewMonster.Network.EC_Game.GetGameRun()?.GetHostPlayer(); if (host != null) { var bp = host.GetBasicProps(); return (uint)bp.iLevel2; } return 0u; } public bool IsKeyTask() { ATaskTempl m = GetTopTask(); return m.m_FixedData.m_bKeyTask; } // ===== Missing methods converted from C++ (TaskTempl.inl) ===== // 保留原中文注释,并在旁加入英文翻译 // inline unsigned long _get_item_count(TaskInterface* pTask, unsigned long ulItemId, bool bCommon) // 获取道具数量(通用/任务) // English: Get item count (common/task) // public static uint _get_item_count(TaskInterface pTask, uint ulItemId, bool bCommon) // { // return bCommon ? pTask.GetCommonItemCount(ulItemId) : pTask.GetTaskItemCount(ulItemId); // } // inline unsigned long ATaskTempl::CheckBudget(ActiveTaskList* pList) const // 检查任务栏容量与空间 // English: Check task list budget and space public uint CheckBudget(ActiveTaskList pList) { // TODO: Convert full logic with TASK_HIDDEN_COUNT/TASK_TITLE_TASK_COUNT/TASK_ACTIVE_LIST_MAX_LEN and list counters when constants and fields are available // 占位返回通过 // English: Placeholder pass return 0u; } // inline unsigned long ATaskTempl::CheckGivenItems(TaskInterface* pTask) const // 检查交付所需道具容量合法性 // English: Check deliverable item capacity public uint CheckGivenItems(TaskInterface pTask) { // TODO: Use m_FixedData.m_ulGivenItems, m_ulGivenCmnCount, m_ulGivenTskCount and pTask.CanDeliver* API when fields confirmed return 0u; } // inline unsigned long ATaskTempl::CheckTimetable(unsigned long ulCurTime) const // 检查任务可接时间表 // English: Check task timetable window public uint CheckTimetable(uint ulCurTime) { // TODO: Implement judge_time_date against m_FixedData.m_tmStart/m_tmEnd/m_tmType return 0u; } // inline unsigned long ATaskTempl::CheckDeliverTime(TaskInterface* pTask, unsigned long ulCurTime) const // 检查任务发放频率限制(日/周/月/年) // English: Check deliver frequency limits (day/week/month/year) public uint CheckDeliverTime(TaskInterface pTask, uint ulCurTime) { // TODO: Implement with FinishedTimeList/FinishedCntList and timezone bias when types are available return 0u; } // inline unsigned long ATaskTempl::CheckFnshLst(TaskInterface* pTask, unsigned long ulCurTime) const // 检查完成与失败记录是否允许重复领取 // English: Check finished/failed list for redo permissions public uint CheckFnshLst(TaskInterface pTask, uint ulCurTime) { // TODO: Implement using FinishedTaskList and m_FixedData.m_bCanRedo/m_bCanRedoAfterFailure return 0u; } // inline unsigned long ATaskTempl::CheckDeliverCount(TaskInterface* pTask) const // 检查周期内角色/账号次数限制 // English: Check period deliver counts for role/account public uint CheckDeliverCount(TaskInterface pTask) { // TODO: Implement with FinishedCountList/FinishedTaskList based on account/role limits return 0u; } // inline unsigned long ATaskTempl::CheckAccountRMB(TaskInterface* pTask) const // 检查账号现金(RMB)范围 // English: Check account total cash (RMB) range public uint CheckAccountRMB(TaskInterface pTask) { if (m_FixedData.m_ulPremRMBMin != 0u && m_FixedData.m_ulPremRMBMax != 0u) { uint total = pTask.GetAccountTotalCash(); if (total < m_FixedData.m_ulPremRMBMin || total > m_FixedData.m_ulPremRMBMax) { return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_RMB_NOT_ENOUGH; } } return 0u; } // inline unsigned long ATaskTempl::CheckCharTime(TaskInterface* pTask) const // 检查角色创建/登录时间窗口 // English: Check character time window public uint CheckCharTime(TaskInterface pTask) { // TODO: Implement using m_FixedData.m_bCharTime, m_iCharStartTime/m_iCharEndTime, m_tmCharEndTime and pTask time APIs return 0u; } // inline unsigned long ATaskTempl::CheckLevel(TaskInterface* pTask) const // 等级上下限 // English: Level min/max public uint CheckLevel(TaskInterface pTask) { uint level = m_FixedData.m_bPremCheckMaxHistoryLevel > 0 ? pTask.GetMaxHistoryLevel() : pTask.GetPlayerLevel(); if (m_FixedData.m_ulPremise_Lev_Min != 0u && level < m_FixedData.m_ulPremise_Lev_Min) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_LEVEL; if (m_FixedData.m_ulPremise_Lev_Max != 0u && level > m_FixedData.m_ulPremise_Lev_Max) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ABOVE_LEVEL; return 0u; } // inline unsigned long ATaskTempl::CheckReincarnation(TaskInterface* pTask) const // 转生次数上下限 // English: Reincarnation count min/max public uint CheckReincarnation(TaskInterface pTask) { if (m_FixedData.m_bPremCheckReincarnation) { uint count = pTask.GetReincarnationCount(); if (count < m_FixedData.m_ulPremReincarnationMin) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_REINCARNATION; if (count > m_FixedData.m_ulPremReincarnationMax) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ABOVE_REINCARNATION; } return 0u; } // inline unsigned long ATaskTempl::CheckRealmLevel(TaskInterface* pTask) const // 修真境界等级 // English: Realm level public uint CheckRealmLevel(TaskInterface pTask) { if (m_FixedData.m_bPremCheckRealmLevel) { uint level = GetRealmLevel(pTask); if (level < m_FixedData.m_ulPremRealmLevelMin) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_REALMLEVEL; if (level > m_FixedData.m_ulPremRealmLevelMax) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ABOVE_REALMLEVEL; } return 0u; } // inline unsigned long ATaskTempl::CheckRealmExpFull(TaskInterface* pTask) const // 修真经验是否已满 // English: Realm EXP full check public uint CheckRealmExpFull(TaskInterface pTask) { if (m_FixedData.m_bPremCheckRealmExpFull) { if (!pTask.IsRealmExpFull()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_REALM_EXP_FULL; } return 0u; } // inline unsigned long ATaskTempl::CheckRepu(TaskInterface* pTask) const // 声望上下限 // English: Reputation min/max public uint CheckRepu(TaskInterface pTask) { if (m_FixedData.m_lPremise_Reputation != 0 && pTask.GetReputation() < (uint)m_FixedData.m_lPremise_Reputation) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_REPU; if (m_FixedData.m_lPremise_RepuMax != 0 && pTask.GetReputation() > (uint)m_FixedData.m_lPremise_RepuMax) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_REPU; return 0u; } // inline unsigned long ATaskTempl::CheckDeposit(TaskInterface* pTask) const // 寄存金(金币) // English: Deposit (gold) public uint CheckDeposit(TaskInterface pTask) { if (m_FixedData.m_ulPremise_Deposit != 0u && pTask.GetGoldNum() < m_FixedData.m_ulPremise_Deposit) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NO_DEPOSIT; return 0u; } // inline unsigned long ATaskTempl::CheckItems(TaskInterface* pTask) const // 前置道具检查(任一/全部) // English: Prerequisite item check (any/ALL) public uint CheckItems(TaskInterface pTask) { // TODO: Implement using m_FixedData.m_ulPremItems, m_bPremItemsAnyOne, m_PremItems[] return 0u; } // inline unsigned long ATaskTempl::CheckFaction(TaskInterface* pTask) const // 家族/帮派及职位 // English: Faction/clan and role public uint CheckFaction(TaskInterface pTask) { int role = pTask.GetFactionRole(); bool roleOk = role <= m_FixedData.m_iPremise_FactionRole; if (m_FixedData.m_ulPremise_Faction != 0u && !(pTask.IsInFaction(m_FixedData.m_ulPremise_Faction) && roleOk)) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CLAN; return 0u; } // inline unsigned long ATaskTempl::CheckGender(TaskInterface* pTask) const // 性别 // English: Gender public uint CheckGender(TaskInterface pTask) { bool isMale = pTask.IsMale(); if (m_FixedData.m_ulGender == TaskTemplConstants.TASK_GENDER_MALE && !isMale) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WRONG_GENDER; if (m_FixedData.m_ulGender == TaskTemplConstants.TASK_GENDER_FEMALE && isMale) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WRONG_GENDER; return 0u; } // inline unsigned long ATaskTempl::CheckOccupation(TaskInterface* pTask) const // 职业 // English: Occupation public uint CheckOccupation(TaskInterface pTask) { if (m_FixedData.m_ulOccupations == 0u) return 0u; uint current = pTask.GetPlayerOccupation(); for (uint i = 0; i < m_FixedData.m_ulOccupations; i++) { if (m_FixedData.m_Occupations[i] == current) return 0u; } return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NOT_IN_OCCU; } // inline unsigned long ATaskTempl::CheckPeriod(TaskInterface* pTask) const // 历练阶段(区间) // English: Period check (interval) public uint CheckPeriod(TaskInterface pTask) { uint cur = pTask.GetCurPeriod(); if (cur < m_FixedData.m_ulPremise_Period) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WRONG_PERIOD; if (m_FixedData.m_ulPremise_Period < 20u) return 0u; if (m_FixedData.m_ulPremise_Period < 30u) return cur < 30u ? 0u : (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WRONG_PERIOD; if (m_FixedData.m_ulPremise_Period < 40u) return cur < 40u ? 0u : (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WRONG_PERIOD; return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WRONG_PERIOD; } // inline unsigned long ATaskTempl::CheckGM(TaskInterface* pTask) const // GM 限制 // English: GM check public uint CheckGM(TaskInterface pTask) { return m_FixedData.m_bGM ? (pTask.IsGM() ? 0u : (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_GM) : 0u; } // inline unsigned long ATaskTempl::CheckShieldUser(TaskInterface* pTask) const // 屏蔽用户 // English: Shielded user public uint CheckShieldUser(TaskInterface pTask) { return m_FixedData.m_bShieldUser ? (pTask.IsShieldUser() ? 0u : (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_SHIELD_USER) : 0u; } // inline unsigned long ATaskTempl::CheckPreTask(TaskInterface* pTask) const // 前置任务 // English: Previous tasks public uint CheckPreTask(TaskInterface pTask) { // TODO: Implement using FinishedTaskList and m_FixedData.m_ulPremise_Tasks[*] return 0u; } // (No inline in provided snippet) 互斥任务 // English: Mutex task public uint CheckMutexTask(TaskInterface pTask, uint ulCurTime) { // TODO: Implement when mutex task data is available return 0u; } // inline unsigned long ATaskTempl::CheckInZone(TaskInterface* pTask) const // 区域检查 // English: In-zone check public uint CheckInZone(TaskInterface pTask) { // TODO: Implement worldId + region bounding box check using m_FixedData.m_ulDelvWorld and m_pDelvRegion return 0u; } // inline unsigned long ATaskTempl::CheckTeamTask(TaskInterface* pTask) const // 组队接任务要求 // English: Team-task requirements public uint CheckTeamTask(TaskInterface pTask) { // TODO: Implement full team captain and member checks per HasAllTeamMemsWanted return 0u; } // inline unsigned long ATaskTempl::CheckSpouse(TaskInterface* pTask) const // 配偶要求 // English: Spouse requirement public uint CheckSpouse(TaskInterface pTask) { if (m_FixedData.m_bPremise_Spouse && !pTask.IsMarried()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_INDETERMINATE; return 0u; } // inline unsigned long ATaskTempl::CheckWeddingOwner(TaskInterface* pTask) const // 婚礼举办者检查 // English: Wedding owner check public uint CheckWeddingOwner(TaskInterface pTask) { if (m_FixedData.m_bPremiseWeddingOwner) { if (pTask.IsAtCrossServer()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_MARRIAGE; if (!pTask.IsWeddingOwner()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WEDDING_OWNER; } return 0u; } // inline unsigned long ATaskTempl::CheckMarriage(TaskInterface* pTask) const // 结婚任务条件 // English: Marriage task requirements public uint CheckMarriage(TaskInterface pTask) { // TODO: Implement two-person team with opposite gender per original logic if APIs exist return 0u; } // inline unsigned long ATaskTempl::CheckLivingSkill(TaskInterface* pTask) const // 生活技能等级 // English: Living skill level public uint CheckLivingSkill(TaskInterface pTask) { // TODO: Loop m_FixedData.m_lSkillLev[MAX_LIVING_SKILLS] with skill ids and pTask.HasLivingSkill/GetLivingSkillLevel return 0u; } // inline unsigned long ATaskTempl::CheckIvtrEmptySlot(TaskInterface* pTask) const // 背包空位检查 // English: Inventory empty slot check public uint CheckIvtrEmptySlot(TaskInterface pTask) { if (!m_FixedData.m_bCompareItemAndInventory) return 0u; if (pTask.GetInvEmptySlot() < m_FixedData.m_ulInventorySlotNum) { return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NOT_IVTRSLOTNUM; } return 0u; } // inline unsigned long ATaskTempl::CheckFactionContrib(TaskInterface* pTask) const // 家族贡献 // English: Faction contribution public uint CheckFactionContrib(TaskInterface pTask) { int contrib = pTask.GetFactionContrib(); if (m_FixedData.m_iPremiseFactionContrib != 0 && contrib < m_FixedData.m_iPremiseFactionContrib) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_BELOW_FACTION_CONTRIB; return 0u; } // inline unsigned long ATaskTempl::CheckRecordTasksNum(TaskInterface* pTask) const // 完成记录任务数量 // English: Finished-record tasks count public uint CheckRecordTasksNum(TaskInterface pTask) { // TODO: Implement using FinishedTaskList scanning for recorded tasks count return 0u; } // inline unsigned long ATaskTempl::CheckTransform(TaskInterface* pTask) const // 变身形态 // English: Transform mask public uint CheckTransform(TaskInterface pTask) { byte playerShapeType = pTask.GetShapeMask(); // 0xFF 不限制 // English: 0xFF = no restriction if (m_FixedData.m_ucPremiseTransformedForm == 0xFF) return 0u; // 职业变身 // English: Occupation transform if (m_FixedData.m_ucPremiseTransformedForm == 0x80) { if ((playerShapeType >> 6) != 2) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_TRANSFORM_MASK; return 0u; } // 指定形态 // English: Specific form if (m_FixedData.m_ucPremiseTransformedForm != playerShapeType) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_TRANSFORM_MASK; return 0u; } // inline unsigned long ATaskTempl::CheckForce(TaskInterface* pTask) const // 势力检查 // English: Force check public uint CheckForce(TaskInterface pTask) { if (m_FixedData.m_bPremCheckForce) { if (pTask.IsAtCrossServer()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE; if (m_FixedData.m_iPremForce == -1) { if (pTask.GetForce() == 0) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_FORCE; } else if (pTask.GetForce() != m_FixedData.m_iPremForce) { return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_FORCE; } } return 0u; } // inline unsigned long ATaskTempl::CheckForceReputation(TaskInterface* pTask) const // 势力声望 // English: Force reputation public uint CheckForceReputation(TaskInterface pTask) { if (m_FixedData.m_iPremForceReputation != 0) { if (pTask.IsAtCrossServer()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE; if (pTask.GetForceReputation() < m_FixedData.m_iPremForceReputation) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_FORCE_REPUTATION; } return 0u; } // inline unsigned long ATaskTempl::CheckForceContribution(TaskInterface* pTask) const // 势力贡献 // English: Force contribution public uint CheckForceContribution(TaskInterface pTask) { if (m_FixedData.m_iPremForceContribution != 0) { if (pTask.IsAtCrossServer()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE; if (pTask.GetForceContribution() < m_FixedData.m_iPremForceContribution) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_FORCE_REPUTATION; } return 0u; } // inline unsigned long ATaskTempl::CheckExp(TaskInterface* pTask) const // 势力经验 // English: Force EXP public uint CheckExp(TaskInterface pTask) { if (m_FixedData.m_iPremForceExp != 0) { if (pTask.IsAtCrossServer()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE; if (pTask.GetExp() < m_FixedData.m_iPremForceExp) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_EXP; } return 0u; } // inline unsigned long ATaskTempl::CheckSP(TaskInterface* pTask) const // 势力SP // English: Force SP public uint CheckSP(TaskInterface pTask) { if (m_FixedData.m_iPremForceSP != 0) { if (pTask.IsAtCrossServer()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE; if (pTask.GetSP() < m_FixedData.m_iPremForceSP) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_SP; } return 0u; } // inline unsigned long ATaskTempl::CheckForceActivityLevel(TaskInterface* pTask) const // 势力活跃等级 // English: Force activity level public uint CheckForceActivityLevel(TaskInterface pTask) { if (m_FixedData.m_iPremForceActivityLevel != -1) { if (pTask.IsAtCrossServer()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_FORCE; if (m_FixedData.m_iPremForceActivityLevel != pTask.GetForceActivityLevel()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_FORCE_AL; } return 0u; } // inline unsigned long ATaskTempl::CheckKing(TaskInterface* pTask) const // 王检查 // English: King check public uint CheckKing(TaskInterface pTask) { if (m_FixedData.m_bPremIsKing && !pTask.IsKing()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_KING; return 0u; } // inline unsigned long ATaskTempl::CheckNotInTeam(TaskInterface* pTask) const // 不在队伍 // English: Not in team public uint CheckNotInTeam(TaskInterface pTask) { if (m_FixedData.m_bPremNotInTeam && pTask.IsInTeam()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_IN_TEAM; return 0u; } // inline unsigned long ATaskTempl::CheckTitle(TaskInterface* pTask) const // 称号检查 // English: Title check public uint CheckTitle(TaskInterface pTask) { // TODO: Implement using m_FixedData.m_iPremTitleNumTotal/m_iPremTitleNumRequired and award title arrays return 0u; } // inline unsigned long ATaskTempl::CheckHistoryStage(TaskInterface* pTask) const // 历史阶段 // English: History stage public uint CheckHistoryStage(TaskInterface pTask) { // TODO: Implement using pTask.GetCurHistoryStageIndex() and m_FixedData.m_iPremHistoryStageIndex[2] return 0u; } // inline unsigned long ATaskTempl::CheckCardCollection(TaskInterface* pTask) const // 将星卡收集数量 // English: General card collection count public uint CheckCardCollection(TaskInterface pTask) { // TODO: Implement using pTask.GetObtainedGeneralCardCount() and m_FixedData.m_ulPremGeneralCardCount return 0u; } // inline unsigned long ATaskTempl::CheckCardRankCount(TaskInterface* pTask) const // 指定品级将星卡数量 // English: Specific rank general card count public uint CheckCardRankCount(TaskInterface pTask) { // TODO: Implement using pTask.GetObtainedGeneralCardCountByRank(rank) and m_FixedData fields return 0u; } // inline unsigned long ATaskTempl::CheckInTransformShape(TaskInterface* pTask) const // 变身中禁止导航 // English: No navigate while in shaped public uint CheckInTransformShape(TaskInterface pTask) { if (m_FixedData.m_enumMethod == (uint)TaskCompletionMethod.enumTMSimpleClientTaskForceNavi && pTask.GetShapeMask() != 0) { return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NO_NAVIGATE_INSHPAED; } return 0u; } // 特殊活动奖励检查 // English: Special award activity check public uint CheckSpecialAward(TaskInterface pTask) { // 非“特殊活动奖励”类型则直接通过 // English: Pass if not a special-award dynamic task if (m_FixedData.m_DynTaskType != (byte)DynTaskType.enumDTTSpecialAward) return 0u; // 未配置特殊奖励标识则失败 // English: Fail if special award id not configured if (m_FixedData.m_ulSpecialAward == 0u) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_SPECIAL_AWARD; // TODO: 获取玩家特殊奖励信息并校验 // English: Fetch player's special-award info and validate against required id // 受限于当前 TaskInterface 未暴露获取接口,暂时视为通过 // English: Interface lacks API; treat as pass for now return 0u; } public void ClearValidCount() { m_uValidCount = 0; } public ATaskTemplMan GetTaskTemplMan() { return EC_Game.GetTaskTemplateMan(); } public ATaskTempl GetConstSubById(uint ulId) { ATaskTempl pChild = m_pFirstChild; while (pChild != null) { if (pChild.m_FixedData.m_ID == ulId) return pChild; pChild = pChild.m_pNextSibling; } return null; } public ActiveTaskEntry DeliverTask( TaskInterface pTask, ActiveTaskList pList, ActiveTaskEntry pEntry, uint ulCaptainTask, uint ulMask, uint ulCurTime, ATaskTempl pSubTempl, ref task_sub_tags pSubTag, TaskGlobalData pGlobal, byte uParentIndex) { // TODO: implement full logic when ActiveTaskList/ActiveTaskEntry and TaskInterface APIs are available return null; /*ActiveTaskEntry* aEntries = pList->m_TaskEntries; if (!pEntry) pEntry = aEntries + pList->m_uTaskCount; else if (pEntry->m_ID != 0) // entry��ռ�ã���Ҫ���Ų��һ����λ; pList->RealignTask(pEntry, 1); unsigned char uIndex = static_cast(pEntry - aEntries); pEntry->m_ID = static_cast(m_ID); pEntry->m_ulTemplAddr = reinterpret_cast(this); pEntry->m_ParentIndex = uParentIndex; pEntry->m_PrevSblIndex = 0xff; pEntry->m_NextSblIndex = 0xff; pEntry->m_ChildIndex = 0xff; pEntry->m_uState = 0; pEntry->m_ulTaskTime = ulCurTime; #ifndef _TASK_CLIENT // ��ΪPQ������Ҫ��ʱ�����¼��m_ulTaskTime�� if (m_bPQTask) { pEntry->m_ulTaskTime = PublicQuestInterface::GetCurTaskStamp(m_ID); } #endif if (ulCaptainTask) { pEntry->m_ulCapTemplAddr = reinterpret_cast(GetTaskTemplMan()->GetTopTaskByID(ulCaptainTask)); if (pEntry->m_ulCapTemplAddr) pEntry->m_uCapTaskId = static_cast(ulCaptainTask); else { pEntry->m_uCapTaskId = 0; char log[1024]; sprintf(log, "DeliverTask, Cant Find CapTask = %d", ulCaptainTask); TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 0, log); } } else { pEntry->m_uCapTaskId = 0; pEntry->m_ulCapTemplAddr = 0; } pEntry->SetSuccess(); // Later will check whether truly succeed memset(pEntry->m_BufData, 0, sizeof(pEntry->m_BufData)); #ifndef _TASK_CLIENT // ��ΪPQ�����PQ��������Ҫ��ʱ�����¼��m_ulTaskTime�� if (m_bPQTask) { ulCurTime = PublicQuestInterface::GetCurTaskStamp(m_ID); } else if (m_enumMethod == enumTMReachTreasureZone) { // ����ر�λ�úͲر�ͼ���½�λ�õ�index unsigned short uZonesSum = m_ucZonesNumX * m_ucZonesNumZ; unsigned short uTreasureLocIndex = pTask->RandNormal(1,uZonesSum); char sTreasureLocMinX = (uTreasureLocIndex % m_ucZonesNumX - 1); char sTreasureLocMinZ = (uTreasureLocIndex / m_ucZonesNumX); // ������������IJر�ͼλ�ã�ʹ�ر�λ�ò��ܴ��ڲر�ͼ�ı�Ե int sMapMinX = pTask->RandNormal(sTreasureLocMinX,sTreasureLocMinX + TASK_TREASURE_MAP_SIDE_MULTIPLE - 3) - TASK_TREASURE_MAP_SIDE_MULTIPLE + 2; int sMapMinZ = pTask->RandNormal(sTreasureLocMinZ,sTreasureLocMinZ + TASK_TREASURE_MAP_SIDE_MULTIPLE - 3) - TASK_TREASURE_MAP_SIDE_MULTIPLE + 2; // �洢���ѽ������б��� pEntry->m_iUsefulData1 = uTreasureLocIndex; pEntry->m_iUsefulData1 |= (sMapMinX << 16) & 0x00FF0000; pEntry->m_iUsefulData1 |= (sMapMinZ << 24) & 0xFF000000; } ulMask |= m_ulMask; #else if (m_enumMethod == enumTMReachTreasureZone) { task_notify_base notify; notify.reason = TASK_CLT_NOTIFY_REQUEST_TREASURE_INDEX; notify.task = static_cast(m_ID); pTask->NotifyServer(¬ify, sizeof(notify)); } #endif pList->m_uTaskCount++; if (!m_pParent) { if (m_bHidden) pList->m_uTopHideTaskCount++; else if (m_bDisplayInTitleTaskUI) pList->m_uTitleTaskCount++; else pList->m_uTopShowTaskCount++; pList->m_uUsedCount += m_uDepth; #ifndef _TASK_CLIENT if (pGlobal) { pGlobal->AddRevNum(); pGlobal->m_ulRcvUpdateTime = ulCurTime; TaskUpdateGlobalData(m_ID, pGlobal->buf); } #endif } if (uParentIndex != 0xff) { ActiveTaskEntry& ParentEntry = aEntries[uParentIndex]; if (ParentEntry.m_ChildIndex == 0xff) ParentEntry.m_ChildIndex = uIndex; else { unsigned char uChildEntry = ParentEntry.m_ChildIndex; while (aEntries[uChildEntry].m_NextSblIndex != 0xff) uChildEntry = aEntries[uChildEntry].m_NextSblIndex; aEntries[uChildEntry].m_NextSblIndex = uIndex; pEntry->m_PrevSblIndex = uChildEntry; } } #ifndef _TASK_CLIENT if (!m_pParent) DeliverGivenItems(pTask); #endif pEntry++; if (pSubTempl) { return pSubTempl->DeliverTask( pTask, pList, pEntry, 0, ulMask, ulCurTime, NULL, pSubTag, NULL, uIndex); } else if (m_bRandOne) { #ifdef _TASK_CLIENT if (pSubTag->cur_index < pSubTag->sz) { pSubTempl = GetSubByIndex(pSubTag->tags[pSubTag->cur_index]); pSubTag->cur_index++; if (pSubTempl) { return pSubTempl->DeliverTask( pTask, pList, pEntry, 0, ulMask, ulCurTime, NULL, pSubTag, NULL, uIndex); } } #else int nSel; pSubTempl = RandOneChild(pTask, nSel); if (pSubTempl) { if (pSubTag->sz < MAX_SUB_TAGS) pSubTag->tags[pSubTag->sz++] = static_cast(nSel); return pSubTempl->DeliverTask( pTask, pList, pEntry, 0, ulMask, ulCurTime, NULL, pSubTag, NULL, uIndex); } #endif } else { const ATaskTempl* pChild = m_pFirstChild; while (pChild) { pEntry = pChild->DeliverTask( pTask, pList, pEntry, 0, ulMask, ulCurTime, NULL, pSubTag, NULL, uIndex); if (m_bExeChildInOrder) return pEntry; pChild = pChild->m_pNextSibling; } } return pEntry;*/ } void RecursiveAward( TaskInterface pTask, ActiveTaskList pList, ActiveTaskEntry pEntry, uint ulCurtime, int nChoice, ref task_sub_tags pSubTag) { // TODO : implement full logic when ActiveTaskList/ActiveTaskEntry and TaskInterface APIs are available /*{ char log[1024]; sprintf(log, "RecursiveAward: state = 0x%x", pEntry->m_uState); TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 1, log); } ActiveTaskEntry* aEntries = pList->m_TaskEntries; // ����ʧ�ܲ���ȡ��Ʒ bool bFailedTaskDoNotTakeItem = !pEntry->IsSuccess() && m_bNotClearItemWhenFailed && m_bClearAcquired; // ��������� pList->ClearChildrenOf(pTask, pEntry, !bFailedTaskDoNotTakeItem); if (!pEntry->m_ulTemplAddr) return; // must check it if (!m_pParent && m_bNeedRecord) { static_cast(pTask->GetFinishedTaskList())->AddOneTask( m_ID, pEntry->IsSuccess()); } // �˺��޴�����������ɴ��� if (!m_pParent && m_bAccountTaskLimit) { // ��������ʱ���ж��Ƿ��������ɴ��� CheckDeliverTime(pTask, ulCurtime); // û�й�ѡ��ʧ�ܵ�ʱ�򲻼�¼��ɴ����������߹�ѡ��ʧ�ܵ�ʱ�򲻼�¼��ɴ�������������ɹ���ʱ�� if (!m_bNotIncCntWhenFailed || (m_bNotIncCntWhenFailed && pEntry->IsSuccess())) static_cast(pTask->GetFinishedCntList())->AddOrUpdate(m_ID,ulCurtime); } // ��ɫ�޴�����������ɴ��� else if (!m_pParent && m_bRoleTaskLimit) { // ��������ʱ���ж��Ƿ��������ɴ��� CheckDeliverTime(pTask, ulCurtime); // û�й�ѡ��ʧ�ܵ�ʱ�򲻼�¼��ɴ����������߹�ѡ��ʧ�ܵ�ʱ�򲻼�¼��ɴ�������������ɹ���ʱ�� if (!m_bNotIncCntWhenFailed || (m_bNotIncCntWhenFailed && pEntry->IsSuccess())) { // FinishedTaskList�ﱣ��������ɴ��� static_cast(pTask->GetFinishedTaskList())->AddForFinishCount(m_ID,pEntry->IsSuccess()); // TaskFinishTimeList�ﱣ���������ʱ�� static_cast(pTask->GetFinishedTimeList())->AddOrUpdate(m_ID, ulCurtime); } } #ifndef _TASK_CLIENT // ������Ʒ AWARD_DATA ad; CalcAwardData( pTask, &ad, pEntry, pEntry->m_ulTaskTime, ulCurtime); unsigned long ulRet = DeliverByAwardData(pTask, pList, pEntry, &ad, ulCurtime, nChoice); if (ulRet) { char log[1024]; sprintf(log, "RecursiveAward, ret = %d", ulRet); TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 0, log); } // ȥ����õĻ�Ԥ�ȸ�����Ʒ���ڷ�����Ʒ��ִ�� if (m_bClearAcquired) { if (!bFailedTaskDoNotTakeItem) RemoveAcquiredItem(pTask, false, pEntry->IsSuccess()); } else if (!pEntry->IsSuccess()) TakeAwayGivenItems(pTask); #endif pEntry->m_ulTemplAddr = 0; pEntry->m_ID = 0; if (pList->m_uTaskCount) pList->m_uTaskCount--; else TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 0, "Award, TaskCount == 0"); if (pEntry->m_ParentIndex != 0xff) { ActiveTaskEntry& ParentEntry = aEntries[pEntry->m_ParentIndex]; if (pEntry->m_PrevSblIndex != 0xff) aEntries[pEntry->m_PrevSblIndex].m_NextSblIndex = pEntry->m_NextSblIndex; else ParentEntry.m_ChildIndex = pEntry->m_NextSblIndex; if (pEntry->m_NextSblIndex != 0xff) aEntries[pEntry->m_NextSblIndex].m_PrevSblIndex = pEntry->m_PrevSblIndex; if (!pEntry->IsSuccess() && m_bParentAlsoFail) { pList->RealignTask(pEntry, 0); ParentEntry.ClearSuccess(); ParentEntry.SetFinished(); m_pParent->RecursiveAward(pTask, pList, &ParentEntry, ulCurtime, -1, pSubTag); } else if (pEntry->IsSuccess() && m_bParentAlsoSucc) { pList->RealignTask(pEntry, 0); ParentEntry.SetFinished(); pList->ClearChildrenOf(pTask, &ParentEntry); if (m_pParent->m_enumFinishType == enumTFTDirect) m_pParent->RecursiveAward(pTask, pList, &ParentEntry, ulCurtime, -1, pSubTag); #ifdef _TASK_CLIENT else if (!m_pParent->m_bHidden && !m_pParent->m_bDisplayInTitleTaskUI) TaskInterface::TraceTask(m_pParent->m_ID); #endif } else if (m_pParent->m_bExeChildInOrder && m_pNextSibling) { if (ParentEntry.m_ChildIndex != 0xff || pList->GetEntry(m_pNextSibling->m_ID)) // ����������������Ϊ0xff pList->RealignTask(pEntry, 0); else { m_pNextSibling->DeliverTask( pTask, pList, pEntry, 0, *pTask->GetTaskMask(), ulCurtime, NULL, pSubTag, NULL, pEntry->m_ParentIndex); #ifdef _TASK_CLIENT // �����������������ѡ��һ�������һ���������������˳��ִ�� // ǰ���������׷�ٸ�����ʱ�Ѿ����� // ���ڵڶ������Ժ��˳��ִ�е������� if (!m_pParent->m_bHidden && !m_pParent->m_bDisplayInTitleTaskUI) TaskInterface::TraceTask(m_pNextSibling->m_ID); #endif } } else if (ParentEntry.m_ChildIndex == 0xff) // ������������������ʱ����Ϊ��� { pList->RealignTask(pEntry, 0); ParentEntry.SetFinished(); if (m_pParent->m_enumFinishType == enumTFTDirect) m_pParent->RecursiveAward(pTask, pList, &ParentEntry, ulCurtime, -1, pSubTag); #ifdef _TASK_CLIENT else if (!m_pParent->m_bHidden && !m_pParent->m_bDisplayInTitleTaskUI) TaskInterface::TraceTask(m_pParent->m_ID); #endif } else pList->RealignTask(pEntry, 0); } else // Root Node { pList->RealignTask(pEntry, 0); if (pList->m_uUsedCount >= m_uDepth) pList->m_uUsedCount -= m_uDepth; else { char log[1024]; sprintf(log, "Award, Used = %d", pList->m_uUsedCount); TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 0, log); pList->m_uUsedCount = 0; } if (m_bHidden) { if (pList->m_uTopHideTaskCount) pList->m_uTopHideTaskCount--; } else if(m_bDisplayInTitleTaskUI) { if (pList->m_uTitleTaskCount) pList->m_uTitleTaskCount--; } else { if (pList->m_uTopShowTaskCount) pList->m_uTopShowTaskCount--; } }*/ } public void TakeAwayGivenItems(TaskInterface pTask) { uint ulCount; for (int i = 0; i < m_FixedData.m_ulGivenItems; i++) { ITEM_WANTED wi = m_FixedData.m_GivenItems[i]; if (wi.m_bCommonItem) { ulCount = (uint)pTask.GetCommonItemCount(wi.m_ulItemTemplId); if (ulCount > wi.m_ulItemNum) ulCount = wi.m_ulItemNum; if (ulCount > 0) pTask.TakeAwayCommonItem(wi.m_ulItemTemplId, ulCount); } else { ulCount = (uint)pTask.GetTaskItemCount(wi.m_ulItemTemplId); if (ulCount > 0) pTask.TakeAwayTaskItem(wi.m_ulItemTemplId, ulCount); } } } public void RemoveAcquiredItem(TaskInterface pTask, bool bClearTask, bool bSuccess) { var m_enumMethod = m_FixedData.m_enumMethod; var m_ulItemsWanted = m_FixedData.m_ulItemsWanted; var m_ItemsWanted = m_FixedData.m_ItemsWanted; var m_ulGoldWanted = m_FixedData.m_ulGoldWanted; var m_iFactionContribWanted = m_FixedData.m_iFactionContribWanted; var m_iFactionExpContribWanted = m_FixedData.m_iFactionExpContribWanted; var m_ulMonsterWanted = m_FixedData.m_ulMonsterWanted; var m_MonsterWanted = m_FixedData.m_MonsterWanted; var m_ulPlayerWanted = m_FixedData.m_ulPlayerWanted; var m_PlayerWanted = m_FixedData.m_PlayerWanted; if (m_enumMethod == (uint)TaskCompletionMethod.enumTMCollectNumArticle) { for (int i = 0; i < m_ulItemsWanted; i++) { ITEM_WANTED wi = m_ItemsWanted[i]; uint ulCount; if (wi.m_bCommonItem) { if (bClearTask) continue; ulCount = (uint)pTask.GetCommonItemCount(wi.m_ulItemTemplId); if (ulCount == 0) continue; if (wi.m_ulItemNum > 0 && ulCount > wi.m_ulItemNum) ulCount = wi.m_ulItemNum; pTask.TakeAwayCommonItem(wi.m_ulItemTemplId, ulCount); } else { ulCount = (uint)pTask.GetTaskItemCount(wi.m_ulItemTemplId); if (ulCount > 0) pTask.TakeAwayTaskItem(wi.m_ulItemTemplId, ulCount); } } // �ɹ����Ǯ���� if (m_ulGoldWanted > 0 && !bClearTask && bSuccess) { uint ulGold = pTask.GetGoldNum(); if (ulGold > m_ulGoldWanted) ulGold = m_ulGoldWanted; pTask.TakeAwayGold(ulGold); } //�ɹ���Ѱ��ɹ��׶����� if (m_iFactionContribWanted > 0 && !bClearTask && bSuccess) { int iContrib = pTask.GetFactionConsumeContrib(); if (iContrib > m_iFactionContribWanted) iContrib = m_iFactionContribWanted; pTask.TakeAwayFactionConsumeContrib(iContrib); } //�ɹ���Ѱ��ɾ������� if (m_iFactionExpContribWanted > 0 && !bClearTask && bSuccess) { int iContrib = pTask.GetFactionExpContrib(); if (iContrib > m_iFactionExpContribWanted) iContrib = m_iFactionExpContribWanted; pTask.TakeAwayFactionExpContrib(iContrib); } } else if (m_enumMethod == (uint)TaskCompletionMethod.enumTMKillNumMonster) { for (int i = 0; i < m_ulMonsterWanted; i++) { // const MONSTER_WANTED& mw = m_MonsterWanted[i]; MONSTER_WANTED mw = m_MonsterWanted[i]; if (mw.m_ulDropItemId == 0) continue; uint ulCount; if (mw.m_bDropCmnItem) { ulCount = (uint)pTask.GetCommonItemCount(mw.m_ulDropItemId); if (mw.m_ulDropItemCount > 0 && ulCount > mw.m_ulDropItemCount) ulCount = mw.m_ulDropItemCount; if (ulCount > 0) pTask.TakeAwayCommonItem(mw.m_ulDropItemId, ulCount); } else { ulCount = (uint)pTask.GetTaskItemCount(mw.m_ulDropItemId); if (ulCount > 0) pTask.TakeAwayTaskItem(mw.m_ulDropItemId, ulCount); } } } else if (m_enumMethod == (uint)TaskCompletionMethod.enumTMKillPlayer) { for (uint i = 0; i < m_ulPlayerWanted; ++i) { // const PLAYER_WANTED& pw = m_PlayerWanted[i]; var pw = m_PlayerWanted[i]; if (pw.m_ulDropItemId == 0) continue; uint ulCount; if (pw.m_bDropCmnItem) { ulCount = (uint)pTask.GetCommonItemCount(pw.m_ulDropItemId); if (pw.m_ulDropItemCount > 0 && ulCount > pw.m_ulDropItemCount) ulCount = pw.m_ulDropItemCount; if (ulCount > 0) pTask.TakeAwayCommonItem(pw.m_ulDropItemId, ulCount); } else { ulCount = (uint)pTask.GetTaskItemCount(pw.m_ulDropItemId); if (ulCount>0) pTask.TakeAwayTaskItem(pw.m_ulDropItemId, ulCount); } } } } public bool IsValidState() { return m_uValidCount < TaskTemplConstants.TASK_MAX_VALID_COUNT; } public static bool _compare_pq_key_value( COMPARE_KEY_VALUE CompKeyVal) { long lleftValue = CompKeyVal.lLeftNum; if (CompKeyVal.nLeftType == 0) { lleftValue = PublicQuestInterface.QuestGetGlobalValue(CompKeyVal.lLeftNum); // pTask->GetGlobalValue(CompKeyVal.lLeftNum); } long lRightValue = CompKeyVal.lRightNum; if (CompKeyVal.nRightType == 0) { lRightValue = PublicQuestInterface.QuestGetGlobalValue(CompKeyVal.lRightNum); // pTask->GetGlobalValue(CompKeyVal.lRightNum); } switch(CompKeyVal.nCompOper) { case 0: { if (lleftValue > lRightValue) return true; } break; case 1: { if (lleftValue == lRightValue) return true; } break; case 2: { if (lleftValue < lRightValue) return true; } break; default: break; } return false; } public uint CheckGlobalPQKeyValue(bool bFinCheck) { var m_bFinNeedComp = m_FixedData.m_bFinNeedComp; var m_bPremNeedComp = m_FixedData.m_bPremNeedComp; var m_Fin1KeyValue = m_FixedData.m_Fin1KeyValue; var m_Fin2KeyValue = m_FixedData.m_Fin2KeyValue; var m_nFinExp1AndOrExp2 = m_FixedData.m_nFinExp1AndOrExp2; var m_nPremExp1AndOrExp2 = m_FixedData.m_nPremExp1AndOrExp2; var m_Prem1KeyValue = m_FixedData.m_Prem1KeyValue; var m_Prem2KeyValue = m_FixedData.m_Prem2KeyValue; if (bFinCheck && !m_bFinNeedComp ||!bFinCheck && !m_bPremNeedComp) return 0; bool bFlag1 = false; bool bFlag2 = false; if (bFinCheck) { bFlag1 = _compare_pq_key_value(m_Fin1KeyValue); bFlag2 = _compare_pq_key_value(m_Fin2KeyValue); if (m_nFinExp1AndOrExp2 == 0 && (bFlag1 || bFlag2) //�� || m_nFinExp1AndOrExp2 == 1 && (bFlag1 && bFlag2)) //�� return 0; } else { bFlag1 = _compare_pq_key_value(m_Prem1KeyValue); bFlag2 = _compare_pq_key_value(m_Prem2KeyValue); if (m_nPremExp1AndOrExp2 == 0 && (bFlag1 || bFlag2) //�� || m_nPremExp1AndOrExp2 == 1 && (bFlag1 && bFlag2)) //�� return 0; } return TaskInterfaceConstants.TASK_PREREQU_FAIL_GLOBAL_KEYVAL; } public void OnSetFinished( TaskInterface pTask, ActiveTaskList pList, ActiveTaskEntry pEntry, bool bNotifyMem = true) { var m_enumFinishType = m_FixedData.m_enumMethod; pEntry.SetFinished(); // ֪ͨ�ͻ�������� NotifyClient( pTask, pEntry, TaskTemplConstants.TASK_SVR_NOTIFY_FINISHED, 0); if(pEntry.GetTempl().m_FixedData.m_bPQTask) PublicQuestInterface.QuestRemovePlayer((int)pEntry.GetTempl().m_FixedData.m_ID, pTask.GetPlayerId()); if (m_enumFinishType == (uint)TaskFinishType.enumTFTDirect || !pEntry.IsSuccess()) DeliverAward(pTask, pList, pEntry, -1, bNotifyMem); } public void GiveUpOneTask( TaskInterface pTask, ActiveTaskList pList, ActiveTaskEntry pEntry, bool bForce) { var m_bCanGiveUp = m_FixedData.m_bCanGiveUp; if (m_pParent != null || !m_bCanGiveUp) return; pEntry.ClearSuccess(); pEntry.SetGiveUp(); OnSetFinished(pTask, pList, pEntry); // TaskInterface::WriteLog(pTask.GetPlayerId(), m_ID, 1, "GiveUpTask"); // TaskInterface::WriteKeyLog(pTask.GetPlayerId(), m_ID, 1, "GiveUpTask"); } private void NotifyClient( TaskInterface pTask, ActiveTaskEntry pEntry, byte uReason, uint ulCurTime, uint ulParam=0, int dps=0, int dph=0) { var m_ID = m_FixedData.m_ID; var m_MonsterWanted = m_FixedData.m_MonsterWanted; string log = new string(new char[1024]); byte[] buf = new byte[512]; // task_notify_base* pNotify = reinterpret_cast(buf); var pNotify = new task_notify_base(); int sz = 0; pNotify.reason = uReason; pNotify.task = (ushort)(m_ID); bool bWriteLog = true; switch (uReason) { case TaskTemplConstants.TASK_SVR_NOTIFY_PLAYER_KILLED: var svr_player_killed = new svr_player_killed(pNotify); svr_player_killed.player_num = pEntry.m_wMonsterNum[ulParam]; svr_player_killed.index = (ushort)ulParam; sz = Marshal.SizeOf(svr_player_killed); break; case TaskTemplConstants.TASK_SVR_NOTIFY_MONSTER_KILLED: { var svrMonsterKilled = new svr_monster_killed(pNotify) { monster_id = m_MonsterWanted[ulParam].m_ulMonsterTemplId, monster_num = pEntry.m_wMonsterNum[ulParam], dps = (dps != 0 && dph != 0) ? dps : 0, dph = (dps != 0 && dph != 0) ? dph : 0 }; sz = Marshal.SizeOf(svrMonsterKilled); bWriteLog = false; } break; case TaskTemplConstants.TASK_SVR_NOTIFY_NEW: { // static_cast(pNotify)->set_data( // ulCurTime, // reinterpret_cast(pEntry), // *(reinterpret_cast(ulParam)) // ); var svrNewTask = new svr_new_task(pNotify); svrNewTask.set_data( ulCurTime, pEntry.m_ID, Marshal.PtrToStructure((IntPtr)ulParam) ); sz = svrNewTask.get_size(); break; } case TaskTemplConstants.TASK_SVR_NOTIFY_COMPLETE: // static_cast(pNotify)->set_data( // ulCurTime, // *(reinterpret_cast(ulParam)) // ); // sz = static_cast(pNotify)->get_size(); var svrTaskComplete = new svr_task_complete(pNotify); svrTaskComplete.set_data( ulCurTime, Marshal.PtrToStructure((IntPtr)ulParam) ); sz = svrTaskComplete.get_size(); break; case TaskTemplConstants.TASK_SVR_NOTIFY_GIVE_UP: case TaskTemplConstants.TASK_SVR_NOTIFY_FINISHED: case TaskTemplConstants.TASK_SVR_NOTIFY_DIS_GLOBAL_VAL: sz = Marshal.SizeOf(); break; case TaskTemplConstants.TASK_SVR_NOTIFY_ERROR_CODE: var svrTaskErrCode = new svr_task_err_code(pNotify); svrTaskErrCode.err_code = ulParam; sz = Marshal.SizeOf( svrTaskErrCode ); break; default: // sprintf(log, "NotifyClient, Unknown Reason = %d", uReason); // TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 0, log); return; } if (bWriteLog) { // sprintf(log, "svr: Reason = %d, Param = 0x%x", uReason, ulParam); // TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 1, log); } // assert(sz <= sizeof(buf)); pTask.NotifyClient(buf, sz); } public bool DeliverAward( TaskInterface pTask, ActiveTaskList pList, ActiveTaskEntry pEntry, int nChoice, bool bNotifyTeamMem = true, // = true Nullable pGlobal = null ) // = null { char[] log = new char[1024]; // sprintf(log, "DeliverAward: Choice = %d", nChoice); // TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 1, log); // TaskInterface::WriteKeyLog(pTask->GetPlayerId(), m_ID, 1, log); // ���ʱ�� uint ulCurTime = pTask.GetCurTime(); RecursiveCheckTimeLimit(pTask, pList, pEntry, ulCurTime); // TODO : implement full logic when ActiveTaskList/ActiveTaskEntry and TaskInterface APIs are available // if (!RecursiveCheckParent(pTask, pList, pEntry)) // pEntry->ClearSuccess(); // // // �������ʧ����� // if (!pEntry->IsAwardNotifyTeam() && bNotifyTeamMem && pEntry->GetCapOrSelf()->m_bTeamwork && !pEntry->IsSuccess()) // { // AwardNotifyTeamMem(pTask, pEntry); // pEntry->SetAwardNotifyTeam(); // Nofity only once // } // // if (!pTask->IsDeliverLegal()) // �������������׵�����״̬ // return false; // // if (pEntry->IsGiveUp() && m_bClearAsGiveUp) // { // pList->ClearTask(pTask, pEntry, true); // pList->UpdateTaskMask(*pTask->GetTaskMask()); // NotifyClient(pTask, NULL, TASK_SVR_NOTIFY_GIVE_UP, 0); // // // �Ѱ������� // if (m_bCompareItemAndInventory) // { // pTask->LockInventory(false); // } // // return true; // } // // pEntry->SetFinished(); // // #if _TASK_CLIENT // // unsigned long ulRet; // if ((ulRet = RecursiveCheckAward( // pTask, // pList, // pEntry, // ulCurTime, // nChoice // )) != 0) // { // if (m_enumFinishType == enumTFTNPC || !pEntry->IsErrReported()) // { // NotifyClient( // pTask, // NULL, // TASK_SVR_NOTIFY_ERROR_CODE, // 0, // ulRet // ); // // pEntry->SetErrReported(); // } // // char log[1024]; // sprintf(log, "DeliverAward: ret = %d", ulRet); // TaskInterface::WriteLog(pTask->GetPlayerId(), m_ID, 1, log); // return false; // } // // #endif // // // ������ӳɹ���� // if (!pEntry->IsAwardNotifyTeam() && bNotifyTeamMem && pEntry->IsSuccess()) // { // if(pEntry->GetCapOrSelf()->m_bTeamwork) // { // AwardNotifyTeamMem(pTask, pEntry); // pEntry->SetAwardNotifyTeam(); // Nofity only once // } // else // { // const ATaskTempl* pParent = pEntry->GetTempl()->GetTopTask(); // ActiveTaskEntry* pParentEntry = static_cast(pTask->GetActiveTaskList())->GetEntry(pParent->GetID()); // // if(pParentEntry->GetCapOrSelf()->m_bTeamwork && pEntry->m_ChildIndex == 0xff) // { // bool bIsLastChild = true; // const ATaskTempl* pTempParent = pEntry->GetTempl(); // while(pTempParent)// && pTempParent->m_pNextSibling == NULL) // { // if(pTempParent->m_pNextSibling != NULL) // { // bIsLastChild = false; // break; // } // // pTempParent = pTempParent->m_pParent; // } // // if(bIsLastChild) // { // AwardNotifyTeamMem(pTask, pParentEntry); // pParentEntry->SetAwardNotifyTeam(); // Nofity only once // } // } // } // } // // task_sub_tags sub_tags; // memset(&sub_tags, 0, sizeof(sub_tags)); // sub_tags.state = pEntry->m_uState; // // // ������� // RecursiveAward(pTask, pList, pEntry, ulCurTime, nChoice, &sub_tags); // // // ֪ͨ�ͻ��� // NotifyClient( // pTask, // NULL, // TASK_SVR_NOTIFY_COMPLETE, // ulCurTime, // reinterpret_cast(&sub_tags)); // // // ���Mask // pList->UpdateTaskMask(*pTask->GetTaskMask()); // // // �Ѱ������� // if (m_bCompareItemAndInventory) // { // pTask->LockInventory(false); // } return true; } private void RecursiveCheckTimeLimit( TaskInterface pTask, ActiveTaskList pList, ActiveTaskEntry pEntry, uint ulCurTime) { // TODO: implement full logic when ActiveTaskList/ActiveTaskEntry and TaskInterface APIs are available // if (m_ulTimeLimit > 0 && pEntry.m_ulTaskTime + m_ulTimeLimit < ulCurTime) // ��ʱ // pEntry.ClearSuccess(); // // // if (m_ulAbsFailTime && m_ulAbsFailTime < ulCurTime) // ��������ʧЧ���� // // ��������ʧЧ���� // if (m_bAbsFail) // { // tm cur = *localtime((long*)&ulCurTime); // // if(m_tmAbsFailTime.before(&cur)) // { // pEntry->ClearSuccess(); // } // } // // if (m_pParent && pEntry->m_ParentIndex != 0xff) // { // ActiveTaskEntry& ParentEntry = pList->m_TaskEntries[pEntry->m_ParentIndex]; // m_pParent->RecursiveCheckTimeLimit(pTask, pList, &ParentEntry, ulCurTime); // } } } }