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

📄 npc.cpp

📁 魔域源代码需要的可以学习一下真么这么麻烦啊
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// TaskNpc.cpp: implementation of the CNpc class.
//
//////////////////////////////////////////////////////////////////////

#include "AllMsg.h"
#include "windows.h"
#include "Gameobj.h"
#include "MapGroup.h"
#include "define.h"
#include "Npc.h"
#include "NpcTask.h"
#include "NpcScene.h"
#include "NpcLink.h"
#include "NpcStorage.h"
#include "BetOutside.h"

//////////////////////////////////////////////////////////////////////
const int	FIXSYNFLAG_SECS				= 10;
const int	MAX_FIXMONEY				= 1000;
const int	FIXLIFE_PER_MONEY			= 1;
const int	BROADCASTSCORE_SECS			= 30;				// 注意:太大可能错开战斗时间检查
const int	TRANSNPC_FEE				= 10000;			// 每天每个传送门收费

//////////////////////////////////////////////////////////////////////
// static 
char	szNpcTable[] = _TBL_NPC;
char	szDynTable[] = _TBL_DYNANPC;
MYHEAP_IMPLEMENTATION(CNpc,s_heap)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CNpc::CNpc()
{
	SetObjType(OBJ_NPC);
	m_id	= ID_NONE;
	m_pData	= NULL;
	m_bDynaNpc	= false;

	m_pShop		= NULL;
	m_pAuction  = NULL;
	m_pTask		= NULL;
//	m_pStorage	= NULL;
	m_pTrunk	= NULL;
	m_pScene	= NULL;
	m_pLinkMap	= NULL;
	m_pBet		= NULL;
	m_pEudemonBrooder	= NULL;
	m_pEudemonStorage	= NULL;
	m_i64Effect	= 0;
}

//////////////////////////////////////////////////////////////////////
CNpc::~CNpc()
{
	if(m_pMap)
	{
		//SendLeaveFromBlock();
		ClrBroadcastSet();
		
		if(m_pMap)
		{
			m_pMap->LeaveRoom(QueryMapThing(), WITH_BLOCK);
			UpdateHoldFloor(false);
		}
	}

	SAFE_RELEASE (m_setStatus);

	if(m_pData)
	{
		if(IsDynaNpc())
		{
			if(IsAlive())
				SaveInfo();
			else
				DeleteRecord();
		}
		m_pData->Release();
	}
	if(m_pShop)
	{
		m_pShop->Release();
	}
	if(m_pAuction)
	{
		m_pAuction->Release();
	}
	if(m_pTask)
	{
		m_pTask->Release();
	}
	/*if(m_pStorage)
	{
		m_pStorage->Release();
	}*/
	if(m_pLinkMap)
	{
		m_pLinkMap->Release();
	}
	if(m_pScene)
	{
		m_pScene->Release();
	}
	if(m_pTrunk)
	{
		m_pTrunk->Release();
	}
	if(m_pBet)
	{
		m_pBet->Release();
	}
	if (m_pEudemonBrooder)
		SAFE_RELEASE (m_pEudemonBrooder);
	if (m_pEudemonStorage)
		SAFE_RELEASE (m_pEudemonStorage);
}

//////////////////////////////////////////////////////////////////////
bool CNpc::Create(PROCESS_ID idProcess, NPCINFO_ST* pInfo, OBJID idItemType, LPCTSTR szName)
{
	m_idProcess = idProcess;
	m_bDynaNpc	= true;
/*
	// 使用VALUES单独INSERT,防止SQL溢出
	SQLBUF	szSQL;
	ASSERT(_MAX_NPCTASK == 8);
	ASSERT(MAX_NPCDATA == 4);
	sprintf(szSQL, "INSERT %s VALUES(%u,%u,%d,'%s',%d,%d,%d,%u,%d,%d"",%d,%d,%d,%d,%d,%d,%d,%d"",%d,%d,%d,%d,'%s'"",%u,%d,%d,%d,%u",
					_TBL_DYNANPC,
					ID_NONE, pInfo->idOwner, pInfo->nOwnerType, "无", pInfo->nType, pInfo->nLookFace, -1, pInfo->idMap, pInfo->nPosX, pInfo->nPosY,
					pInfo->setTask[0], pInfo->setTask[1], pInfo->setTask[2], pInfo->setTask[3], 
					pInfo->setTask[4], pInfo->setTask[5], pInfo->setTask[6], pInfo->setTask[7], 
					pInfo->setData[0], pInfo->setData[1], pInfo->setData[2], pInfo->setData[3], pInfo->szData, 
					ID_NONE, pInfo->nLife, pInfo->nLife, pInfo->nDir, pInfo->idRegion);
	CHECKFDatabase()->ExecuteSQL(szSQL));
	OBJID idRecord = Database()->GetInsertId();
	CHECKF(idRecord != ID_NONE);
*/
	ASSERT(!m_pData);
	CDynaNpcData* pData = CDynaNpcData::CreateNew();
	if(pData)
		m_pData	= pData->QueryInterface();
	IF_NOT(m_pData && m_pData->Create(GameDataDefault()->GetDynaNpc(), ID_NONE))			// idRecord))
		return false;
	m_pData->SetInt(NPCDATA_OWNERID,	pInfo->idOwner);
	m_pData->SetInt(NPCDATA_OWNERTYPE,	pInfo->nOwnerType);
	m_pData->SetInt(NPCDATA_TYPE,		pInfo->nType);
	m_pData->SetStr(NPCDATA_NAME,		szName, _MAX_NAMESIZE);
	m_pData->SetInt(NPCDATA_LOOKFACE,	pInfo->nLookFace);
	m_pData->SetInt(NPCDATA_LENGTH,		pInfo->cLength);
	m_pData->SetInt(NPCDATA_FAT,		pInfo->cFat);
	m_pData->SetInt(NPCDATA_IDXSERVER,	-1);
	m_pData->SetInt(NPCDATA_MAPID,		pInfo->idMap);
	m_pData->SetInt(NPCDATA_POSX_,		pInfo->nPosX);
	m_pData->SetInt(NPCDATA_POSY_,		pInfo->nPosY);
	m_pData->SetInt(NPCDATA_TASK0,		pInfo->setTask[0]);
	m_pData->SetInt(NPCDATA_TASK1,		pInfo->setTask[1]);
	m_pData->SetInt(NPCDATA_TASK2,		pInfo->setTask[2]);
	m_pData->SetInt(NPCDATA_TASK3,		pInfo->setTask[3]);
	m_pData->SetInt(NPCDATA_TASK4,		pInfo->setTask[4]);
	m_pData->SetInt(NPCDATA_TASK5,		pInfo->setTask[5]);
	m_pData->SetInt(NPCDATA_TASK6,		pInfo->setTask[6]);
	m_pData->SetInt(NPCDATA_TASK7,		pInfo->setTask[7]);
	m_pData->SetInt(NPCDATA_DATA0,		pInfo->setData[0]);
	m_pData->SetInt(NPCDATA_DATA1,		pInfo->setData[1]);
	m_pData->SetInt(NPCDATA_DATA2,		pInfo->setData[2]);
	m_pData->SetInt(NPCDATA_DATA3,		pInfo->setData[3]);
	m_pData->SetStr(NPCDATA_DATASTR,	pInfo->szData, _MAX_NAMESIZE);
	m_pData->SetInt(NPCDATA_LINKID,		pInfo->idLink);
	m_pData->SetInt(NPCDATA_LIFE,		pInfo->nLife);
	m_pData->SetInt(NPCDATA_MAXLIFE,	pInfo->nLife);
	m_pData->SetInt(NPCDATA_BASE,		pInfo->idBase);
	m_pData->SetInt(NPCDATA_SORT,		pInfo->nSort);
	if(pInfo->nSort & NPCSORT_RECYCLE)
		m_pData->SetInt(NPCDATA_ITEMTYPE,		idItemType);
	m_pData->InsertRecord();

	m_id	= MapManager()->SpawnNewNpcID();
	m_nPosX = m_pData->GetInt(NPCDATA_POSX_);
	m_nPosY = m_pData->GetInt(NPCDATA_POSY_);

	if (this->IsTrunkNpc()
			|| this->IsShopNpc()
				|| this->IsSceneNpc()
					|| this->IsTaskNpc()
						|| this->IsBetNpc())
	{
		IF_NOT(CreateFuncObj(idProcess))
			return false;
	}

	IF_NOT(CheckSortMutex())
		return false;

	m_setStatus = CStatusSet::CreateNew(true);
	CHECKF(m_setStatus);
	m_pMap = MapManager()->QueryMap(m_pData->GetInt(NPCDATA_MAPID));
	IF_NOT(m_pMap)
		return false;			//?? 非本进程组地图

	// trans npc exclusive
	MapGroup(PID)->QueryIntraMsg()->DelTransNpc(GetInt(NPCDATA_LINKID));	// del this mapgroup first

	m_pMap->EnterRoom(QueryMapThing(), WITH_BLOCK);
	UpdateHoldFloor(true);
	//SendSelfToBlock();
	UpdateBroadcastSet();

	// set map syn id
	if(IsSynFlag())
	{
		GetMap()->SetSynID(GetSynID(), true);		// with all map npc
//		CheckFightTime();

		// temporary code
		OBJID idMoreMap = GetData(SYNFLAGNPC_MOREMAPID);
		if(idMoreMap != ID_NONE)
		{
			CGameMap* pMoreMap = MapManager()->QueryMap(idMoreMap);
			if(pMoreMap)
				pMoreMap->SetSynID(GetSynID(), true);		// with all map npc
		}
	}

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CNpc::Create(PROCESS_ID idProcess, IRecordset* pRecordset, bool bDynaNpc)
{
	m_idProcess = idProcess;
	m_bDynaNpc	= bDynaNpc;

	ASSERT(!m_pData);
	if(bDynaNpc)
	{
		CDynaNpcData* pData = CDynaNpcData::CreateNew();
		if(pData)
			m_pData	= pData->QueryInterface();
	}
	else
	{
		CNpcData* pData = CNpcData::CreateNew();
		if(pData)
			m_pData	= pData->QueryInterface();
	}
	IF_NOT(m_pData && m_pData->Create(pRecordset))
		return false;

	CGameMap* pMap = MapManager()->QueryMap(m_pData->GetInt(NPCDATA_MAPID), false);		// false: not load dynamic map
	if(!pMap)
		return false;			//?? 非本进程组地图,或者动态地图的NPC

	if(bDynaNpc)
		m_id	= MapManager()->SpawnNewNpcID();
	else
		m_id	= m_pData->GetID();					// fixed to database id
	m_nPosX = m_pData->GetInt(NPCDATA_POSX_);
	m_nPosY = m_pData->GetInt(NPCDATA_POSY_);

	if (this->IsTrunkNpc()
			|| this->IsShopNpc()
				|| this->IsSceneNpc()
					|| this->IsTaskNpc()
						|| this->IsBetNpc()
							|| this->IsAuctionNpc() )
	{
		IF_NOT(CreateFuncObj(idProcess))
			return false;
	}

	IF_NOT(CheckSortMutex())
		return false;

	m_setStatus = CStatusSet::CreateNew(true);
	CHECKF(m_setStatus);
	m_pMap = pMap;

	// 冗错非法NPC坐标
	if(!GetMap()->IsValidPoint(GetPosX(), GetPosY()))
	{
		LOGERROR("NPC数据错[%u],坐标非法[%d,%d]", GetRecordID(), GetPosX(), GetPosY());
		m_pMap	= NULL;
		return false;
	}

	m_pMap->EnterRoom(QueryMapThing(), WITH_BLOCK);
	UpdateHoldFloor(true);
	UpdateBroadcastSet();

	// set map syn id
	if(IsSynFlag())
	{
		GetMap()->SetSynID(GetSynID(), false);		// false: no set npc in map
		CheckFightTime();

		// temporary code
		OBJID idMoreMap = GetData(SYNFLAGNPC_MOREMAPID);
		if(idMoreMap != ID_NONE)
		{
			CGameMap* pMoreMap = MapManager()->QueryMap(idMoreMap);
			if(pMoreMap)
				pMoreMap->SetSynID(GetSynID(), false);		// false: no set npc in map
		}
	}

	if(!IsDynaNpc() && GetMaxLife() > 0)
	{
		LOGERROR("静态NPC不能设置最大血为非0:[%d]", GetID());
	}

	return true;
}

/////////////////////////////////////////////////////////////////////
BOOL CNpc::	ChangePos (OBJID idMap, int nPosX, int nPosY)
{
	if (!MapManager()->QueryMap(idMap))
		return false;
	
	this->SendLeaveFromBlock();
	m_pMap->LeaveRoom(QueryMapThing(), WITH_BLOCK);
	UpdateHoldFloor(false);

	m_pMap = MapManager()->QueryMap(idMap);
	m_nPosX = nPosX;
	m_nPosY = nPosY;

	m_pMap->EnterRoom(QueryMapThing(), WITH_BLOCK);
	UpdateHoldFloor(true);
	UpdateBroadcastSet();

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CNpc::CreateFuncTrunk(PROCESS_ID idProcess)
{
	/*if(IsStorageNpc())
	{
		ASSERT(!m_pStorage);
		CNpcStorage*	m_pStorage = CNpcStorage::CreateNew();
		IF_NOT(m_pStorage && m_pStorage->Create(idProcess, GetID())
			return false;
	}*/
	if(IsTrunkNpc())
	{
		ASSERT(!m_pTrunk);
		m_pTrunk = CNpcTrunk::CreateNew();
		IF_NOT(m_pTrunk && m_pTrunk->Create(idProcess, GetRecordID(), GetData(TRUNKNPC_SIZE), ITEMPOSITION_TRUNK))
			return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CNpc::CreateFuncEudemonBrooder(PROCESS_ID idProcess)
{
	if (IsEudemonBrooderNpc())
	{
		ASSERT(!m_pEudemonBrooder);
		m_pEudemonBrooder = CNpcTrunk::CreateNew();
		IF_NOT(m_pEudemonBrooder && m_pEudemonBrooder->Create(idProcess, GetRecordID(), GetData(EUDEMON_BROODER_NPC_SIZE), ITEMPOSITION_EUDEMON_BROODER))
			return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CNpc::CreateFuncEudemonStorage(PROCESS_ID idProcess)
{
	if (IsEudemonStorageNpc())
	{
		ASSERT(!m_pEudemonStorage);
		m_pEudemonStorage = CNpcTrunk::CreateNew();
		IF_NOT(m_pEudemonStorage && m_pEudemonStorage->Create(idProcess, GetRecordID(), GetData(EUDEMON_STORAGE_NPC_SIZE), ITEMPOSITION_EUDEMON_STORAGE))
			return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////
bool CNpc::CreateFuncObj(PROCESS_ID idProcess)
{
	// shop
	if(IsShopNpc())
	{
		ASSERT(!m_pShop);
		m_pShop = CNpcShop::CreateNew();
		IF_NOT(m_pShop && m_pShop->Create(idProcess, this, GetRecordID()))
			return false;
	}
	if(IsAuctionNpc())
	{
		ASSERT(!m_pAuction);
/*		CAuction* temp = CAuction::CreateNew(idProcess);
		CHECKF(temp);
		m_pAuction = temp->QueryInterface();*/
		m_pAuction = CAuction::CreateNew(idProcess);
		IF_NOT(QueryAuction()->Create(idProcess,GetRecordID()))
			return false;
		//	delete temp;
	}
	if(IsTaskNpc())
	{
		ASSERT(!m_pTask);
		m_pTask = CNpcTask::CreateNew();
		IF_NOT(m_pTask && m_pTask->Create(idProcess, this, m_pData))
			return false;
	}
	if(IsSceneNpc())
	{
		CGameMap* pMap = MapManager()->QueryMap(m_pData->GetInt(NPCDATA_MAPID), false);
		if(!pMap)
			return false;

		ASSERT(!m_pScene);
		m_pScene = CNpcScene::CreateNew();
		IF_NOT(m_pScene && m_pScene->Create(this, pMap))
			return false;
	}
	if(IsLinkNpc())
	{
		ASSERT(!m_pLinkMap);
		m_pLinkMap = CNpcLink::CreateNew(m_idProcess, this);
		IF_NOT(m_pLinkMap)
			return false;
	}
	if(IsBetNpc())
	{
		ASSERT(!m_pBet);
		m_pBet = CNpcBet::CreateNew(m_idProcess, this);
		IF_NOT(m_pBet)
			return false;
	}
	if((m_pData->GetInt(NPCDATA_SORT) & NPCSORT_TABLE) != 0)
	{
		ASSERT(!m_pTable);
		m_pTable = CNpcTable::CreateNew();
		IF_NOT(m_pTable && m_pTable->Create(idProcess, this, GetRecordID()))
			return false;
	}

	return true;		//@
}

int CNpc::GetMountTypeID()
{ return IsShelfNpc() ? QueryTrunk()->QueryPackage()->GetItemType(0) : m_pData->GetInt(STATUARYDATA_HELMET); }
int CNpc::GetArmorTypeID()
{ return IsShelfNpc() ? QueryTrunk()->QueryPackage()->GetItemType(1) : m_pData->GetInt(STATUARYDATA_ARMOR); }
int CNpc::GetWeaponRTypeID()
{ return IsShelfNpc() ? QueryTrunk()->QueryPackage()->GetItemType(2) : m_pData->GetInt(STATUARYDATA_WEAPONR); }
int CNpc::GetWeaponLTypeID()
{ return IsShelfNpc() ? QueryTrunk()->QueryPackage()->GetItemType(3) : m_pData->GetInt(STATUARYDATA_WEAPONL); }
//////////////////////////////////////////////////////////////////////
void CNpc::SendShow(IRole* pRole)
{
	if(IsStatuary() || IsShelfNpc())
	{
		CMsgPlayer msg;
		IF_OK(msg.Create(QueryRole()))
			pRole->SendMsg(&msg);
	}
	else if(IsDynaNpc() && GetMaxLife() > 0)
	{
		CMsgNpcInfoEx	msg;
		IF_OK(msg.Create(this))
			pRole->SendMsg(&msg);
	}
	else
	{
		CMsgNpcInfo	msg;
		IF_OK(msg.Create(this))
			pRole->SendMsg(&msg);
	}
}

//////////////////////////////////////////////////////////////////////
// application
//////////////////////////////////////////////////////////////////////
bool CNpc::SendSelfToBlock()
{
	CHECKF(GetMap());

	if(IsStatuary() || IsShelfNpc())
	{
		CMsgPlayer msg;
		IF_OK(msg.Create(QueryRole()))
			GetMap()->BroadcastBlockMsg(QueryMapThing(), &msg);
	}
	else if(IsDynaNpc() && GetMaxLife() > 0)
	{
		CMsgNpcInfoEx	msg;
		IF_OK(msg.Create(this))
			GetMap()->BroadcastBlockMsg(QueryMapThing(), &msg);
	}
	else
	{
		CMsgNpcInfo	msg;
		IF_OK(msg.Create(this))
			GetMap()->BroadcastBlockMsg(QueryMapThing(), &msg);
	}

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CNpc::SendLeaveFromBlock()
{
	CHECKF(GetMap());

	CMsgNpc	msg;
	CHECKF(msg.Create(EVENT_LEAVEMAP, GetID()));
	GetMap()->BroadcastBlockMsg(QueryMapThing(), &msg);

	return true;
}

bool CNpc::ActivateNpc(IRole* pRole, int nAction)
{
	CUser* pUser = NULL;
	if(IsTaskNpc() && IsAlive() && pRole->QueryObj(OBJ_USER, IPP_OF(pUser)))
		return QueryTask()->ActivateTask(pUser);

	return false;
}

//////////////////////////////////////////////////////////////////////
OBJID CNpc::GetMapID()
{
	CHECKF(m_pMap);
	return m_pMap->GetID();
}

//////////////////////////////////////////////////////////////////////
void CNpc::OnTimer(time_t tCurr)
{
	if(IsAuctionNpc())
		QueryAuction()->OnTimer(tCurr);
	// auto recruit life
	//---jinggy---进行帮派每占领一周,军团声望增加50万的处理---begin
	if(this->IsSynWarLetter())  //判断是否是接收战书的NPC
	{
		if(!m_tSynWarLetter.IsActive())
			m_tSynWarLetter.Startup(SYNWARLETTERNPC_CHECKINTERVAL);
		if(m_tSynWarLetter.ToNextTime())
		{

			int nOccupyTime = this->GetData(SYNWARLETTER_OCCUPYTIME);
			time_t tTmp = nOccupyTime;
			tm * pTm = localtime(&tTmp);
			if(!pTm)
				return;
			tm	tmOccupy;	
			memset(&tmOccupy, 0, sizeof(tm));		
			tmOccupy =*pTm;
			tmOccupy.tm_mday	+= 7;			
		
			time_t	tAfterOccupy7 = mktime(&tmOccupy);

			
			time_t	tCur;		
			tCur = time(NULL);
			
			if(tCur>=tAfterOccupy7)
			{

⌨️ 快捷键说明

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