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

📄 user_item.cpp

📁 魔域的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	//根据品质计算转换为鉴定的成功概率
	int  nQuality = pItem->GetQuality();
	int  nRate=0;
	if(nQuality==QUALITY_ZERO)
		nRate = 80;
	else if(nQuality==QUALITY_ONE||nQuality==QUALITY_TWO)
		nRate = 70;
	else if(nQuality==QUALITY_THREE||nQuality==QUALITY_FOUR)
		nRate = 50;
	
	int	nMoney	= IDENT_FEE;		// MulDiv(pItem->GetInt(ITEMDATA_PRICE), ITEMIDENT_PERCENT, 100);
	// 钱不够
	if(nMoney && GetMoney() < nMoney)
		return false;	
	if(nMoney)
		this->SpendMoney(nMoney, SYNCHRO_TRUE);

	if(::RandGet(100) < nRate)
	{
		pItem->SetIdent(0, UPDATE_FALSE);

		char szBuff[255];
		if(nQuality==QUALITY_ZERO)
			sprintf(szBuff,STR_IDENT_NORMAL,pItem->GetStr(ITEMDATA_NAME));
		else if(nQuality==QUALITY_ONE)
			sprintf(szBuff,STR_IDENT_QUALITY_ONE, pItem->GetStr(ITEMDATA_NAME));
		else if(nQuality==QUALITY_TWO)
			sprintf(szBuff,STR_IDENT_QUALITY_TWO, pItem->GetStr(ITEMDATA_NAME));
		else if(nQuality==QUALITY_THREE)
			sprintf(szBuff,STR_IDENT_QUALITY_THREE, pItem->GetStr(ITEMDATA_NAME));
		else if(nQuality==QUALITY_FOUR)
			sprintf(szBuff,STR_IDENT_QUALITY_FOUR, pItem->GetStr(ITEMDATA_NAME));
		
		this->SendSysMsg(szBuff);

		if(bSynchro)
		{
			CMsgItemInfo	msg;
			CHECKF(msg.Create(pItem));
			SendMsg(&msg);
		}
		return true;
	}		
	else
	{
		//鉴定失败
		if(nQuality==QUALITY_ZERO)
			nRate = 70;
		else if(nQuality==QUALITY_ONE||nQuality==QUALITY_TWO)
			nRate = 50;
		else if(nQuality==QUALITY_THREE||nQuality==QUALITY_FOUR)
			nRate = 30;
		if(::RandGet(100) < nRate)
		{
			this->EraseItem(idItem,true);
			SendSysMsg(STR_ACTION_IDENT_FAIL_DISAPPEAR);
		}
		else
		{
			SendSysMsg(STR_ACTION_IDENT_FAIL);
		}		
		return false;
	}
}				


//////////////////////////////////////////////////////////////////////
void CUser::EmbedGem (OBJID idItem, OBJID idGem, int nPos)
{
	CItem* pItem = this->GetItem(idItem);
	IF_NOT (pItem)
		return;

	CItem* pGem	= this->GetItem(idGem);
	IF_NOT (pGem)
		return;
 
	nPos = __min(2, __max(1, nPos));

	ItemInfoStruct info;
	pItem->GetInfo(&info);

	switch(nPos)
	{
	case 1:
		{
			IF_OK (GEM_HOLE == info.nGem1)
			{
				pItem->SetInt(ITEMDATA_GEM1, pGem->GetInt(ITEMDATA_TYPE)%1000);

				int nDurEffect = pItem->GetGemDurEffect(pGem->GetInt(ITEMDATA_TYPE));
				if (nDurEffect != 0)
				{
					int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
					pItem->SetInt(ITEMDATA_AMOUNTLIMIT, nDur*(100+nDurEffect)/100);
				}

				DEBUG_TRY		// VVVVVVVVVV
				pItem->SaveInfo();
				ASSERT(EraseItem(idGem, SYNCHRO_TRUE));
				DEBUG_CATCH("EmbedGem2")		// AAAAAAAAAAA
			}
		}
		break;

	case 2:
		{
			IF_OK (GEM_HOLE == info.nGem2)
			{
				pItem->SetInt(ITEMDATA_GEM2, pGem->GetInt(ITEMDATA_TYPE)%1000);

				int nDurEffect = pItem->GetGemDurEffect(pGem->GetInt(ITEMDATA_TYPE));
				if (nDurEffect != 0)
				{
					int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
					pItem->SetInt(ITEMDATA_AMOUNTLIMIT, nDur*(100+nDurEffect)/100);
				}

				DEBUG_TRY		// VVVVVVVVVV
				pItem->SaveInfo();
				ASSERT(EraseItem(idGem, SYNCHRO_TRUE));
				DEBUG_CATCH("EmbedGem2")		// AAAAAAAAAAA
			}
		}
		break;

	default:
		{
			::LogSave("invalid pos:%u in gem embed.", nPos);
			return;
		}
		break;
	}

	// update item info at client
	CMsgItemInfo msg;
	IF_OK (msg.Create(pItem, ITEMINFO_UPDATE))
		this->SendMsg(&msg);
}

//////////////////////////////////////////////////////////////////////
void CUser::TakeOutGem (OBJID idItem, int nPos)
{
	CItem* pItem = this->GetItem(idItem);
	IF_NOT (pItem)
		return;

	nPos = __min(2, __max(1, nPos));

	ItemInfoStruct info;
	pItem->GetInfo(&info);

	switch(nPos)
	{
	case 1:
		{
			IF_OK (GEM_NONE != info.nGem1 && GEM_HOLE != info.nGem1)
			{
				pItem->SetInt(ITEMDATA_GEM1, GEM_HOLE);

				// correct dur
				OBJID idGemType = 700000+info.nGem1;
				int nDurEffect = pItem->GetGemDurEffect(idGemType);
				if (nDurEffect != 0)
				{
					int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
					pItem->SetInt(ITEMDATA_AMOUNTLIMIT, __max(0, nDur*100/(100+nDurEffect)));

					if (pItem->GetInt(ITEMDATA_AMOUNT) > pItem->GetInt(ITEMDATA_AMOUNTLIMIT))
						pItem->SetInt(ITEMDATA_AMOUNT, pItem->GetInt(ITEMDATA_AMOUNTLIMIT));
				}

				pItem->SaveInfo();
			}
		}
		break;

	case 2:
		{
			IF_OK (GEM_NONE != info.nGem2 && GEM_HOLE != info.nGem2)
			{
				pItem->SetInt(ITEMDATA_GEM2, GEM_HOLE);

				// correct dur
				OBJID idGemType = 700000+info.nGem2;
				int nDurEffect = pItem->GetGemDurEffect(idGemType);
				if (nDurEffect != 0)
				{
					int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
					pItem->SetInt(ITEMDATA_AMOUNTLIMIT, __max(0, nDur*100/(100+nDurEffect)));

					if (pItem->GetInt(ITEMDATA_AMOUNT) > pItem->GetInt(ITEMDATA_AMOUNTLIMIT))
						pItem->SetInt(ITEMDATA_AMOUNT, pItem->GetInt(ITEMDATA_AMOUNTLIMIT));
				}

				pItem->SaveInfo();
			}
		}
		break;

	default:
		{
			::LogSave("invalid pos:%u in gem take out.", nPos);
			return;
		}
		break;
	}

	// update item info at client
	CMsgItemInfo msg;
	IF_OK (msg.Create(pItem, ITEMINFO_UPDATE))
		this->SendMsg(&msg);
}

//////////////////////////////////////////////////////////////////////
void CUser::UpdateWeight()
{
	m_bUpdateWeight	= true;
}

//////////////////////////////////////////////////////////////////////
bool CUser::Court	(OBJID idTarget)
{
	if (this->IsMarried())
		return false;

	CUser* pTargetUser = this->FindAroundUser(idTarget);
	if (!pTargetUser)
		return false;
		
	if (this->GetSex() == pTargetUser->GetSex())
		return false;
	
	this->SetApply(CUser::APPLY_MARRY, idTarget);

	CMsgInteract msg;
	IF_OK (msg.Create(INTERACT_COURT, this->GetID(), idTarget, 0, 0))
		pTargetUser->SendMsg(&msg);

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CUser::Marry	(OBJID idTarget)
{
	if (this->IsMarried())
		return false;

	CUser* pTargetUser = this->FindAroundUser(idTarget);
	if (!pTargetUser)
		return false;
			
	if (pTargetUser->FetchApply(CUser::APPLY_MARRY) != this->GetID())
		return false;
	
	this->UpdateMate(pTargetUser->GetName(), true);
	pTargetUser->UpdateMate(this->GetName(), true);

	// boradcast msg 
	MSGBUF szMsg;
	sprintf(szMsg, STR_MARRY, this->GetName(), pTargetUser->GetName());

	CMsgTalk msg;
	IF_OK_ (msg.Create(SYSTEM_NAME, ALLUSERS_NAME, szMsg, NULL, 0xff0000, _TXTATR_GM))
		UserManager()->BroadcastMsg(&msg);

	// fireworks
	{
		CMsgItem msg;
		IF_OK (msg.Create(this->GetID(), ITEMACT_FIREWORKS))
			this->BroadcastRoomMsg(&msg, true);
	}

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CUser::Divorce	(void)
{
	if (!this->IsMarried())
		return false;
		
	CUser* pMate = UserManager()->GetUser(this->GetMate());

	IDatabase* pDb = Database();
	IF_OK (pDb)
	{
		char szSQL[1024] = "";
		sprintf(szSQL, "INSERT INTO %s SELECT 0,%u,user.id,user.id,0,0,0,%u,0,0,0,0,0,0 FROM %s AS user where user.name='%s'",
						_TBL_ITEM,
						TYPE_DIVOICEITEM, ITEMPOSITION_BACKPACK, _TBL_USER, this->GetMate());

		IF_NOT (pDb->ExecuteSQL(szSQL))
			return false;
	}
	
	MSGBUF szMsg;
	sprintf(szMsg, STR_DIVORCE, this->GetName(), this->GetMate());
	this->BroadcastRoomMsg(szMsg, true);

	if (pMate)
		pMate->UpdateMate(NOMATE_NAME, true);
	else
	{
		char szSQL[1024] = "";
		sprintf(szSQL, "UPDATE %s SET mate='%s' WHERE name='%s' LIMIT 1", _TBL_USER, NOMATE_NAME, this->GetMate());
		pDb->ExecuteSQL(szSQL);
	}

	this->UpdateMate(NOMATE_NAME, true);
	return true;
}

//////////////////////////////////////////////////////////////////////
void CUser::UpdateMate	(const char* pszName, bool bUpdate/* = true*/)
{
	IF_NOT (pszName && strlen(pszName) < _MAX_NAMESIZE)
		return;

	m_data.SetMate(pszName, true);
	if (bUpdate)
	{
		CMsgName msg;
		IF_OK (msg.Create(NAMEACT_MATE, pszName, this->GetID()))
			this->SendMsg(&msg);
	}
}

//////////////////////////////////////////////////////////////////////
bool CUser::IsMarried(void)
{
	const char* pszMate = this->GetMate();
	return (0 != strcmp(pszMate, NOMATE_NAME));
}

//////////////////////////////////////////////////////////////////////
bool CUser::IsMate(CUser* pUser)
{
	IF_NOT (pUser)
		return false;

	return (0 == strcmp(this->GetMate(), pUser->GetName()));
}

//////////////////////////////////////////////////////////////////////
void CUser::UpdateEquipmentDurability(void)
{
	for(int i = ITEMPOSITION_EQUIPBEGIN; i < ITEMPOSITION_EQUIPEND; i++)
	{
		if (i == ITEMPOSITION_RINGR || 
				i == ITEMPOSITION_RINGL ||
					i == ITEMPOSITION_WEAPONR ||
						i == ITEMPOSITION_WEAPONL)
			continue;

		this->AddEquipmentDurability(i, -1);
	}
}

//////////////////////////////////////////////////////////////////////
void CUser::AddEquipmentDurability(int nPosition, int nAddValue)
{
	ASSERT(nAddValue < 0);

	CItemPtr& refpEquip = this->GetEquipItemRef(nPosition);
	if (!refpEquip || refpEquip->IsExpend() || refpEquip->IsNeverWear())
		return;

	int nOldDur	= refpEquip->GetInt(ITEMDATA_AMOUNT);
	int nDurability = __max(0, refpEquip->GetInt(ITEMDATA_AMOUNT)+nAddValue);
	refpEquip->SetInt(ITEMDATA_AMOUNT, nDurability);

	if (nDurability < 100)
	{
		if ((nDurability%10) == 0)
			this->SendSysMsg(_TXTATR_GM, STR_DAMAGED_REPAIR, refpEquip->GetStr(ITEMDATA_NAME));
	}	
	else if (nDurability < 200)
	{
		if ((nDurability%20) == 0)
			this->SendSysMsg(_TXTATR_GM, STR_DURABILITY_REPAIR, refpEquip->GetStr(ITEMDATA_NAME));
	}
	
	if (nOldDur/100 != nDurability/100 
			|| nDurability <= 0)	// should update info to client (nDurability%100) == 0
	{
		CMsgItem msg;	// if nDurability equal zero, the client will auto delete this equipment
		if (msg.Create(nPosition, ITEMACT_DURABILITY, nDurability))
			this->SendMsg(&msg);
		
		if (nDurability == 0 && !refpEquip->IsMount()) // this equipment is damaged
		{
			::MyLogSave("gmlog/wareout_item", "%s(%u) wear out item:[id=%u, type=%u], dur=%d, max_dur=%d", 
					this->GetName(),
					this->GetID(),
					refpEquip->GetID(), 
					refpEquip->GetInt(ITEMDATA_TYPE),
					refpEquip->GetInt(ITEMDATA_AMOUNT),
					refpEquip->GetInt(ITEMDATA_AMOUNTLIMIT));

			EraseEquip(nPosition, SYNCHRO_TRUE);
/*
			CMsgItem msg;
			if (msg.Create(refpEquip->GetID(), ITEMACT_DROPEQUIPMENT, nPosition))
				this->SendMsg(&msg);
			
			refpEquip->DeleteRecord();
			refpEquip->ReleaseByOwner();
			refpEquip = NULL;

			CMsgPlayer msgPlayer;
			if (msgPlayer.Create(this->QueryRole()))
				this->BroadcastRoomMsg(&msgPlayer, EXCLUDE_SELF);
*/
		}
		else
			refpEquip->SaveInfo();
	}
}

//////////////////////////////////////////////////////////////////////
int CUser::GetWeight()
{
	if(m_bUpdateWeight)
	{
		m_nAllWeight = 0;
		if(m_pHelmet)
			m_nAllWeight	+= m_pHelmet->GetWeight();
		if(m_pNecklace)
			m_nAllWeight	+= m_pNecklace->GetWeight();
		if(m_pArmor)
			m_nAllWeight	+= m_pArmor->GetWeight();
		if(m_pWeaponR)
			m_nAllWeight	+= m_pWeaponR->GetWeight();
		if(m_pWeaponL)
			m_nAllWeight	+= m_pWeaponL->GetWeight();
		if(m_pRingR)
			m_nAllWeight	+= m_pRingR->GetWeight();
		if(m_pRingL)
			m_nAllWeight	+= m_pRingL->GetWeight();
		if(m_pShoes)
			m_nAllWeight	+= m_pShoes->GetWeight();
		if(m_pMount)
			m_nAllWeight	+= m_pMount->GetWeight();
		if(m_pSprite)
			m_nAllWeight	+= m_pSprite->GetWeight();
		if(m_pMantle)
			m_nAllWeight	+= m_pMantle->GetWeight();

		m_nAllWeight	+= m_pPackage->GetWeight();

		m_bUpdateWeight = false;
	}

	return m_nAllWeight;
}

//////////////////////////////////////////////////////////////////////
bool CUser::PickMapItem(OBJID idItem)
{
	CMapItem* pMapItem = MapManager()->QueryMapItem(idItem);
	if (!pMapItem)
		return false;

	if (this->GetDistance(pMapItem->QueryMapThing()) > PICKMAPITEMDIST_LIMIT)
	{
		this->SendSysMsg(STR_FAR_CANNOT_PICK);
		return false;
	}

	if (!pMapItem->IsMoney() && 
		this->IsItemFull(pMapItem->GetWeight(), pMapItem->GetType(), pMapItem->GetInfo()->nAmountLimit))
	{
		if (CItem::IsGhostGem(pMapItem->GetType()))
			this->SendSysMsg(STR_GEMBAG_FULL);
		else
			this->SendSysMsg(STR_FULL_CANNOT_PICK);
		return false;
	}

	OBJID idOwner = pMapItem->GetPlayerID();
	if (pMapItem->IsPriv() && idOwner != GetID())
	{
		CUser* pOwner = UserManager()->GetUser(idOwner);
		if (!(pOwner && this->IsMate(pOwner)))
		{
			CTeam* pTeam = this->GetTeam();
			if (pTeam && pTeam->IsTeamMember(idOwner)
					&& (pMapItem->IsMoney() && !pTeam->IsCloseMoney() || !pMapItem->IsMoney() && !pTeam->IsCloseItem() || pMapItem->IsGem() && !pTeam->IsCloseGemAccess())
					&& !(pMapItem->GetType() == TYPE_DRAGONBALL || pMapItem->GetType() == TYPE_SHOOTINGSTAR) )
			{
				
				
			}
			else
			{
				SendSysMsg(STR_OTHERS_ITEM);
				return false;
			}
		}
	}

	if (pMapItem->IsMoney())
	{
		int	nMoney = pMapItem->GetAmount();
		if (this->GetMoney() + nMoney > _MAX_MONEYLIMIT)
		{
			Se

⌨️ 快捷键说明

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