⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 user_task.cpp

📁 魔域的源代码
💻 CPP
字号:
// User.cpp: implementation of the CUser class.
//
//////////////////////////////////////////////////////////////////////

#include "AllMsg.h"
#include "User.h"
#include "MapGroup.h"
#include "netmsg.h"
#include "ItemType.h"
#include "MapItem.h"
#include "Package.h"
#include "ActionDefine.h"
#include "Syndicate.h"
#include "npc.h"
#include "WantedList.h"
#include "MercenaryTask.h"

const VAL_SKIPTEST	=999;
const int	PRESENTMONEY_LIMIT		= 10000;			// 基金划拨不少于10000

//////////////////////////////////////////////////////////////////////
// task
////////////////////////////////////////////////////////////////////////////////////
bool CUser::TestTask(CTaskData* pTask)
{
	CHECKF(pTask);

	try
	{
		if(!CheckItem(pTask))
			return false;	// 没有任务物品

		if (this->GetMoney() < pTask->GetInt(TASKDATA_MONEY))
			return false;

		if (pTask->GetInt(TASKDATA_PROFESSION) && this->GetProfession() != pTask->GetInt(TASKDATA_PROFESSION))
			return false;

//		if (pTask->GetInt(TASKDATA_SEX) && ((1 << this->GetSex()) & pTask->GetInt(TASKDATA_SEX)) != 0)
//			return false;

		if (this->GetPk() < pTask->GetInt(TASKDATA_MINPK) || this->GetPk() > pTask->GetInt(TASKDATA_MAXPK))
			return false;

		if (pTask->GetInt(TASKDATA_TEAM) != VAL_SKIPTEST)
		{
/*			switch(pTask->GetInt(TASKDATA_TEAM))
			{
			case 0:
			case 1:
				{
					int nMembers	=this->GetTeamMembers();
					if (nMembers != 0 && nMembers != 1)
						return false;
				}
				break;

			case 2:
			case 3:
			case 4:
			case 5:
				{
					if (this->GetTeamMembers() != m_Info.nTeam)
						return false;
				}
				break;

			case 6:		// no team members check
				break;

			case 7:		// couple
				{
					CTeam* pTeam	=this->GetTeam();
					if (!pTeam || !pTeam->IsCoupleTeam())
						return false;
				}
				break;

			case 8:		// brother
				{
					CTeam* pTeam	=this->GetTeam();
					if (!pTeam || !pTeam->IsBrotherTeam())
						return false;
				}
				break;

			default:
				return false;
			} // switch
*/		}

		if (pTask->GetInt(TASKDATA_SEX) != VAL_SKIPTEST)
		{
			if (this->GetSex() != pTask->GetInt(TASKDATA_SEX))
				return false;
		}
/*
		if(pTask->GetInt(TASKDATA_METEMPSYCHOSIS) && this->GetMetempsychosis() < pTask->GetInt(TASKDATA_METEMPSYCHOSIS))
		{
			if (g_cSyndicate.GetLevel(this->GetSyndicateID()) != m_Info.nSyndicate)
				return false;
		}
*/
		int nMarriageChk = pTask->GetInt(TASKDATA_MARRIAGE);
		if (-1 != nMarriageChk)
		{
			if (0 == nMarriageChk && this->IsMarried())
				return false;

			if (1 == nMarriageChk && !this->IsMarried())
				return false;
		}

		return true;
	}
	catch(...)
	{
		ASSERT(!"catch");
		::LogSave("exception catched In CGameTask::TestUser.");
		return false;
	}
}

////////////////////////////////////////////////////////////////////////////////////
bool CUser::CheckItem(CTaskData* pTask)
{
	if(strlen(pTask->GetStr(TASKDATA_ITEMNAME1)) > 0)
	{
		if(!this->GetTaskItem(pTask->GetStr(TASKDATA_ITEMNAME1)))
			return false;

		if(strlen(pTask->GetStr(TASKDATA_ITEMNAME2)) > 0)
		{
			if(!this->GetTaskItem(pTask->GetStr(TASKDATA_ITEMNAME2)))
				return false;
		}
	}

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CUser::ProcessClientTask(OBJID idTask, LPCTSTR pszAccept)
{
	CTaskData* pTask = TaskSet()->GetObj(idTask);
	CHECKF(pTask && pTask->GetInt(TASKDATA_CLIENTACT));

	CNpc* pNpc = NULL;
	GetMap()->QueryObj(GetPosX(), GetPosY(), OBJ_NPC, m_idTaskNpc, IPP_OF(pNpc));	// pNpc may be null

	if (!this->TestTask(pTask))
	{
		OBJID idNext	= pTask->GetInt(TASKDATA_IDNEXTFAIL);
		if (idNext != ID_NONE)
		{
			GameAction()->ProcessAction(idNext, this, pNpc->QueryRole(), NULL, pszAccept);
			return true;
		}

		this->SendSysMsg(STR_UNQUALIFIED);
		return false;
	}

	OBJID idNext	= pTask->GetInt(TASKDATA_IDNEXT);
	if (idNext != ID_NONE)
		GameAction()->ProcessAction(idNext, this, pNpc->QueryRole(), NULL, pszAccept);

	return true;
}

//////////////////////////////////////////////////////////////////////
int CUser::PushTaskID(OBJID idTask, OBJID idIter)
{
	if(idTask != ID_NONE && m_setTaskID.size() < MAX_MENUTASKSIZE)
	{
		m_setTaskID.push_back(idTask);
		m_setIterID.push_back(idIter);
		return m_setTaskID.size()-1;
	}
	return INDEX_NONE;
}

//////////////////////////////////////////////////////////////////////
bool CUser::ProcessTask(int idx, LPCTSTR pszAccept)
{
	// check npc
	if(m_idTaskNpc == ID_NONE)
		return false;
	CNpc* pNpc = NULL;
	if(!GetMap()->QueryObj(GetPosX(), GetPosY(), OBJ_NPC, m_idTaskNpc, IPP_OF(pNpc)))
	{
//		LOGERROR("任务系统回馈触发的NPC[%u]找不到!", m_idTaskNpc);
		return false;
	}
	CHECKF(pNpc);

	OBJID	idTask = GetTaskID(idx);
	if (idTask == ID_NONE)
		return false;
	SetIterID(idx);
	ClearTaskID();

	CTaskData* pTask = TaskSet()->GetObj(idTask);
	IF_NOT(pTask)
	{
		LOGERROR("Don't find ACTION ID in menu: %d", idTask);
		return false;
	}

	if (!this->TestTask(pTask))
	{
		OBJID idNext	= pTask->GetInt(TASKDATA_IDNEXTFAIL);
		if (idNext != ID_NONE)
		{
			GameAction()->ProcessAction(idNext, this, pNpc->QueryRole(), NULL, pszAccept);
			return true;
		}

		this->SendSysMsg(STR_UNQUALIFIED);
		return false;
	}

	OBJID idNext	= pTask->GetInt(TASKDATA_IDNEXT);
	if (idNext != ID_NONE)
		GameAction()->ProcessAction(idNext, this, pNpc->QueryRole(), NULL, pszAccept);

	return true;
}

//////////////////////////////////////////////////////////////////////
void CUser::AddTaskMask		(int idx)
{
	IF_NOT (idx >= 0 && idx < 32)
		return;

	DWORD dwMask = m_data.GetTaskMask()|(1<<idx);
	m_data.SetTaskMask(dwMask);
}

//////////////////////////////////////////////////////////////////////
void CUser::ClrTaskMask		(int idx)
{
	IF_NOT (idx >= 0 && idx < 32)
		return;

	DWORD dwMask = m_data.GetTaskMask();
	dwMask	&= ~(1<<idx);
	m_data.SetTaskMask(dwMask);
}

//////////////////////////////////////////////////////////////////////
bool CUser::ChkTaskMask		(int idx)
{
	IF_NOT (idx >= 0 && idx < 32)
		return false;

	return (m_data.GetTaskMask() & (1<<idx)) != 0;
}

//////////////////////////////////////////////////////////////////////
bool CUser::CompleteMercenaryTask(OBJID idTask, OBJID idItem)
{
	// 提交完成的佣兵任务
	// 检查任务合法性
	CMercenaryTaskData* pTaskData = MercenaryTask()->QueryTaskDataByID(idTask);
	if (!pTaskData)
	{
		SendSysMsg(STR_INVALID_MERCENARYTASK);
		return false;
	}
	if (pTaskData->GetInt(MTASKDATA_USER_ID) == GetID())
	{
		// 关闭自己的任务
		if (pTaskData->GetInt(MTASKDATA_STATE) != MTASKSTATE_COMPLETED)
		{
			// 任务还没结束呢
			SendSysMsg(STR_TASK_NOT_FINISHED_YET);
			return false;
		}

		// 取得任务物品
		if (pTaskData->GetInt(MTASKDATA_TYPE) == _WANT_ITEM
			|| pTaskData->GetInt(MTASKDATA_TYPE) == _WANT_EUDEMON)
		{
			{	// 先检查背包空间
				CItem* pItem = pTaskData->GetResultItem();
				if (pItem && QueryPackage()->IsPackFull(1, &pItem))
				{
					SendSysMsg(STR_BAG_FULL);
					return false;
				}
			}
			CItem* pItem = pTaskData->PopResultItem();
			ASSERT(pItem);
			AddItem(pItem, true, true);
		}
		else if (pTaskData->GetInt(MTASKDATA_TYPE) ==_WANT_PK)
		{
			// 杀人任务,不需要取得任何物品
		}
		else
		{
			::LogSave("Invalid mercenary task type [ID=%u, type=%u]", 
				pTaskData->GetID(), pTaskData->GetInt(MTASKDATA_TYPE));
			return false;
		}
		// 关闭任务 —— 直接删除任务
		MercenaryTask()->DeleteTask(idTask);

		// return a message
		SendSysMsg(STR_CLOSE_TASK_OK);
	}
	else
	{
		// 完成自己接的任务
		if (pTaskData->GetInt(MTASKDATA_ACCEPT_USERID) != GetID()
			|| (pTaskData->GetInt(MTASKDATA_STATE) != MTASKSTATE_ACCEPTED
				&& pTaskData->GetInt(MTASKDATA_STATE) != MTASKSTATE_FINISHED))
		{
			// 不是自己接的任务,或者不是处于已接未完成状态,非法
			SendSysMsg(STR_INVALID_MERCENARYTASK);
			return false;
		}
		// 任务有两种情况:悬赏杀人或者悬赏物品
		if (pTaskData->GetInt(MTASKDATA_TYPE) == _WANT_ITEM
			|| pTaskData->GetInt(MTASKDATA_TYPE) == _WANT_EUDEMON)
		{
			// 悬赏物品
			// 检查idItem给顶的物品是否满足条件
			// coding here...
			CItem* pResultItem = GetItem(idItem);	// 先不同步到客户端
			if (pResultItem && pResultItem->IsEudemon())
			{
				CallBackEudemon(pResultItem->GetID());
				DetachEudemon(pResultItem);
			}

			IF_NOT (pResultItem = PopItem(idItem, false, true))
				return false;

			if (pTaskData->AddResultItem(pResultItem))
			{
				CMsgItem msg;
				if(msg.Create(idItem, ITEMACT_DROP))	// 成功后才同步
					this->SendMsg(&msg);

				// set task finished.
				pTaskData->SetInt(MTASKDATA_STATE, MTASKSTATE_FINISHED, true);		// 为了保证不要出错,这里立刻写库
			}
			else
			{
				// 失败,重新返回给玩家
				AddItem(pResultItem, false);		// 因为前面没有同步通知客户端删除,这里也就没必要通知客户端添加
				SendSysMsg(STR_ILLEGAL_TASK_ITEM);
				return false;
			}
		}
		else if (pTaskData->GetInt(MTASKDATA_TYPE) == _WANT_PK)
		{
			// 悬赏杀人,在杀死目标的时候就自动将任务设置为Finished状态了,这里就不需要做任何事情了
		}
		else
		{
			::LogSave("Invalid mercenary task type [ID=%u, type=%u]", 
				pTaskData->GetID(), pTaskData->GetInt(MTASKDATA_TYPE));
			return false;
		}

		// 经过上面一步,如果任务成功执行,则已经将任务设置为finished状态。

		if (pTaskData->GetInt(MTASKDATA_STATE) == MTASKSTATE_FINISHED)
		{
			// 任务已经完成,领取奖品
			// 先检查背包空间
			{
				CItem* setItems[_MAX_PRIZE];
				int nAmount = 0;
				for (int i=0; i<_MAX_PRIZE; i++)
				{
					OBJID idItem = pTaskData->GetInt((MTASKDATA)(MTASKDATA_PRIZE_ITEMID0+i));
					if (idItem != ID_NONE)
					{
						CItem* pItem = pTaskData->GetItem(idItem);
						IF_NOT (pItem)
							return false;
						setItems[nAmount]	= pItem;
						++nAmount;
					}
				}
				if (nAmount > 0 && QueryPackage()->IsPackFull(nAmount, setItems))
				{
					SendSysMsg(STR_BAG_FULL);
					return false;
				}
			}

			// 先结束任务
			pTaskData->SetInt(MTASKDATA_STATE, MTASKSTATE_COMPLETED);
			
			// 后领奖
			// 奖品
			for (int i=0; i<_MAX_PRIZE; i++)
			{
				OBJID idItem = pTaskData->GetInt((MTASKDATA)(MTASKDATA_PRIZE_ITEMID0+i));
				if (idItem != ID_NONE)
				{
					CItem* pItem = pTaskData->PopItem(idItem);
					if (pItem)
						AddItem(pItem, true, true);
					pTaskData->SetInt((MTASKDATA)(MTASKDATA_PRIZE_ITEMID0+i), ID_NONE);
				}
			}
			// 奖金
			GainMoney(pTaskData->GetInt(MTASKDATA_PRIZE_MONEY), true);
			pTaskData->SetInt(MTASKDATA_PRIZE_MONEY, 0, true);

			// send a message to client
			SendSysMsg(STR_TAKE_PRIZE_OK);
		}
		else
		{
			// 任务还没完成呢
			// send task unfinished msg to client
			SendSysMsg(STR_TASK_NOT_FINISHED_YET);
			return false;
		}
	}
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CUser::AcceptMercenaryTask(OBJID idTask)
{
	// 检查是否已经接过任务
	{
		CMercenaryTaskData* pTaskData = MercenaryTask()->QueryTaskDataAccepted(GetID());
		if (pTaskData)
		{
			SendSysMsg(STR_DUPLICATE_TASK);
			return false;
		}
	}

	// 检查被接任务的有效性
	CMercenaryTaskData* pTaskData = MercenaryTask()->QueryTaskDataByID(idTask);
	if (!pTaskData)
	{
		SendSysMsg(STR_INVALID_MERCENARYTASK);
		return false;
	}

	if (pTaskData->GetInt(MTASKDATA_USER_ID) == this->GetID())
	{
		SendSysMsg(STR_CANNOT_ACCEPT_MYTASK);
		return false;
	}

	if (pTaskData->GetInt(MTASKDATA_STATE) != MTASKSTATE_NONE)
	{
		SendSysMsg(STR_INVALID_MERCENARYTASK);
		return false;
	}

	if (GetMercenaryRank() < pTaskData->GetInt(MTASKDATA_RANK_REQ))
	{
		SendSysMsg(STR_LOW_MERCENARY_RANK);
		return false;
	}

	// 扣押金
	int nMoney = pTaskData->GetInt(MTASKDATA_PRIZE_MONEY);
	for (int i=0; i<_MAX_PRIZE; i++)
	{
		CItem* pItem = pTaskData->GetItemByIndex(i);
		if (pItem)
			nMoney += pItem->GetInt(ITEMDATA_PRICE);
	}
	nMoney = __max(500, nMoney/100);	// 接任务只收任务奖品价格+奖金的1%,但是最低为500
	if (!SpendMoney(nMoney, true))
	{
		SendSysMsg(STR_NOT_ENOUGH_MONEY, nMoney);
		return false;
	}

	// 接任务
	pTaskData->SetInt(MTASKDATA_STATE, MTASKSTATE_ACCEPTED);
	pTaskData->SetInt(MTASKDATA_ACCEPT_TIME, ::TimeGet(TIME_SECOND));	// 记录时间
	pTaskData->SetInt(MTASKDATA_ACCEPT_USERID, GetID(), true);

	// retuen a message
	SendSysMsg(STR_ACCEPT_TASK_OK);
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CUser::CancelMercenaryTask(OBJID idTask)
{
	// 检查任务合法性
	CMercenaryTaskData* pTaskData = MercenaryTask()->QueryTaskDataByID(idTask);
	if (!pTaskData)
	{
		SendSysMsg(STR_INVALID_MERCENARYTASK);
		return false;
	}
	if (pTaskData->GetInt(MTASKDATA_USER_ID) == GetID())
	{
		// 中止自己的任务
		if (pTaskData->GetInt(MTASKDATA_STATE) != MTASKSTATE_NONE)
		{
			// 任务不是处于未接状态,不能中止
			SendSysMsg(STR_CANNOT_CANCEL_TASK);
			return false;
		}
		// 先检查背包空间
		{
			CItem* setItems[_MAX_PRIZE];
			int nAmount = 0;
			for (int i=0; i<_MAX_PRIZE; i++)
			{
				OBJID idItem = pTaskData->GetInt((MTASKDATA)(MTASKDATA_PRIZE_ITEMID0+i));
				if (idItem != ID_NONE)
				{
					CItem* pItem = pTaskData->GetItem(idItem);
					IF_NOT (pItem)
						return false;
					setItems[nAmount]	= pItem;
					++nAmount;
				}
			}
			if (nAmount > 0 && QueryPackage()->IsPackFull(nAmount, setItems))
			{
				SendSysMsg(STR_BAG_FULL);
				return false;
			}
		}
		// 返还奖品和奖金
		// 奖品
		DEBUG_TRY
		for (int i=0; i<_MAX_PRIZE; i++)
		{
			OBJID idItem = pTaskData->GetInt((MTASKDATA)(MTASKDATA_PRIZE_ITEMID0+i));
			if (idItem != ID_NONE)
			{
				CItem* pItem = pTaskData->PopItem(idItem);
				if (pItem)
					AddItem(pItem, true, true);
				pTaskData->SetInt((MTASKDATA)(MTASKDATA_PRIZE_ITEMID0+i), ID_NONE);
			}
		}
		DEBUG_CATCH("CUser::CancelMercenaryTask crash when return prize items")
		// 奖金
		GainMoney(pTaskData->GetInt(MTASKDATA_PRIZE_MONEY), true);

		//pTaskData->SetInt(MTASKDATA_STATE, MTASKSTATE_CANCELED, true);
		// 中止任务只要直接删除任务就好了
		MercenaryTask()->DeleteTask(idTask);
	}
	else
	{
		// 中止自己接的任务
		if (pTaskData->GetInt(MTASKDATA_ACCEPT_USERID) != GetID()
			|| pTaskData->GetInt(MTASKDATA_STATE) != MTASKSTATE_ACCEPTED)
		{
			// 不是自己接的任务,或者不是处于已接未完成状态,非法
			SendSysMsg(STR_INVALID_MERCENARYTASK);
			return false;
		}

		// 撤消正在执行的佣兵任务
		pTaskData->SetInt(MTASKDATA_ACCEPT_USERID, ID_NONE);
		pTaskData->SetInt(MTASKDATA_STATE, MTASKSTATE_NONE, true);

	}
	// return a message
	SendSysMsg(STR_CANCEL_TASK_OK);
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -