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

📄 user_item.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 5 页
字号:
bool CUser::UseItem(OBJID idItem, int nPosition, bool bSynchro)
{
	if (!this->TryItem(idItem, nPosition))
		return false;
		
	CItemPtr pItem = GetItem(idItem);
	if(!pItem)
		return false;

	if (!ChkUseItem(pItem, this->QueryRole()))
		return false;

	if(pItem->IsActionItem() || pItem->IsGhostGem())
	{
/*
		if (pItem->IsGhostGem())
		{
			if (!(pItem->GetInt(ITEMDATA_TYPE)%100000/1000*1000 == ITEMTYPE_GHOSTGEM_PASSIVE_ATK		// 状态被动类
				|| pItem->GetInt(ITEMDATA_TYPE)%100000/1000*1000 == ITEMTYPE_GHOSTGEM_RELEASE			// 解除类
				|| pItem->GetInt(ITEMDATA_TYPE)%100000/1000*1000 == ITEMTYPE_GHOSTGEM_PROTECTIVE))		// 护身类
			{
#ifdef _DEBUG
				::LogSave("Can not use item %s [%u] to self.", pItem->GetStr(ITEMDATA_NAME), idItem);
#endif
				return false;
			}
		}
*/

		CHECKF(pItem->GetInt(ITEMDATA_ACTION));

		SetTaskItemID(pItem->GetID());
		GameAction()->ProcessAction(pItem->GetInt(ITEMDATA_ACTION), this, NULL, pItem);	//??? mast last code, may be user chgmap to another mapgroup
		return true;
	}
	/*else if (pItem->IsSpell())
	{
		int nAmount = pItem->GetInt(ITEMDATA_AMOUNT);
		// check it first
		if (nAmount <= 0)
		{
			IF_NOT (EraseItem(pItem->GetID(), SYNCHRO_TRUE))
				return false;
		}

		// process action
		OBJID idAction = pItem->GetInt(ITEMDATA_ACTION);

		pItem->SetInt(ITEMDATA_AMOUNT, --nAmount);
		if (nAmount <= 0)
		{
			ASSERT (EraseItem(pItem->GetID(), SYNCHRO_TRUE));
			pItem	= NULL;
		}
		else
		{
			pItem->SaveInfo();
			
			CMsgItemInfo msg;
			IF_OK (msg.Create(pItem, ITEMINFO_ADDITEM))
				this->SendMsg(&msg);
		}

		if (idAction != ID_NONE)
		{
			SetTaskItemID(ID_NONE);		// no more spell item operator in action
			GameAction()->ProcessAction(idAction, this, NULL, NULL);	//??? mast last code, may be user chgmap to another mapgroup
		}
		return true;
	}*/
	else if(pItem->IsEquipEnable())
		return EquipItem(pItem, nPosition, bSynchro);
	else if(pItem->IsEatEnable())
	{
		int	nAddLife	= pItem->GetInt(ITEMDATA_LIFE);
		int	nAddMana	= pItem->GetInt(ITEMDATA_MANA);

//		if(nAddLife >= MINI_ADDLIFE_DRAG && m_setSlowHealUp2Life.Size() > 1)		// 限制吃药速度
//			return false;

		DEBUG_TRY	// VVVVVVVVVVVVVV
		int nTimes = pItem->GetInt(ITEMDATA_ATKSPEED);	// 补血的次数
		IF_NOT(SpendItem(pItem))		//??? 能吃的一定能删除, 先删除,防作弊
			return false;

		// 2003.2.8 修改加血变成慢慢加。
		if(nAddLife > 0)
		{
			int nFirstAdd	= (nTimes<2) ? nAddLife : 2*nAddLife/(nTimes+1);
			int nNextAdd	= (nTimes>=2) ? (nAddLife - nFirstAdd) / (nTimes - 1) : 0;
			int nLastAdd	= nAddLife - nFirstAdd;
			if (nTimes > 2)
				nLastAdd -= nNextAdd*(nTimes - 2);

			typedef std::vector<int>	ADDLIFE_LIST;
			ADDLIFE_LIST	setAddLife;
			// first
			if (m_setSlowHealUp2Life.Size() == 0)
			{
				AddAttrib(_USERATTRIB_LIFE, nFirstAdd, SYNCHRO_TRUE);
				this->BroadcastTeamLife();
			}
			else
				setAddLife.push_back(nFirstAdd);
			if (nNextAdd > 0)
			{				
				for (int i=1; i<nTimes-1; i++)
					setAddLife.push_back(nNextAdd);
			}
			if (nLastAdd > 0)
				setAddLife.push_back(nLastAdd);

			int nMinNum = __min(setAddLife.size(), m_setSlowHealUp2Life.Size());
			for (int i=0; i<nMinNum; i++)
			{
				if (setAddLife[i] > m_setSlowHealUp2Life[i])
					m_setSlowHealUp2Life[i] = setAddLife[i];
			}
			for (i=nMinNum; i<setAddLife.size(); i++)
				m_setSlowHealUp2Life.Push(setAddLife[i]);

			m_tSlowHealLife.Update();

			// cheat check
			{
				if((IsCheater(_TYPE_WS)||IsCheater(_TYPE_FY)) && IsCheater(_TYPE_USE_LIFE) && ::RandGet(3)==0)
					KickoutCheat(_TYPE_USE_LIFE);
			}
		}
		else if (nAddLife < 0)
		{
			AddAttrib(_USERATTRIB_LIFE, nAddLife, SYNCHRO_TRUE);
			this->BroadcastTeamLife();
		}

		if(nAddMana > 0)
		{
			int nFirstAdd	= (nTimes<2) ? nAddMana : 2*nAddMana/(nTimes+1);
			int nNextAdd	= (nTimes>=2) ? (nAddMana - nFirstAdd) / (nTimes - 1) : 0;
			int nLastAdd	= nAddMana - nFirstAdd;
			if (nTimes > 2)
				nLastAdd -= nNextAdd*(nTimes - 2);
			
			typedef std::vector<int>	ADDMANA_LIST;
			ADDMANA_LIST	setAddMana;
			// first
			if (m_setSlowHealUp2Mana.Size() == 0)
			{
				AddAttrib(_USERATTRIB_MANA, nFirstAdd, SYNCHRO_TRUE);
			}
			else
				setAddMana.push_back(nFirstAdd);
			if (nNextAdd > 0)
			{				
				for (int i=1; i<nTimes-1; i++)
					setAddMana.push_back(nNextAdd);
			}
			if (nLastAdd > 0)
				setAddMana.push_back(nLastAdd);
			
			int nMinNum = __min(setAddMana.size(), m_setSlowHealUp2Mana.Size());
			for (int i=0; i<nMinNum; i++)
			{
				if (setAddMana[i] > m_setSlowHealUp2Mana[i])
					m_setSlowHealUp2Mana[i] = setAddMana[i];
			}
			for (i=nMinNum; i<setAddMana.size(); i++)
				m_setSlowHealUp2Mana.Push(setAddMana[i]);
			
			m_tSlowHealMana.Update();
			
			// cheat check
			{
				if((IsCheater(_TYPE_WS)||IsCheater(_TYPE_FY)) && IsCheater(_TYPE_USE_MANA) && ::RandGet(3)==0)
					KickoutCheat(_TYPE_USE_MANA);
			}
		}
		else if (nAddMana < 0)
		{
			AddAttrib(_USERATTRIB_MANA, nAddMana, SYNCHRO_TRUE);
		}		
		DEBUG_CATCH("UseItem") // AAAAAAAAAAAAAAAAA

		UpdateWeight();
		return true;
	}

	return false;
}

//////////////////////////////////////////////////////////////////////
bool CUser::UseItemTo(OBJID idTarget, OBJID idItem)
{
	if (idTarget == ID_NONE)
		return false;

	if (!this->TryItem(idItem, ITEMPOSITION_GHOSTGEM_PACK))
		return false;
		
	CItemPtr pItem = GetItem(idItem);
	if(!pItem)
		return false;

	// 判断是否是可以对其他角色使用的魔魂宝石
/*
	if (!(pItem->IsGhostGem()		// 魔魂宝石
			&& ((pItem->GetInt(ITEMDATA_TYPE)%100000/1000*1000 == ITEMTYPE_GHOSTGEM_ACTIVE_ATK) ||	// 状态攻击类
				(pItem->GetInt(ITEMDATA_TYPE)%100000/1000*1000 == ITEMTYPE_GHOSTGEM_TRACE)))			// 追杀类
			)
	{
#ifdef _DEBUG
	::LogSave("Can not use item %s [%u] to target.", pItem->GetStr(ITEMDATA_NAME), idItem);
#endif
		return false;
	}
*/

	IRole* pTarget = RoleManager()->QueryRole(idTarget);
	if (!pTarget)
		return false;

	if (!ChkUseItem(pItem, pTarget))
		return false;

	if(pItem->IsActionItem() || pItem->IsGhostGem())
	{
		CHECKF(pItem->GetInt(ITEMDATA_ACTION));

		SetTaskItemID(pItem->GetID());
		GameAction()->ProcessAction(pItem->GetInt(ITEMDATA_ACTION), this, pTarget, pItem);	//??? mast last code, may be user chgmap to another mapgroup
		return true;
	}

	return false;
}

//////////////////////////////////////////////////////////////////////
/*
bool CUser::UserItemToByType(OBJID idTarget, OBJID idType)
{
	if (idTarget == ID_NONE)
		return false;

	// 判断是否是可以对别人使用的魔魂宝石
	if (!(CItem::IsGhostGem(idType)
		&& ((idType%100000/1000*1000 == ITEMTYPE_GHOSTGEM_ACTIVE_ATK)	// 状态攻击类
			|| (idType%100000/1000*1000 == ITEMTYPE_GHOSTGEM_TRACE))			// 追杀类
		))
	{
#ifdef _DEBUG
		::LogSave("Can not use itemtype [%u] to target.", idType);
#endif
		return false;
	}

	IRole* pTarget = RoleManager()->QueryRole(idTarget);
	if (!pTarget)
		return false;

	CItemTypeData* pItemType = ItemType()->QueryItemType(idType);
	if (pItemType && pItemType->GetInt(ITEMTYPEDATA_ACTION))
	{
//		SetTaskItemID(pItem->GetID());
		GameAction()->ProcessAction(pItemType->GetInt(ITEMTYPEDATA_ACTION), this, pTarget, NULL);	//??? mast last code, may be user chgmap to another mapgroup
		return true;
	}

	return false;
}
*/

//////////////////////////////////////////////////////////////////////
bool CUser::UnEquipItem(int nPosition, bool bSynchro)
{
	if(!( nPosition >= ITEMPOSITION_EQUIPBEGIN && nPosition < ITEMPOSITION_EQUIPEND ))
		return false;

	if (QueryMagic())
		QueryMagic()->AbortMagic();

	CItem* pEquip = GetEquipItemByPos(nPosition);
	if(!pEquip)
		return false;

	if(nPosition == ITEMPOSITION_WEAPONR && m_pWeaponL && (m_pWeaponL->IsShield() || m_pWeaponL->IsArrowSort()))
	{
		if(!IsBackPackSpare(2, 0, ID_NONE, ITEMPOSITION_BACKPACK))
			return false;
	}
	else
	{
		if(!IsBackPackSpare(1, 0, ID_NONE, ITEMPOSITION_BACKPACK))
			return false;
	}

	CItemPtr pItem = UnEquipOnly(nPosition);
	CHECKF(pItem);

	
	//---jinggy---2004-11-19--启动设备经验值记数器---begin
	UpdateEquipmentExp_Stop(nPosition);
	//---jinggy---2004-11-19--启动设备经验值记数器---end

	// 无右手武器
	if(!m_pWeaponR && m_pWeaponL)
	{
		if(m_pWeaponL->IsWeapon1())
		{
			m_pWeaponR = m_pWeaponL;
			m_pWeaponL = NULL;
		}
		else if(m_pWeaponL->IsShield() || m_pWeaponL->IsArrowSort())
		{
			UnEquipOnly(ITEMPOSITION_WEAPONL);
		}
	}

	if(bSynchro)
	{
		CMsgItem msg;
		if(msg.Create(pItem->GetID(), ITEMACT_UNEQUIP, nPosition))
			this->SendMsg(&msg);

		if(nPosition == ITEMPOSITION_HELMET
				|| nPosition == ITEMPOSITION_ARMOR
				|| nPosition == ITEMPOSITION_WEAPONR
				|| nPosition == ITEMPOSITION_WEAPONL
				|| nPosition == ITEMPOSITION_MANTLE )
		{
			CMsgPlayer msgPlayer;
			if (msgPlayer.Create(this->QueryRole()))
				this->BroadcastRoomMsg(&msgPlayer, EXCLUDE_SELF);
		}
	}

	if(GetMana() > GetMaxMana())
		SetAttrib(_USERATTRIB_MANA, GetMaxMana(), SYNCHRO_TRUE);

//	UpdateWeight();
	CalcFightRate();
	return true;
}

//////////////////////////////////////////////////////////////////////
CItem* CUser::UnEquipOnly(int nPosition)
{
	//CHECKF(m_setItem.size() < _MAX_USERITEMSIZE);

	CItem* pItem = NULL;
	CItemPtr& refpEquip = GetEquipItemRef(nPosition);
	if (refpEquip == NULL)
		return NULL;

	CHECKF(!m_pPackage->IsPackFull(refpEquip));

//	if(nPosition == ITEMPOSITION_WEAPONR)
//		QueryStatusSet()->DelObj(STATUS_KEEPBOW);

	if(refpEquip)
	{
		pItem = refpEquip;
		//pItem->SetInt(ITEMDATA_POSITION, ITEMPOSITION_BACKPACK);
		//m_setItem.push_back(pItem);
		m_pPackage->AddItem(pItem);

		refpEquip = NULL;

	}

	UnequipMagicItem(nPosition);
	return pItem;
}

//////////////////////////////////////////////////////////////////////
// msgitem
//////////////////////////////////////////////////////////////////////
void CUser::BuyItem (OBJID idNpc, OBJID idType)
{
	CNpc* pNpc; 
	if(!GetMap()->QueryObj(GetPosX(), GetPosY(), OBJ_NPC, idNpc, IPP_OF(pNpc)))
		return ;
	if(!pNpc->IsShopNpc())
		return;
	if(!pNpc->QueryShop()->IsOpen())
		return;

	CItemTypeData* pType = pNpc->QueryShop()->QueryItemType(idType);
	IF_NOT (pType)
		return;

	int nPrice = pType->GetInt(ITEMTYPEDATA_PRICE);
	nPrice = pNpc->QueryShop()->Rebate(nPrice, GetSynID(), GetSynRankShow());

	//---jinggy---过是向帮派NPC买东西,帮派成员有优惠---begin	
/*	
	CGameMap * pSynMap = this->GetMap();
    //1%给帮派基金
	int nSynGainMoney = MulDiv(nPrice,1, 100);
	CSyndicate * pSyn = SynManager()->QuerySyndicate(pSynMap->GetSynID());
	if(pSyn)
	{
		pSyn->QueryModify()->AddData(SYNDATA_MONEY,nSynGainMoney,true);
	}

*/
	//---jinggy---过是向帮派NPC买东西,帮派成员有优惠---end


	if(this->GetMoney() < nPrice)
	{
		this->SendSysMsg(STR_NOT_SO_MUCH_MONEY);
		return;
	}

	if(!AwardItem(idType, SYNCHRO_TRUE, CUser::IDENT_OK))
	{
//		this->SendSysMsg("您身上带不了这么多东西!");
		return;
	}

	ASSERT(this->SpendMoney(nPrice, SYNCHRO_TRUE));
	UpdateWeight();
}

//////////////////////////////////////////////////////////////////////
void CUser::SellItem(OBJID idNpc, OBJID idItem)
{
	CNpc* pNpc; 
	if(!GetMap()->QueryObj(GetPosX(), GetPosY(), OBJ_NPC, idNpc, IPP_OF(pNpc)))
		return ;
	if(!pNpc->IsShopNpc())
		return;

	CItemPtr pItem = this->GetItem(idItem);
	if(!pItem)
	{
		this->SendSysMsg(STR_ITEM_NOT_FOUND);
		return;
	}

	if (!pItem->IsSellEnable())
	{
		this->SendSysMsg(STR_NOT_SELL_ENABLE);
		return;
	}

	if (pItem->IsNonsuchItem())
	{
		::MyLogSave("gmlog/sell_item", "%s(%u) sell item:[id=%u, type=%u], dur=%d, max_dur=%d", 
				this->GetName(),
				this->GetID(),
				pItem->GetID(), 
				pItem->GetInt(ITEMDATA_TYPE),
				pItem->GetInt(ITEMDATA_AMOUNT),
				pItem->GetInt(ITEMDATA_AMOUNTLIMIT));
	}

	DEBUG_TRY	// VVVVVVVVVVVVVV
	DWORD	dwMoney = pItem->GetSellPrice();
	if(!this->EraseItem(idItem, SYNCHRO_TRUE))			//??? 先删除物品,以防作弊
	{
		this->SendSysMsg(STR_ITEM_INEXIST);
		return;
	}

	if(!this->GainMoney(dwMoney, SYNCHRO_TRUE))
		this->SendSysMsg(STR_MONEYBAG_FULL);
	DEBUG_CATCH("SellItem") // AAAAAAAAAAAAAAAAA

	UpdateWeight();
}

//////////////////////////////////////////////////////////////////////
bool CUser::DropItem(OBJID idItem, int x, int y)
{
	CHECKF(GetMap()->IsLayItemEnable(x, y));

	ItemInfoStruct info;
	CItemPtr pItem = NULL;
	bool	bDropItem = false;
	int i;
	for(i = ITEMPOSITION_EQUIPBEGIN; i < ITEMPOSITION_EQUIPEND; i++)
	{
		CItemPtr& refpEquip = GetEquipItemRef(i);

		if(refpEquip && refpEquip->GetID() == idItem)
		{
			// inform client the equipment is droped.
			CMsgItem msg;
			if (msg.Create(refpEquip->GetID(), ITEMACT_DROPEQUIPMENT, i))
				this->SendMsg(&msg);

			char szPrompt[255];
			sprintf(szPrompt,STR_DROPITEM_PROMPT,refpEquip->GetStr(ITEMDATA_NAME));			
			this->SendSysMsg(szPrompt);

			pItem	= refpEquip;
			refpEquip	= NULL;

			// 丢弃幻兽要扣亲密度
			if (pItem->IsEudemon())
			{
				CallBackEudemon(pItem->GetID());
				DetachEudemon(pItem);
				int nFidelity = __max(0, pItem->GetInt(ITEMDATA_FIDELITY) - EUDEMON_DEC_FIDELITY_WHEN_DEAL);
				pItem->SetInt(ITEMDATA_FIDELITY, nFidelity);
			}
			//丢弃物品重新设置战魂经验值
			pItem->WarGhostLevelReset();

⌨️ 快捷键说明

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