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

📄 item.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Item.cpp: implementation of the CItem class.
//
//////////////////////////////////////////////////////////////////////

#include "Item.h"
#include "ItemType.h"
#include "MapGroup.h"
#include "I_mydb.h"
#include "User.h"
#include "MsgEudemonAttrib.h"
//---jinggy---2004-11-12---Begin
#include "netmsg.h"
#include "AllMsg.h"

#define WARGHOSTVALUE_LIMIT  1024	//战魂经验值的界限
//---jinggy---2004-11-12---End

MYHEAP_IMPLEMENTATION(CItem,s_heap)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CItem::CItem()
{

	SetObjType(OBJ_ITEM);
}

//////////////////////////////////////////////////////////////////////
CItem::~CItem()
{
}

//////////////////////////////////////////////////////////////////////
bool CItem::CreateItemInfo(ItemInfoStruct& info, DWORD dwValue, CNpcType* pType, int nQuality/*=0*/)
{
	if (!pType)
		return false;

	// item quality
	DWORD dwItemQuality = 0;

	if (nQuality == 0)	
	{	// auto create this param
		int nRand = ::RandGet(100);
		if (nRand >= 0 && nRand < 30)
			dwItemQuality = 5;
		else if (nRand >= 30 && nRand <70)
			dwItemQuality = 4;
		else
			dwItemQuality = 3;
	}
	else
		dwItemQuality = nQuality;

	// item sort & item color
	DWORD dwItemSort	= 0;
	DWORD dwItemColor	= 0;
	DWORD dwItemLev		= 0;

	int nRand = ::RandGet(1200);
	if (nRand >= 0 && nRand < 20)
	{	// shoes
		dwItemSort	= 160;

		dwItemLev	= pType->GetInt(NPCTYPEDATA_DROP_SHOES);
	}
	else if (nRand >= 20 && nRand < 50)
	{	// necklace
		DWORD dwSort[2] = {120, 121};
		dwItemSort = dwSort[::RandGet(2)];

		dwItemLev	= pType->GetInt(NPCTYPEDATA_DROP_NECKLACE);
	}
	else if (nRand >= 50 && nRand < 100)
	{	// ring
		DWORD dwSort[3] = {150, 151, 152};
		dwItemSort = dwSort[::RandGet(3)];

		dwItemLev	= pType->GetInt(NPCTYPEDATA_DROP_RING);
	}
	else if (nRand >= 100 && nRand < 400)
	{	// armet
		DWORD dwSort[6] = {111, 112, 113, 114, 117, 118};
		dwItemSort = dwSort[::RandGet(6)];

		if (dwItemSort <= 118)	// have color
			dwItemColor = ::RandGet(7)+3;

		dwItemLev	= pType->GetInt(NPCTYPEDATA_DROP_ARMET);
	}
	else if (nRand >= 400 && nRand < 700)
	{	// armor
		DWORD dwSort[5] = {130, 131, 132, 133, 134};
		dwItemSort	= dwSort[::RandGet(5)];
		dwItemColor = ::RandGet(7)+3;
		dwItemLev	= pType->GetInt(NPCTYPEDATA_DROP_ARMOR);
	}
	else 
	{	// weapon & shield
		int nRate = ::RandGet(100);
		if (nRate >= 0 && nRate < 20)		// 20% for sword of Taoist
		{
			dwItemSort = 421;
		}
		else if (nRate >= 20 && nRate < 40)	// 20% for archer
		{
			// dwItemSort = 500;
			return false;
		}
		else if (nRate >= 40 && nRate < 80)	// 40% for single hand weapon
		{
			DWORD dwSort[11] = {410, 420, 421, 430, 440, 450, 460, 480, 481, 490, 500};
			dwItemSort = dwSort[::RandGet(11)];
		}
		else	// 20% for two hand weapon
		{
			DWORD dwSort[6] = {510, 530, 560, 561, 580, 900};
			dwItemSort = dwSort[::RandGet(6)];

			if (900 == dwItemSort)	// shield
				dwItemColor = ::RandGet(7)+3;
		}

		if (900 == dwItemSort)	// shield
		{
			dwItemColor = ::RandGet(7)+3;
			dwItemLev	= pType->GetInt(NPCTYPEDATA_DROP_SHIELD);
		}
		else // weapon
		{
			dwItemLev	= pType->GetInt(NPCTYPEDATA_DROP_WEAPON);
		}
	}


	// item lev
	if (dwItemLev == 99)
		return false;
		
	{
		int nRate = ::RandGet(100);
		if (nRate < 50)		// 50% down one lev
		{
			DWORD dwLev = dwItemLev;
			dwItemLev = ::RandGet(dwLev/2)+dwLev/3;

			if (dwItemLev >= 1)
				dwItemLev--;
		}
		else if (nRate >= 80)	// 20% up one lev
		{
			if ((dwItemSort >= 110 && dwItemSort <= 114) ||
					(dwItemSort >= 130 && dwItemSort <= 134) ||
						(dwItemSort >= 900 && dwItemSort <= 999))
			{	// item with color
				dwItemLev = __min(dwItemLev+1, 9);
			}
			else
			{
				dwItemLev = __min(dwItemLev+1, 23);
			}
		}

		// 50% do nothing
	}


	// item type
	OBJID idItemType = dwItemSort*1000+dwItemColor*100+dwItemLev*10+dwItemQuality;

	CItemTypeData* pItemType = ItemType()->QueryItemType(idItemType);
	if (!pItemType)
		return false;

	// fill item info
	memset(&info, 0L, sizeof(info));

	info.id			= ID_NONE;
	info.idOwner	= ID_NONE;
	info.idPlayer	= ID_NONE;
	info.idType		= idItemType;

	info.nAmountLimit	= pItemType->GetInt(ITEMTYPEDATA_AMOUNT_LIMIT)*::RandomRateGet(0.3);
	if (info.nAmountLimit < 1)
		info.nAmountLimit = 1;

	if (dwItemQuality > 5)
		info.nAmount = info.nAmountLimit*(50+::RandGet(50))/100;
	else
	{
		DWORD dwPrice = pItemType->GetInt(ITEMTYPEDATA_PRICE);
		if (dwPrice <= 0)
			dwPrice = 1;

		info.nAmount = 3*info.nAmountLimit*dwValue/dwPrice;
		if (info.nAmount >= info.nAmountLimit)
			info.nAmount = info.nAmountLimit;

		if (info.nAmount < 1)
		{
			info.nAmount = 1;
			//return false;
		}
	}

	// gem hole
	if (idItemType >= 400000 && idItemType < 599999)	
	{	// is weapon
		int nRate = ::RandGet(100);
		if (nRate < 5)			// 5% got 2 holes
		{
			info.nGem1 = 0xff;
			info.nGem2 = 0xff;
		}
		else if (nRate < 20)	// 15% got 1 hole
		{
			info.nGem1 = 0xff;
		}

		// 80% do nothing
	}

	// magic
	// to do...

	return true;
}

//////////////////////////////////////////////////////////////////////
int	CItem::CalcRepairMoney()
{
	// the highest price is about million.
	int nRecoverDurability = __max(0, GetInt(ITEMDATA_AMOUNTLIMIT) - GetInt(ITEMDATA_AMOUNT));
	
	if (nRecoverDurability == 0)
		return 0;

	// 修理价格=(持久上限-当前持久)/持久上限*商店出售价格*50%
	// 案子中没有说明当amount_limit==0的时候怎么处理,这里只好当作修理价格为0处理了
	int nRepairCost	= 0;
	if (GetInt(ITEMDATA_AMOUNTLIMIT) > 0)
		nRepairCost	= GetInt(ITEMDATA_PRICE) * nRecoverDurability / GetInt(ITEMDATA_AMOUNTLIMIT) / 2;
	
	return __max(1, nRepairCost);	// 最低修理价格为1
}

//////////////////////////////////////////////////////////////////////
DWORD CItem::GetSellPrice()
{
	if(GetInt(ITEMDATA_AMOUNTLIMIT) == 0)
		return 0;

	int nAmount = this->GetInt(ITEMDATA_AMOUNT);
	if (nAmount > this->GetInt(ITEMDATA_AMOUNTLIMIT))
		nAmount = this->GetInt(ITEMDATA_AMOUNTLIMIT);

	DWORD dwPrice = GetInt(ITEMDATA_PRICE);
	dwPrice	= dwPrice + MulDiv(dwPrice, GetQuality()*5, 100) /* + MulDiv(dwPrice, (GetInt(ITEMDATA_ADDITION)/10)*5, 100)*/ + MulDiv(dwPrice, GetInt(ITEMDATA_LUCK)*5, 100);
	dwPrice = MulDiv(dwPrice/3, nAmount, GetInt(ITEMDATA_AMOUNT_ORIGINAL));

	// ident
	if(IsNeedIdent())
		dwPrice = UNIDENT_SALE_FEE;

	if(IsArrowSort())
		dwPrice = 0;

	return dwPrice;
}

//////////////////////////////////////////////////////////////////////
CItem*	CItem::Split(int nNum)
{
	CHECKF(IsPileEnable());

	int nCurrNum = GetInt(ITEMDATA_AMOUNT);
	CHECKF(nNum > 0 && nNum < nCurrNum);

	DEBUG_TRY ////////
	CItemPtr pItem = Clone();
	CHECKF(pItem);

	pItem->SetInt(ITEMDATA_AMOUNT, nNum, UPDATE_TRUE);
	this->SetInt(ITEMDATA_AMOUNT, nCurrNum - nNum, UPDATE_TRUE);

	return pItem;
	DEBUG_CATCH("item split") //////////

	return NULL;
}

//////////////////////////////////////////////////////////////////////
CItem*	CItem::Clone()		// 新物品存数据库
{
	CItemPtr pItem = CreateNew();
	IF_NOT(pItem)
		return NULL;

	ItemInfoStruct	info;
	GetInfo(&info);
	info.id		= ID_NONE;		// new record
	if (this->IsEudemon())
	{
		ASSERT (m_pEudemonData);
		if(pItem->Create(m_pData->GetRecord(), &info, m_pEudemonData->GetRecord(), true))		// true: insert
			return pItem;
	}
	else
	{
		if(pItem->Create(m_pData->GetRecord(), &info, NULL, true))		// true: insert
			return pItem;
	}

	pItem->ReleaseByOwner();
	return NULL;
}

/*/////////////////////////////////////////////////////////////////////
int	CItem::GetItemSort()
{
	//取百万+十万位
	int nType = ITEMSORT_INVALID;
	switch((GetInt(ITEMDATA_TYPE)%10000000)/100000)
	{
	case 10:
		nType = ITEMSORT_EXPEND;
		break;

	case 1:
		{
			////取十万位+万位
			switch((GetInt(ITEMDATA_TYPE)%1000000)/10000)
			{
			case 11:
				nType = ITEMSORT_HELMET;
				break;
			case 12:
				nType = ITEMSORT_NECKLACE;
				break;
			case 13:
				nType = ITEMSORT_ARMOR;
				break;
			case 15:
				nType = ITEMSORT_RING;
				break;
			case 16:
				nType = ITEMSORT_SHOES;
				break;
			}
		}
		break;

	case 4:
		nType = ITEMSORT_WEAPON1;
		break;

	case 5:
		nType = ITEMSORT_WEAPON2;
		break;

	case 6:
		nType = ITEMSORT_MOUNT;
		break;

	case 7:
		nType = ITEMSORT_OTHER;
		break;

	case 9:
		nType = ITEMSORT_SHIELD;
		break;
	}

	return nType;
}
//*/
/*/////////////////////////////////////////////////////////////////////
int	CItem::GetItemType()
{
	int nType = ITEMTYPE_INVALID;
	//取百万+十万位
	switch((GetInt(ITEMDATA_TYPE)%10000000)/100000)
	{
	case 7:
	case 10:
		nType = ((GetInt(ITEMDATA_TYPE)%100000)/10000)*10000;	// 返回万位*万
		break;

	case 4:
	case 5:
		nType = ((GetInt(ITEMDATA_TYPE)%100000)/1000)*1000;		// 返回(万位,千位)*千
		break;

	default:
		break;
	}

	return nType;
}
//*/
//////////////////////////////////////////////////////////////////////
int	CItem::GetItemType(OBJID idType)
{
	if(GetItemSort(idType) == ITEMSORT_WEAPON1 || GetItemSort(idType) == ITEMSORT_WEAPON2) // || GetItemSort(idType) == ITEMSORT_EXPEND)
		return  ((idType%100000)/1000)*1000;		// 返回(万位,千位)*千
	else
		return  ((idType%100000)/10000)*10000;	// 返回万位*万
}
//////////////////////////////////////////////////////////////////////
int	CItem::GetItemSubType()
{
	// 取十万,万,千位
	return (GetInt(ITEMDATA_TYPE)%1000000)/1000;
}

//////////////////////////////////////////////////////////////////////
int	CItem::GetLevel(void)
{
	if (this->IsShield() || this->IsArmor() || this->IsHelmet())
		return (GetInt(ITEMDATA_TYPE)%100)/10;
	else
		return (GetInt(ITEMDATA_TYPE)%1000)/10;
}

//////////////////////////////////////////////////////////////////////
/*
 对表 cq_item 中的 type, 改变 type 的末尾就是改变装备的品质 ;
 通过 type 和 magic3 就可定位到  表 cq_itemaddition (不同品质及追加属性的装备对应的其他属性)
*/
bool CItem::ChangeType	(OBJID idNewType) //
{
	// type
	CItemTypeData *pType = ItemType()->QueryItemType(idNewType);
	if(!pType)
	{
		LOGERROR("ChangeType类型[%d]错误!", idNewType);

		return false;
	}
	
	m_pType = pType;
	this->SetInt(ITEMDATA_TYPE, idNewType);

	// TODO:这里暂时不考虑从非幻兽物品到幻兽物品的type变换
	// 否则需要读入或创建eudemon表数据
	// zlong 2005-03-02
	
	
	m_pAddition = ItemAddition()->QueryItemAddition(idNewType, GetInt(ITEMDATA_ADDITION));

	return true;
}
//////////////////////////////////////////////////////////////////////
/*
对表 cq_item 中的 magic3, 改变 type 的末尾就是改变装备的追加等级属性
*/
bool CItem::ChangeAddition(int nLevel)
{
	CItemAdditionData* pAddition = NULL;
	if (nLevel > 0)
	{
		pAddition = ItemAddition()->QueryItemAddition(this->GetInt(ITEMDATA_TYPE), nLevel);
		if (!pAddition)
			return false;
	}
	m_pAddition	= pAddition;
	this->SetInt(ITEMDATA_ADDITION, nLevel, true);
	return true;
}

//////////////////////////////////////////////////////////////////////
int	CItem::GetGemDmgEffect()
{
	int nEffect = 0;
	int nGem[2] = { this->GetInt(ITEMDATA_GEM1), this->GetInt(ITEMDATA_GEM2) };

	for (int i=0; i<2; i++)
	{
		if (nGem[i] != GEM_NONE && nGem[i] != GEM_HOLE)
		{
			OBJID idGemType = 700000 + nGem[i];
			switch(idGemType)
			{
			case GEM_DMG_LOW:
				nEffect += 5;
				break;
				
			case GEM_DMG_MID:
				nEffect += 10;
				break;
				
			case GEM_DMG_HGT:
				nEffect += 15;
				break;
			}
		}
	}
	
	return nEffect;
}

//////////////////////////////////////////////////////////////////////
int	CItem::GetGemMgcAtkEffect()
{
	int nEffect = 0;
	int nGem[2] = { this->GetInt(ITEMDATA_GEM1), this->GetInt(ITEMDATA_GEM2) };

	for (int i=0; i<2; i++)
	{
		if (nGem[i] != GEM_NONE && nGem[i] != GEM_HOLE)
		{
			OBJID idGemType = 700000 + nGem[i];
			switch(idGemType)
			{
			case GEM_MATK_LOW:
				nEffect += 5;
				break;
				
			case GEM_MATK_MID:
				nEffect += 10;
				break;
				
			case GEM_MATK_HGT:
				nEffect += 15;
				break;
			}
		}
	}
	
	return nEffect;
}

//////////////////////////////////////////////////////////////////////
int	CItem::GetGemHitRateEffect()
{
	int nEffect = 0;
	int nGem[2] = { this->GetInt(ITEMDATA_GEM1), this->GetInt(ITEMDATA_GEM2) };

	for (int i=0; i<2; i++)
	{
		if (nGem[i] != GEM_NONE && nGem[i] != GEM_HOLE)
		{
			OBJID idGemType = 700000 + nGem[i];
			switch(idGemType)
			{
			case GEM_HIT_LOW:
				nEffect += 5;
				break;
				
			case GEM_HIT_MID:
				nEffect += 10;
				break;
				
			case GEM_HIT_HGT:
				nEffect += 15;
				break;
			}
		}
	}
	
	return nEffect;
}

//////////////////////////////////////////////////////////////////////
int	CItem::GetGemExpEffect()
{
	int nEffect = 0;
	int nGem[2] = { this->GetInt(ITEMDATA_GEM1), this->GetInt(ITEMDATA_GEM2) };

	for (int i=0; i<2; i++)
	{
		if (nGem[i] != GEM_NONE && nGem[i] != GEM_HOLE)
		{
			OBJID idGemType = 700000 + nGem[i];
			switch(idGemType)
			{
			case GEM_EXP_LOW:
				nEffect += 10;
				break;
				
			case GEM_EXP_MID:
				nEffect += 15;
				break;
				
			case GEM_EXP_HGT:
				nEffect += 25;
				break;
			}
		}
	}

	return nEffect;
}

//////////////////////////////////////////////////////////////////////
int	CItem::GetGemWpnExpEffect()
{
	int nEffect = 0;
	int nGem[2] = { this->GetInt(ITEMDATA_GEM1), this->GetInt(ITEMDATA_GEM2) };

	for (int i=0; i<2; i++)
	{
		if (nGem[i] != GEM_NONE && nGem[i] != GEM_HOLE)
		{
			OBJID idGemType = 700000 + nGem[i];
			switch(idGemType)
			{
			case GEM_WPNEXP_LOW:
				nEffect += 30;
				break;
				

⌨️ 快捷键说明

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