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

📄 inventorymgr.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			}
		}
	}

	if (emptyslot == -1)	// No empty slots, if we don't already have it return
	{
		if (!bAlreadyHave)
			return CHWEAP_NOAVAILSLOTS;
	}

	// Create the item
	if (!bAlreadyHave)
	{
		switch(nSpellType)
		{
			case SPELL_STONE:
				item = new CInvSpellStone;
				break;

			case SPELL_SHIELD:
				item = new CInvSpellShield;
				break;

			case SPELL_REFLECTION:
				item = new CInvSpellReflection;
				break;

			case SPELL_AURA:
				item = new CInvSpellAura;
				break;

			case SPELL_DARKNESS:
				item = new CInvSpellDarkness;
				break;

			case SPELL_DOUBLE:
				item = new CInvSpellDouble;
				break;

			case SPELL_HEAL:
				item = new CInvSpellHeal;
				break;

//			case SPELL_ILLUSION
//				item = new CInvSpellIllusion;
//				break;

			case SPELL_SPEED:
				item = new CInvSpellSpeed;
				break;

			case SPELL_TELEPORT:
				item = new CInvSpellTeleport;
				break;

			default: return CHWEAP_NOMESSAGE;
		}
		m_InvSpells[emptyslot] = item;
		item->Init(m_hOwner);
	}
	else	// Try to add more of this item
	{
		return CHWEAP_ALREADYHAVE;
	}
	SendClientItemMsg(SMSG_NEWITEM, nSpellType);
	return CHWEAP_OK;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::SetActiveSpell()
//
//	PURPOSE:	Sets the active spell
//
// ----------------------------------------------------------------------- //

int CInventoryMgr::SetActiveSpell(DBYTE nSpellSlot)
{
	if(nSpellSlot < 0 || nSpellSlot >= SLOTCOUNT_SPELLS)
		return CHWEAP_NOTAVAIL;

	_mbscpy((unsigned char*)msgbuf, (const unsigned char*)"");

	CInvItem *pInvSpell = m_InvSpells[nSpellSlot];
	if (!pInvSpell) return CHWEAP_NOTAVAIL;

	pInvSpell->ActivateItem(msgbuf);

	if (_mbstrlen(msgbuf))
		SendConsoleMessageToClient(msgbuf);
		
	return CHWEAP_OK;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::DeleteSpell(DBYTE slot)
//
//	PURPOSE:	Spawns an Item at the client location
//
// ----------------------------------------------------------------------- //
int CInventoryMgr::DeleteSpell(DBYTE slot)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	CInvItem *sToDrop = m_InvSpells[slot];

	if(!sToDrop)	return	0;
	RemoveSpell(sToDrop->GetType());
	sToDrop = NULL;
	return	1;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::RemoveSpell()
//
//	PURPOSE:	Remove an Item
//
// ----------------------------------------------------------------------- //
int CInventoryMgr::RemoveSpell(DBYTE nSpellType)
{
	if(nSpellType < INV_BASESPELL || nSpellType > INV_LASTSPELL)
		return CHWEAP_NOTAVAIL;

	CInvItem	*item;
	for (int i=0; i < SLOTCOUNT_SPELLS; i++)
	{
		item = m_InvSpells[i];
		if (item && (item->GetType() == nSpellType) )		// See if we already have it..
		{
			item->Term();
			delete item;
			m_InvSpells[i] = NULL;
			break;
		}
	}
	SendClientItemMsg(SMSG_REMOVEITEM, nSpellType);
    return  CHWEAP_OK;
}    
*/

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::SetAmmoCount()
//
//	PURPOSE:	Sets the ammo value
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::SetAmmoCount(DBYTE nAmmoType, DFLOAT fAmmoCount)
{
	CInvItem *pInvItem = DNULL;
	CWeapon *pWeapon;
	CServerDE* pServerDE = BaseClass::GetServerDE();

	if(nAmmoType <= AMMO_NONE || nAmmoType > AMMO_MAXAMMOTYPES)
		return;

	// Don't allow ammo changes in infinite mode
	if (m_bInfiniteAmmo)
		return;

	m_fAmmo[nAmmoType] = fAmmoCount;

	// If it's Mana and less than max, start the recharge timer
	if (nAmmoType == AMMO_FOCUS )
	{
		DBYTE nMagic = m_nAttribMagic - 1;
		CLIPLOWHIGH(nMagic, 0, 5);
	}

	// If out of ammo, remove inventory item from weapons that have them...
	if( fAmmoCount <= 0.0f )
	{
		int nInvItem;

		pWeapon = DNULL;
		switch( nAmmoType )
		{
			case AMMO_PROXIMITYBOMB:
				nInvItem = INV_PROXIMITY;
				pWeapon = GetWeapon( nInvItem - INV_BASEINVWEAPON + SLOTCOUNT_WEAPONS );
				break;
			case AMMO_REMOTEBOMB:
				nInvItem = INV_REMOTE;
				pWeapon = GetWeapon( nInvItem - INV_BASEINVWEAPON + SLOTCOUNT_WEAPONS );
				break;
			case AMMO_TIMEBOMB:
				nInvItem = INV_TIMEBOMB;
				pWeapon = GetWeapon( nInvItem - INV_BASEINVWEAPON + SLOTCOUNT_WEAPONS );
				break;
			default:
				nInvItem = -1;
				break;
		}

		if( nInvItem != -1 )
		{
 			RemoveItem( nInvItem );
			if( pWeapon )
				pWeapon->Holster( );
		}
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::SendPickedUpMessage()
//
//	PURPOSE:	Tells an object that we picked it up
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::SendPickedUpMessage(HOBJECT hObject, int iRet)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();

	// Tell the item we picked it up
	if (iRet == CHWEAP_OK)
	{
		HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject((LPBASECLASS)this, hObject, MID_PICKEDUP);
		pServerDE->WriteToMessageFloat(hMessage, -1.0f);
		pServerDE->EndMessage(hMessage);
	}

	// Display an appropriate client message
	if (m_hClient)
	{
		HCLASS hObjectClass = pServerDE->GetObjectClass(hObject);

		if(pServerDE->IsKindOf(hObjectClass, pServerDE->GetClass("PickupObject"))) 
		{
			PickupObject *pObj = (PickupObject*)pServerDE->HandleToObject(hObject);
			if (pObj)
			{
				char *szObject = pServerDE->GetStringData(pObj->GetDisplayName());
				_mbscpy((unsigned char*)msgbuf, (const unsigned char*)"");
				switch(iRet)
				{
					case CHWEAP_OK:
					{
						HSTRING hstr = pServerDE->FormatString(IDS_GENERAL_PICKUP_1, szObject);
						char *pszTemp = pServerDE->GetStringData(hstr);
						if( pszTemp )
							_mbscpy((unsigned char*)msgbuf, (const unsigned char*)pszTemp );
						pServerDE->FreeString(hstr);
//						sprintf(msgbuf, "Picked Up %s", szObject);
						break;
					}
/*
					case CHWEAP_NOTENOUGHSTRENGTH:
						if (hObject != m_hLastPickupObject && iRet != m_nLastPickupResult)
							sprintf(msgbuf, "Not Enough Strength for %s", szObject);
						break;
					case CHWEAP_NOTENOUGHMAGIC:
						if (hObject != m_hLastPickupObject && iRet != m_nLastPickupResult)
							sprintf(msgbuf, "Not Enough Magic for %s", szObject);
						break;
*/
					case CHWEAP_NOTAVAIL:
						if (hObject != m_hLastPickupObject && iRet != m_nLastPickupResult)
						{
							HSTRING hstr = pServerDE->FormatString(IDS_GENERAL_PICKUP_2, szObject);
							char *pszTemp = pServerDE->GetStringData(hstr);
							if( pszTemp )
								_mbscpy((unsigned char*)msgbuf, (const unsigned char*)pszTemp);
							pServerDE->FreeString(hstr);
//							sprintf(msgbuf, "%s Not Available", szObject);
						}
						break;
					case CHWEAP_NOAVAILSLOTS:
						if (hObject != m_hLastPickupObject && iRet != m_nLastPickupResult)
						{
							HSTRING hstr = pServerDE->FormatString(IDS_GENERAL_PICKUP_3, szObject);
							char *pszTemp = pServerDE->GetStringData(hstr);
							if( pszTemp )
								_mbscpy((unsigned char*)msgbuf, (const unsigned char*)pszTemp );
							pServerDE->FreeString(hstr);
//							sprintf(msgbuf, "No Available Slots for %s", szObject);
						}
						break;
				}

				if (_mbstrlen(msgbuf))
					SendConsoleMessageToClient(msgbuf);
		
				m_hLastPickupObject = hObject;
				m_nLastPickupResult = iRet;
			}
		}
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::SendKeyQueryResponse()
//
//	PURPOSE:	Sends a MID_KEYQUERYRESPONSE message back to the sender
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::SendKeyQueryResponse(HOBJECT hObject, HSTRING hstrItemName, int iRet)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !hObject || !hstrItemName) return;

	// Tell the item we picked it up
	HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject((LPBASECLASS)this, hObject, MID_KEYQUERYRESPONSE);
	pServerDE->WriteToMessageHString(hMessage, hstrItemName);
	pServerDE->WriteToMessageByte(hMessage, (DBYTE) (iRet == CHWEAP_OK));
	pServerDE->EndMessage(hMessage);
}



// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::SendClientItemMsg()
//
//	PURPOSE:	Sends an item message to the client
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::SendClientItemMsg(DBYTE nMessageID, DBYTE nItem)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hClient) return;

	// Tell the item we picked it up
	HMESSAGEWRITE hMessage = pServerDE->StartMessage(m_hClient, nMessageID);
	pServerDE->WriteToMessageDWord(hMessage, nItem);
	pServerDE->EndMessage(hMessage);
}



// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::EngineMessageFn
//
//	PURPOSE:	Handle message from the engine
//
// ----------------------------------------------------------------------- //
		
DDWORD CInventoryMgr::EngineMessageFn(LPBASECLASS pObject, DDWORD messageID, void *pData, DFLOAT fData)
{
	switch(messageID)
	{
		case MID_UPDATE:
			Update();
			break;

		case MID_SAVEOBJECT:
			Save((HMESSAGEWRITE)pData, (DDWORD)fData);
			break;

		case MID_LOADOBJECT:
			Load((HMESSAGEREAD)pData, (DDWORD)fData);
			break;

		case MID_GETFORCEUPDATEOBJECTS:
			SetForceUpdateList((ForceUpdate*)pData);
			break;

		case MID_LINKBROKEN:
		{
			if( m_hMuzzleFlash == ( HOBJECT )pData )
				m_hMuzzleFlash = NULL;
		
			break;
		}
	}

	return Aggregate::EngineMessageFn(pObject, messageID, pData, fData);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::UpdateCurrentWeaponFiring()
//
//	PURPOSE:	Handles the raising/lowering of a weapon, and updates the current
//				weapon's state.
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::UpdateCurrentWeaponFiring(DVector *firedPos, DVector *lFiredPos, DRotation *rotP, DBOOL bFiring, DBOOL bAltFiring)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	CWeapon *pWeap = m_Weapons[m_nCurWeaponSlot];
	CWeapon *pLWeap = m_LWeapons[m_nCurWeaponSlot];

	if(pWeap && pLWeap)
		bAltFiring = DFALSE;

	if(pWeap)
		pWeap->UpdateFiringState(firedPos, rotP, bFiring, bAltFiring);
	if(pLWeap)
		pLWeap->UpdateFiringState(lFiredPos, rotP, bFiring, bAltFiring);

/*	if(pWeap && pLWeap)
	{
		// Don't use the alt-fires if we have two weapons
		bAltFiring = DFALSE;

		DFLOAT fTime = pServerDE->GetTime();

		if((fTime - g_LastDuelShotTime) >= (pWeap->GetReloadTime() / 2.0f))
		{
			if(g_FireLeftHand)
				pLWeap->UpdateFiringState(lFiredPos, rotP, bFiring, bAltFiring);
			else
				pWeap->UpdateFiringState(firedPos, rotP, bFiring, bAltFiring);

			g_FireLeftHand = !g_FireLeftHand;
			g_LastDuelShotTime = fTime;
		}
	}
	else if (pWeap)
		pWeap->UpdateFiringState(firedPos, rotP, bFiring, bAltFiring);
*/
	// Check to see if done switching, and complete the switch if so.
	if (m_bSwitchingWeapons)
	{
		if(!pWeap)
		{
			if (m_Weapons[m_nCurWeaponSlot])
				m_Weapons[m_nCurWeaponSlot]->ShowHandModel(DFALSE);
			if (m_LWeapons[m_nCurWeaponSlot])
				m_LWeapons[m_nCurWeaponSlot]->ShowHandModel(DFALSE);

			m_nCurWeaponSlot = m_nNextWeaponSlot;
			assert( m_nCurWeaponSlot < 10 );
			m_pCurWeapon = pWeap = m_Weapons[m_nCurWeaponSlot];
			pLWeap = m_LWeapons[m_nCurWeaponSlot];
			m_nCurWeapon = m_pCurWeapon->GetType();

			m_bSwitchingWeapons = DFALSE;

			// raise the weapon if it exists, otherwise hide the view model
			if (pWeap) 
				pWeap->Draw();
			else
				m_pViewModel->SetVisible(DFALSE);

			if (pLWeap) 
				pLWeap->Draw();
			else
				m_pLViewModel->SetVisible(DFALSE);
		}
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::Update()
//
//	PURPOSE:	Updates all of the weapon
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::Update()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;
	unsigned long i;
	DFLOAT  fTime = pServerDE->GetTime();
	DFLOAT  fBurnFocus = 0;

	// Move the weapon models to this position
	DVector vPos;
	pServerDE->GetObjectPos(m_hOwner, &vPos);

	// Update all of the weapons
	for (i=0; i<SLOTCOUNT_TOTALWEAPONS; i++)
	{
		CWeapon *w = m_Weapons[i];
		if (w)
		{
			// See if client needs to be notified
			if (m_hClient && w->IsInitialized() && !w->IsClientNotified())
				w->SendClientInfo((DBYTE)i);
			w->Update();
		}
		w = m_LWeapons[i];
		if (w)
		{
			// See if client needs to be notified
			if (m_hClient && w->IsInitialized() && !w->IsClientNotified())
				w->SendClientInfo((DBYTE)i);
			w->Update();
		}
	}

	// Update all of the inventory items & spells
	DLink *pLink = m_InvItemList.m_Head.m_pNext;
	for (i=0; i < m_InvItemList.m_nElements; i++)
	{
		CInvItem *pItem = (CInvItem*) pLink->m_pData;
		pLink = pLink->m_pNext;
		if (pItem)
		{
			pItem->Update();
			if( GetItemCharges( pItem ) <= 0 )
				RemoveItem( pItem->GetType( ));
		}
	}

	// Show the current weapon
	if (IsBaseCharacter(m_hOwner))
	{
		CBaseCharacter *pBC = (CBaseCharacter*)pServerDE->HandleToObject(m_hOwner);
		if (pBC && !pBC->IsDead())
		{
			if(m_Weapons[m_nCurWeaponSlot])
				m_Weapons[m_nCurWeaponSlot]->ShowHandModel(DTRUE);
			if(m_LWeapons[m_nCurWeaponSlot])
				m_LWeapons[m_nCurWeaponSlot]->ShowHandModel(DTRUE);
		}
	}

//	m_Weapons[m_nCurWeaponSlot]->ShowHandModel(m_Weapons[m_nCurWeaponSlot] ? DTRUE : DFALSE);
//	m_LWeapons[m_nCurWeaponSlot]->ShowHandModel(m_LWeapons[m_nCurWeaponSlot] ? DTRUE : DFALSE);

	// Regenerate focus, and subtract any continuous use focus in effect

	if (IsBaseCharacter(m_hOwner))
	{
		CBaseCharacter *pBC = (CBaseCharacter*)pServerDE->HandleToObject(m_hOwner);
		if (pBC && !pBC->IsDead())
		{
			DBYTE nMagic = m_nAttribMagic-1;
			CLIPLOWHIGH(nMagic, 0, 5);

			DFLOAT fMaxFocus = fMaxAmmoCount[AMMO_FOCUS][nMagic];
			if (m_fAmmo[AMMO_FOCUS] < fMaxFo

⌨️ 快捷键说明

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