2548 lines
86 KiB
C#
2548 lines
86 KiB
C#
using System;
|
||
using System.Runtime.InteropServices;
|
||
using BrewMonster.Network;
|
||
using BrewMonster.Scripts.Task;
|
||
using CSNetwork.GPDataType;
|
||
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 (pList.GetEntry(m_FixedData.m_ID) != null)
|
||
{
|
||
ulRet = (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_SAME_TASK;
|
||
goto ret_here;
|
||
}
|
||
/*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++)
|
||
{
|
||
ActiveTaskEntry 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
|
||
// Only log failures to reduce noise
|
||
if (ulRet != 0)
|
||
{
|
||
string log = $"CheckPrerequisite Task {m_FixedData.m_ID}: FAIL code {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 '%<digits>'
|
||
// 跳过 '%' 后面的所有数字
|
||
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,
|
||
task_notify_base pNotify,
|
||
uint sz,
|
||
byte[] pBuf) // In C++ pNotify is a pointer to raw data; here we pass the full byte array for parsing
|
||
{
|
||
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 = new svr_monster_killed();
|
||
svr_player_killed pKilledPlayer = new svr_player_killed();
|
||
StorageTaskList pStorage = pTask.GetStorageTaskList();
|
||
svr_treasure_map pTreasure = new svr_treasure_map();
|
||
|
||
var m_enumMethod = m_FixedData.m_enumMethod;
|
||
switch (pNotify.reason)
|
||
{
|
||
case TaskTemplConstants.TASK_SVR_NOTIFY_PLAYER_KILLED:
|
||
{
|
||
if (sz != Marshal.SizeOf<svr_player_killed>()) break;
|
||
if (m_enumMethod != (uint)TaskCompletionMethod.enumTMKillPlayer) break;
|
||
|
||
pKilledPlayer = GPDataTypeHelper.FromBytes<svr_player_killed>(pBuf);
|
||
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 = GPDataTypeHelper.FromBytes<svr_treasure_map>(pBuf);
|
||
pEntry.m_iUsefulData1 = pTreasure.treasure_index;
|
||
}
|
||
break;
|
||
case TaskTemplConstants.TASK_SVR_NOTIFY_MONSTER_KILLED:
|
||
if (sz != Marshal.SizeOf<svr_monster_killed>()) break;
|
||
if (m_enumMethod != (uint)TaskCompletionMethod.enumTMKillNumMonster) break;
|
||
|
||
pKilled = GPDataTypeHelper.FromBytes<svr_monster_killed>(pBuf);
|
||
|
||
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 = GPDataTypeHelper.FromBytes<svr_new_task>(pBuf);
|
||
if (svr_new_task.valid_size((int)sz))
|
||
{
|
||
BMLogger.LogError($" [TASK_SVR_NOTIFY_NEW] the size of byte not meet !!!");
|
||
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<TaskFinishTimeList*>(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 = GPDataTypeHelper.FromBytes<svr_task_complete>(pBuf);
|
||
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( notify, (uint)Marshal.SizeOf<task_notify_base>());
|
||
pTask.NotifyServer( GPDataTypeHelper.ToBytes(notify), (uint)Marshal.SizeOf<task_notify_base>());
|
||
}
|
||
#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)
|
||
{
|
||
// 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;
|
||
|
||
var m_bHidden = m_FixedData.m_bHidden;
|
||
var m_bDisplayInTitleTaskUI = m_FixedData.m_bDisplayInTitleTaskUI;
|
||
var m_ID = m_FixedData.m_ID;
|
||
|
||
|
||
// ����ﵽ����
|
||
bool bReachLimit = false;
|
||
if (m_bHidden)
|
||
bReachLimit = pList.m_uTopHideTaskCount >= TASK_HIDDEN_COUNT;
|
||
else if (m_bDisplayInTitleTaskUI)
|
||
bReachLimit = bReachLimit || pList.m_uTitleTaskCount >= TASK_TITLE_TASK_COUNT;
|
||
else
|
||
bReachLimit = bReachLimit || pList.m_uTopShowTaskCount >= pList.GetMaxSimultaneousCount();
|
||
|
||
if (bReachLimit)
|
||
return TaskInterfaceConstants.TASK_PREREQU_FAIL_FULL;
|
||
|
||
// Check Task List Empty Space
|
||
if (pList.m_uUsedCount + m_uDepth > TaskInterfaceConstants.TASK_ACTIVE_LIST_MAX_LEN)
|
||
return TaskInterfaceConstants.TASK_PREREQU_FAIL_NO_SPACE;
|
||
|
||
// �Ƿ�������ͬ����
|
||
if (pList.GetEntry(m_ID) != null) return TaskInterfaceConstants.TASK_PREREQU_FAIL_SAME_TASK;
|
||
|
||
return 0;
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckGivenItems(TaskInterface* pTask) const
|
||
// 检查交付所需道具容量合法性 // English: Check deliverable item capacity
|
||
public uint CheckGivenItems(TaskInterface pTask)
|
||
{
|
||
if (m_FixedData.m_ulGivenItems != 0)
|
||
{
|
||
if (!pTask.IsDeliverLegal()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_GIVEN_ITEM;
|
||
|
||
if (m_FixedData.m_ulGivenCmnCount != 0 && !pTask.CanDeliverCommonItem(m_FixedData.m_ulGivenCmnCount)
|
||
|| m_FixedData.m_ulGivenTskCount != 0 && !pTask.CanDeliverTaskItem(m_FixedData.m_ulGivenTskCount))
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_GIVEN_ITEM;
|
||
}
|
||
return 0u;
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckTimetable(unsigned long ulCurTime) const
|
||
// 检查任务可接时间表 // English: Check task timetable window
|
||
public uint CheckTimetable(uint ulCurTime)
|
||
{
|
||
if (m_FixedData.m_ulTimetable == 0) return 0;
|
||
|
||
// TODO: Implement judge_time_date function to properly check time windows
|
||
// C++ logic: if ANY timetable entry matches current time, return 0; else return TASK_PREREQU_FAIL_WRONG_TIME
|
||
// For now, since judge_time_date is not implemented, we allow the task to pass
|
||
// This is a temporary workaround - proper implementation should check each timetable entry
|
||
// WARNING: This may allow tasks to show when they shouldn't, but prevents blocking valid tasks
|
||
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)
|
||
{
|
||
// C++: if (m_lAvailFrequency == enumTAFNormal) return 0;
|
||
if (m_FixedData.m_lAvailFrequency == (int)TaskAwardFreq.enumTAFNormal)
|
||
return 0u;
|
||
|
||
// Basic implementation: Check if task was never completed
|
||
// If task was never completed (Search returns 0), allow it
|
||
// TODO: Full implementation should also check time periods (daily/weekly/monthly/yearly)
|
||
// and compare last completion time with current time
|
||
|
||
byte[] finishedTimeListBuf = pTask.GetFinishedTimeList();
|
||
if (finishedTimeListBuf == null || finishedTimeListBuf.Length == 0)
|
||
{
|
||
// No finished time list, task was never completed, allow it
|
||
return 0u;
|
||
}
|
||
|
||
TaskFinishTimeList pTimeList = new TaskFinishTimeList();
|
||
pTimeList.ReadFromBuffer(finishedTimeListBuf);
|
||
|
||
// Check if list is full
|
||
if (pTimeList.m_uCount >= TaskInterfaceConstants.TASK_FINISH_TIME_MAX_LEN)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_FULL;
|
||
|
||
// Search for task completion time
|
||
uint ulTaskTime = pTimeList.Search(m_FixedData.m_ID);
|
||
|
||
// If task was never completed (Search returns 0), allow it
|
||
if (ulTaskTime == 0)
|
||
return 0u;
|
||
|
||
// Task was completed - TODO: Check if within same period based on frequency
|
||
// For now, return error to prevent showing tasks that were already completed
|
||
// This is a temporary fix - proper implementation should check time periods
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_WRONG_TIME;
|
||
}
|
||
|
||
// 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)
|
||
{
|
||
// Get top task ID - finished task list stores top-level task IDs
|
||
// 获取顶层任务ID - 已完成任务列表存储的是顶层任务ID
|
||
ATaskTempl pTopTempl = GetTopTask();
|
||
uint taskIdToCheck = pTopTempl != null ? pTopTempl.m_FixedData.m_ID : m_FixedData.m_ID;
|
||
|
||
// Use top task's redo flags
|
||
// 使用顶层任务的重做标志
|
||
bool bCanRedo = pTopTempl != null ? pTopTempl.m_FixedData.m_bCanRedo : m_FixedData.m_bCanRedo;
|
||
bool bCanRedoAfterFailure = pTopTempl != null ? pTopTempl.m_FixedData.m_bCanRedoAfterFailure : m_FixedData.m_bCanRedoAfterFailure;
|
||
|
||
// If both redo flags are true, task can always be redone, skip check
|
||
// 如果两个重做标志都为true,任务总是可以重做,跳过检查
|
||
if (bCanRedo && bCanRedoAfterFailure)
|
||
return 0u;
|
||
|
||
FinishedTaskList pFinished = (FinishedTaskList)pTask.GetFinishedTaskList();
|
||
int nRet = pFinished.SearchTask(taskIdToCheck);
|
||
|
||
// nRet: -1 = not found, 0 = successfully completed, 1 = failed
|
||
// 成功完成不能接任务,或失败后不能重新接任务
|
||
// If successfully completed and can't redo, or failed and can't redo after failure
|
||
if ((nRet == 0 && !bCanRedo) || (nRet == 1 && !bCanRedoAfterFailure))
|
||
{
|
||
// Debug: Log why task is blocked
|
||
string taskName = GetTaskName(pTopTempl ?? this);
|
||
UnityEngine.Debug.Log($"[CheckFnshLst] Task {taskIdToCheck} '{taskName}' blocked: nRet={nRet}, bCanRedo={bCanRedo}, bCanRedoAfterFailure={bCanRedoAfterFailure}");
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CANT_REDO;
|
||
}
|
||
|
||
return 0u;
|
||
}
|
||
|
||
// Helper to get task name for debugging
|
||
private string GetTaskName(ATaskTempl pTempl)
|
||
{
|
||
if (pTempl == null || pTempl.m_FixedData.m_szName == null)
|
||
return "Unknown";
|
||
|
||
try
|
||
{
|
||
return ModelRenderer.Scripts.Common.ByteToStringUtils.UshortArrayToUnicodeString(pTempl.m_FixedData.m_szName);
|
||
}
|
||
catch
|
||
{
|
||
return "Error";
|
||
}
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckDeliverCount(TaskInterface* pTask) const
|
||
// 检查周期内角色/账号次数限制 // English: Check period deliver counts for role/account
|
||
public uint CheckDeliverCount(TaskInterface pTask)
|
||
{
|
||
if (m_FixedData.m_bAccountTaskLimit && m_FixedData.m_lPeriodLimit != 0)
|
||
{
|
||
if (pTask.IsAtCrossServer())
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_ACOUNT_LIMIT;
|
||
|
||
byte[] finishedCntListBuf = pTask.GetFinishedCntList();
|
||
TaskFinishCountList pFnshList = new TaskFinishCountList();
|
||
pFnshList.ReadFromBytes(finishedCntListBuf);
|
||
uint ulTemp = 0;
|
||
uint nRet = pFnshList.Search(m_FixedData.m_ID, ref ulTemp);
|
||
|
||
if ((uint)nRet >= m_FixedData.m_lPeriodLimit)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_MAX_ACC_CNT;
|
||
}
|
||
else if (m_FixedData.m_bRoleTaskLimit && m_FixedData.m_lPeriodLimit != 0)
|
||
{
|
||
FinishedTaskList pFnshList = (FinishedTaskList)pTask.GetFinishedTaskList();
|
||
long finish_count = pFnshList.SearchTaskFinishCount(m_FixedData.m_ID);
|
||
if (finish_count >= m_FixedData.m_lPeriodLimit)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_MAX_ROLE_CNT;
|
||
}
|
||
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)
|
||
{
|
||
uint i = 0;
|
||
uint ret = m_FixedData.m_bPremItemsAnyOne ? (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NO_ITEM : 0;
|
||
|
||
for (; i < m_FixedData.m_ulPremItems; i++)
|
||
{
|
||
ITEM_WANTED wi = m_FixedData.m_PremItems[i];
|
||
|
||
if (m_FixedData.m_bPremItemsAnyOne)
|
||
{
|
||
if (_get_item_count(pTask, wi.m_ulItemTemplId, wi.m_bCommonItem) >= wi.m_ulItemNum)
|
||
{
|
||
ret = 0;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (_get_item_count(pTask, wi.m_ulItemTemplId, wi.m_bCommonItem) < wi.m_ulItemNum)
|
||
{
|
||
ret = (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NO_ITEM;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 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)
|
||
{
|
||
uint i;
|
||
FinishedTaskList pFinished = (FinishedTaskList)pTask.GetFinishedTaskList();
|
||
|
||
uint iPremTaskFinishedCount = 0;
|
||
for (i = 0; i < m_FixedData.m_ulPremise_Task_Count; i++)
|
||
{
|
||
if (m_FixedData.m_ulPremise_Task_Least_Num == 0)
|
||
{
|
||
if (pFinished.SearchTask(m_FixedData.m_ulPremise_Tasks[i]) != 0)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_PREV_TASK;
|
||
}
|
||
else if (pFinished.SearchTask(m_FixedData.m_ulPremise_Tasks[i]) == 0)
|
||
{
|
||
iPremTaskFinishedCount++;
|
||
}
|
||
}
|
||
return m_FixedData.m_ulPremise_Task_Least_Num != 0 ?
|
||
(iPremTaskFinishedCount < m_FixedData.m_ulPremise_Task_Least_Num ? (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_PREV_TASK : 0) : 0;
|
||
}
|
||
|
||
// (No inline in provided snippet) 互斥任务 // English: Mutex task
|
||
public uint CheckMutexTask(TaskInterface pTask, uint ulCurTime)
|
||
{
|
||
uint i;
|
||
FinishedTaskList pFinished = (FinishedTaskList)pTask.GetFinishedTaskList();
|
||
|
||
uint iPremTaskFinishedCount = 0;
|
||
for (i = 0; i < m_FixedData.m_ulPremise_Task_Count; i++)
|
||
{
|
||
if (m_FixedData.m_ulPremise_Task_Least_Num == 0)
|
||
{
|
||
if (pFinished.SearchTask(m_FixedData.m_ulPremise_Tasks[i]) != 0)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_PREV_TASK;
|
||
}
|
||
else if (pFinished.SearchTask(m_FixedData.m_ulPremise_Tasks[i]) == 0)
|
||
{
|
||
iPremTaskFinishedCount++;
|
||
}
|
||
}
|
||
|
||
return m_FixedData.m_ulPremise_Task_Least_Num != 0 ? (iPremTaskFinishedCount < m_FixedData.m_ulPremise_Task_Least_Num ?
|
||
(uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_PREV_TASK : 0) : 0;
|
||
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckInZone(TaskInterface* pTask) const
|
||
// 区域检查 // English: In-zone check
|
||
public uint CheckInZone(TaskInterface pTask)
|
||
{
|
||
if (m_FixedData.m_bDelvInZone)
|
||
{
|
||
float[] pos = new float[3];
|
||
uint ulWorldId = (uint)pTask.GetPos(pos);
|
||
|
||
/* if (ulWorldId != m_ulDelvWorld ||
|
||
!is_in_zone(
|
||
m_DelvMinVert,
|
||
m_DelvMaxVert,
|
||
pos))
|
||
return TASK_PREREQU_FAIL_NOT_IN_ZONE;*/
|
||
if(ulWorldId != m_FixedData.m_ulDelvWorld)
|
||
return (uint) TaskInterfaceConstants.TASK_PREREQU_FAIL_NOT_IN_ZONE;
|
||
|
||
for (uint i=0; i < m_FixedData.m_ulDelvRegionCnt; i++)
|
||
{
|
||
Task_Region t = m_FixedData.m_pDelvRegion[i];
|
||
if(is_in_zone(t.zvMin,t.zvMax,pos))
|
||
return 0;
|
||
}
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NOT_IN_ZONE;
|
||
}
|
||
|
||
return 0u;
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckTeamTask(TaskInterface* pTask) const
|
||
// 组队接任务要求 // English: Team-task requirements
|
||
public uint CheckTeamTask(TaskInterface pTask)
|
||
{
|
||
// if (m_FixedData.m_bTeamwork && m_FixedData.m_bRcvByTeam) // ��ӽ���
|
||
// {
|
||
// if (!pTask.IsCaptain()) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_NOT_CAPTAIN;
|
||
// return HasAllTeamMemsWanted(pTask, true);
|
||
// }
|
||
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:
|
||
/*if (m_FixedData.m_bMarriage)
|
||
{
|
||
|
||
if (pTask.IsAtCrossServer())
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CROSSSERVER_NO_MARRIAGE;
|
||
if (pTask.IsMarried())
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ILLEGAL_MEM;
|
||
|
||
if (!pTask.IsInTeam())
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ILLEGAL_MEM;
|
||
|
||
if (pTask.GetTeamMemberNum() != 2)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ILLEGAL_MEM;
|
||
|
||
task_team_member_info m1, m2;
|
||
pTask.GetTeamMemberInfo(0, &m1);
|
||
pTask.GetTeamMemberInfo(1, &m2);
|
||
|
||
if (m1.m_bMale == m2.m_bMale)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_ILLEGAL_MEM;
|
||
}*/
|
||
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
|
||
// unsigned long i;
|
||
//
|
||
// for (i = 0; i < MAX_LIVING_SKILLS; i++)
|
||
// {
|
||
// if (m_lSkillLev[i] == 0)
|
||
// continue;
|
||
//
|
||
// if (!pTask.HasLivingSkill(_living_skill_ids[i])
|
||
// || pTask->GetLivingSkillLevel(_living_skill_ids[i]) < m_lSkillLev[i])
|
||
// return TASK_PREREQU_FAIL_LIVING_SKILL;
|
||
// }
|
||
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)
|
||
{
|
||
if (m_FixedData.m_iPremTitleNumTotal != 0) {
|
||
int iNumRequired = (int)m_FixedData.m_iPremTitleNumTotal;
|
||
if (m_FixedData.m_iPremTitleNumRequired > 0 && m_FixedData.m_iPremTitleNumRequired < m_FixedData.m_iPremTitleNumTotal)
|
||
iNumRequired = (int)m_FixedData.m_iPremTitleNumRequired;
|
||
int iTitleCount = 0;
|
||
for (uint i = 0; i < m_FixedData.m_iPremTitleNumTotal; ++i) {
|
||
if (pTask.HaveGotTitle((uint)m_FixedData.m_PremTitles[i]))
|
||
iTitleCount++;
|
||
}
|
||
if (iTitleCount < iNumRequired)
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_TITLE;
|
||
}
|
||
if (m_Award_S.m_ulTitleNum != 0) {
|
||
for (uint i = 0; i < m_Award_S.m_ulTitleNum; ++i) {
|
||
if (pTask.HaveGotTitle(m_Award_S.m_pTitleAward[i].m_ulTitleID))
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_TITLE;
|
||
}
|
||
}
|
||
if (m_Award_F.m_ulTitleNum != 0) {
|
||
for (uint i = 0; i < m_Award_F.m_ulTitleNum; ++i) {
|
||
if (pTask.HaveGotTitle(m_Award_F.m_pTitleAward[i].m_ulTitleID))
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_TITLE;
|
||
}
|
||
}
|
||
return 0u;
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckHistoryStage(TaskInterface* pTask) const
|
||
// 历史阶段 // English: History stage
|
||
public uint CheckHistoryStage(TaskInterface pTask)
|
||
{
|
||
int index = pTask.GetCurHistoryStageIndex();
|
||
|
||
if (m_FixedData.m_iPremHistoryStageIndex[0] != 0 && (index <=0 || index < m_FixedData.m_iPremHistoryStageIndex[0]))
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_HISTORYSTAGE;
|
||
if (m_FixedData.m_iPremHistoryStageIndex[1] != 0 && (index <=0 || index > m_FixedData.m_iPremHistoryStageIndex[1]))
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_HISTORYSTAGE;
|
||
|
||
return 0u;
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckCardCollection(TaskInterface* pTask) const
|
||
// 将星卡收集数量 // English: General card collection count
|
||
public uint CheckCardCollection(TaskInterface pTask)
|
||
{
|
||
uint count = pTask.GetObtainedGeneralCardCount();
|
||
|
||
if (m_FixedData.m_ulPremGeneralCardCount != 0 && (count < m_FixedData.m_ulPremGeneralCardCount))
|
||
return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CARD_COUNT_COLLECTION;
|
||
|
||
return 0u;
|
||
}
|
||
|
||
// inline unsigned long ATaskTempl::CheckCardRankCount(TaskInterface* pTask) const
|
||
// 指定品级将星卡数量 // English: Specific rank general card count
|
||
public uint CheckCardRankCount(TaskInterface pTask)
|
||
{
|
||
if (m_FixedData.m_iPremGeneralCardRank >= 0 && m_FixedData.m_ulPremGeneralCardRankCount != 0) {
|
||
uint count = pTask.GetObtainedGeneralCardCountByRank(m_FixedData.m_iPremGeneralCardRank);
|
||
if (count < m_FixedData.m_ulPremGeneralCardRankCount) return (uint)TaskInterfaceConstants.TASK_PREREQU_FAIL_CARD_COUNT_RANK;
|
||
}
|
||
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<unsigned char>(pEntry - aEntries);
|
||
|
||
pEntry->m_ID = static_cast<unsigned short>(m_ID);
|
||
pEntry->m_ulTemplAddr = reinterpret_cast<unsigned long>(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<unsigned long>(GetTaskTemplMan()->GetTopTaskByID(ulCaptainTask));
|
||
if (pEntry->m_ulCapTemplAddr) pEntry->m_uCapTaskId = static_cast<unsigned short>(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<unsigned short>(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<unsigned char>(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<FinishedTaskList*>(pTask->GetFinishedTaskList())->AddOneTask(
|
||
m_ID,
|
||
pEntry->IsSuccess());
|
||
}
|
||
|
||
// �˺�������������ɴ���
|
||
if (!m_pParent && m_bAccountTaskLimit)
|
||
{
|
||
// ��������ʱ���ж��Ƿ��������ɴ���
|
||
CheckDeliverTime(pTask, ulCurtime);
|
||
// û�й�ѡ��ʧ�ܵ�ʱ��¼��ɴ����������߹�ѡ��ʧ�ܵ�ʱ��¼��ɴ�������������ɹ���ʱ��
|
||
if (!m_bNotIncCntWhenFailed || (m_bNotIncCntWhenFailed && pEntry->IsSuccess()))
|
||
static_cast<TaskFinishCountList*>(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<FinishedTaskList*>(pTask->GetFinishedTaskList())->AddForFinishCount(m_ID,pEntry->IsSuccess());
|
||
// TaskFinishTimeList�ﱣ���������ʱ��
|
||
static_cast<TaskFinishTimeList*>(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<task_notify_base*>(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();
|
||
svr_player_killed.baseObj = 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()
|
||
{
|
||
baseObj = 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<svr_new_task*>(pNotify)->set_data(
|
||
// ulCurTime,
|
||
// reinterpret_cast<unsigned long>(pEntry),
|
||
// *(reinterpret_cast<const task_sub_tags*>(ulParam))
|
||
// );
|
||
var svrNewTask = new svr_new_task
|
||
{
|
||
baseObj = pNotify,
|
||
};
|
||
svrNewTask.set_data(
|
||
ulCurTime,
|
||
pEntry.m_ID,
|
||
Marshal.PtrToStructure<task_sub_tags>((IntPtr)ulParam)
|
||
);
|
||
sz = svrNewTask.get_size();
|
||
break;
|
||
}
|
||
case TaskTemplConstants.TASK_SVR_NOTIFY_COMPLETE:
|
||
// static_cast<svr_task_complete*>(pNotify)->set_data(
|
||
// ulCurTime,
|
||
// *(reinterpret_cast<const task_sub_tags*>(ulParam))
|
||
// );
|
||
// sz = static_cast<svr_task_complete*>(pNotify)->get_size();
|
||
var svrTaskComplete = new svr_task_complete
|
||
{
|
||
baseObj = pNotify,
|
||
};
|
||
svrTaskComplete.set_data(
|
||
ulCurTime,
|
||
Marshal.PtrToStructure<task_sub_tags>((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<task_notify_base>();
|
||
break;
|
||
case TaskTemplConstants.TASK_SVR_NOTIFY_ERROR_CODE:
|
||
var svrTaskErrCode = new svr_task_err_code
|
||
{
|
||
baseObj = 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<TaskGlobalData> 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<ActiveTaskList*>(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<unsigned long>(&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);
|
||
// }
|
||
}
|
||
|
||
|
||
}
|
||
} |