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

📄 inventorymgr.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//----------------------------------------------------------
//
// MODULE  : InventoryMgr.cpp
//
// PURPOSE : Container for weapons objects, inventory items, etc.
//
// CREATED : 9/22/97
//
//----------------------------------------------------------

// Includes...
#include <stdio.h>
#include "InventoryMgr.h"
#include "GameWeapons.h"
#include "GameInvItems.h"
#include "WeaponPickups.h"
#include "ItemPickups.h"
#include "BloodServerShell.h"
#include "PlayerObj.h"
#include "ClientRes.h"

#include "windows.h"

extern char msgbuf[255];

// Table of max ammo values
static DFLOAT fMaxAmmoCount[AMMO_MAXAMMOTYPES+1][6] = 
{
// Strength or Magic attrib:
//   1		2		3		4		5		6
	{0.0f,  0.0f,   0.0f,   0.0f,   0.0f,   0.0f},		// None
	{100.0f,200.0f, 300.0f, 400.0f, 500.0f, 600.0f},	// Bullets
	{50.0f,	75.0f,  100.0f, 125.0f, 150.0f, 175.0f},	// Shells
	{20.0f,	40.0f,  60.0f,  80.0f,  100.0f, 120.0f},	// BMG Rounds
	{20.0f,	40.0f,  60.0f,  80.0f,  100.0f, 120.0f},	// Flares
	{25.0f,	50.0f,  75.0f,  100.0f, 150.0f, 200.0f},	// DieBugDie
	{5.0f,	10.0f,	20.0f,	35.0f,	50.0f,	120.0f},	// Rockets
	{25.0f,	25.0f,	50.0f,	75.0f,	100.0f,	125.0f},	// Fuel
	{100.0f,200.0f, 300.0f, 400.0f, 500.0f, 600.0f},	// Batteries
	{100.0f,200.0f, 300.0f, 400.0f, 500.0f, 600.0f},	// Focus
	{10.0f, 10.0f,  10.0f,  10.0f,  10.0f,  10.0f},		// ProximityBomb
	{10.0f, 10.0f,  10.0f,  10.0f,  10.0f,  10.0f},		// RemoteBomb
	{10.0f, 10.0f,  10.0f,  10.0f,  10.0f,  10.0f},		// TimeBomb
};

	// Focus regen rates
//Magic of 1 - No Focus, and no regeneration.
//Magic of 2 - Maximum of 50 Focus, regenerates at 1 point a second.
//Magic of 3 - Maximum of 200 Focus, regenerates at 3 points a second.
//Magic of 4 - Maximum of 400 Focus, regenerates at 5 points a second.
//Magic of 5 - Maximum of 750 Focus, regenerates at 10 points a second.
//Magic of 6 - Maximum of 999 Focus, regenerates at 20 points a second.
//  g_nFocusRegenAmt is the amount to add to the focus each second
static DFLOAT g_fFocusRegenAmt[6] = {2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f};


// For alternating weapons
static DBOOL g_FireLeftHand = 0;
static DFLOAT g_LastDuelShotTime = 0.0f;


// Prototypes...

DBOOL IsDemoWeapon(int nWeapon);


// Functions...

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::CInventoryMgr()
//
//	PURPOSE:	Constructor
//
// ----------------------------------------------------------------------- //

CInventoryMgr::CInventoryMgr()
{
	int i;
	for (i=0; i < SLOTCOUNT_TOTALWEAPONS; i++)
	{
		m_Weapons[i] = NULL;
		m_LWeapons[i] = NULL;
	}

//	for (i=0; i < SLOTCOUNT_ITEMS; i++)
//		m_InvItems[i] = NULL;
	m_InvItemList.m_Head.m_pData = DNULL;
	dl_InitList(&m_InvItemList);
	m_pCurItem = DNULL;

/*
	for (i=0; i < SLOTCOUNT_SPELLS; i++)
		m_InvSpells[i] = NULL;
*/

/*	for (i=0; i <= INV_LASTSPELL; i++)
		m_nItemIndex[i] = ITEMINDEX_NOSLOT;
*/
	for (i=0; i <= AMMO_MAXAMMOTYPES; i++)
		m_fAmmo[i] = 0.0f;

//	for (i=0; i < SLOTCOUNT_KEYS; i++)
//		m_KeyItems[i] = NULL;

	m_pViewModel = DNULL;
	m_pLViewModel = DNULL;
	m_hViewModelAttach = DNULL;
	m_hLViewModelAttach = DNULL;
	m_hMuzzleFlash = DNULL;				// Object with the muzzle flash light

// Clear the pointers
	m_nCurWeapon = -1;
	m_nCurWeaponSlot = 0;
	m_pCurWeapon = NULL;
	m_hOwner = NULL;
	m_hClient = NULL;

	m_fDamageMultiplier = 1.0f;
	m_fFireRateMultiplier = 1.0f;

	m_bGodMode = DFALSE;
	m_bInfiniteAmmo = DFALSE;

	m_nAttribStrength = 1;
	m_nAttribMagic = 1;
	
	m_hLastPickupObject = NULL;
	m_nLastPickupResult = CHWEAP_OK;
	m_hLastDroppedItem  = NULL;
	m_fLastDroppedTime = 0;

//	m_nCurrentItemIndex = 0;

	//	m_bHasSpellbook = DFALSE;

    m_bDropEye = DFALSE;

	m_bSwitchingWeapons = DFALSE;

	m_pLastCurrentItem = DNULL;
	m_pLastPrevItem = DNULL;
	m_pLastNextItem = DNULL;
	m_nLastCurrentItemCharge = 0;
	m_nLastPrevItemCharge = 0;
	m_nLastNextItemCharge = 0;
	m_bShowItems = DFALSE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::~CInventoryMgr()
//
//	PURPOSE:	Destructor
//
// ----------------------------------------------------------------------- //

CInventoryMgr::~CInventoryMgr()
{
	Term();
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::Init()
//
//	PURPOSE:	Initializes the inventory
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::Init(HOBJECT hObject, HCLIENT hClient)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();

	m_hOwner = hObject;

	// Create the muzzle flash object
	if (!m_hMuzzleFlash)
	{
		ObjectCreateStruct ocStruct;
		INIT_OBJECTCREATESTRUCT(ocStruct);

		ocStruct.m_ObjectType = OT_LIGHT; 

		HCLASS hClass = pServerDE->GetClass("BaseClass");
		if (LPBASECLASS pFlash = pServerDE->CreateObject(hClass, &ocStruct))
		{
			m_hMuzzleFlash = pFlash->m_hObject;
			pServerDE->CreateInterObjectLink( m_hOwner, m_hMuzzleFlash );
		}
	}

	if (hClient) SetClient(hClient);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::SetClient()
//
//	PURPOSE:	Sets the client handle, sets it for all weapons too.
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::SetClient(HCLIENT hClient)
{
/*	if (!m_pViewModel)
	{
		m_pViewModel = CreateViewModel(&m_hViewModelAttach);
	}

	if (!m_pLViewModel)
	{
		m_pLViewModel = CreateViewModel(&m_hLViewModelAttach);
	}
*/
	int i;
	for (i=0; i<SLOTCOUNT_TOTALWEAPONS; i++)
	{
		CWeapon *w = m_Weapons[i];
		if (w)
		{
			w->SetClient(hClient, m_pViewModel);
		}
		w = m_LWeapons[i];
		if (w)
		{
			w->SetClient(hClient, m_pLViewModel);
		}
	}
	if (m_nCurWeaponSlot >= 0 && m_nCurWeaponSlot < SLOTCOUNT_TOTALWEAPONS)
	{
		CWeapon *w = m_Weapons[m_nCurWeaponSlot];
		if (w)
		{
			w->Draw();
		}
		w = m_LWeapons[m_nCurWeaponSlot];
		if (w)
		{
			w->Draw();
		}
	}
	m_hClient = hClient;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::Term()
//
//	PURPOSE:	Terminates the inventory
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::Term()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();

	int i;
	for (i=0; i < SLOTCOUNT_TOTALWEAPONS; i++)
	{
		if (m_Weapons[i])
		{
			m_Weapons[i]->Term();
			delete m_Weapons[i];
			m_Weapons[i] = DNULL;
		}

		if (m_LWeapons[i])
		{
			m_LWeapons[i]->Term();
			delete m_LWeapons[i];
			m_LWeapons[i] = DNULL;
		}
	}

	m_nCurWeapon = -1;
	m_nCurWeaponSlot = 0;
	m_pCurWeapon = DNULL;

	while(m_InvItemList.m_nElements)
	{
		DLink *pLink = m_InvItemList.m_Head.m_pNext;
		dl_RemoveAt(&m_InvItemList,m_InvItemList.m_Head.m_pNext);
		
		if (pLink->m_pData)
		{
			((CInvItem*)pLink->m_pData)->Term();
			delete pLink->m_pData;
		}
	}

	m_pCurItem = DNULL;

	if (m_hViewModelAttach)
	{
		pServerDE->RemoveAttachment(m_hViewModelAttach);
		m_hViewModelAttach = DNULL;
	}

	if (m_hLViewModelAttach)
	{
		pServerDE->RemoveAttachment(m_hLViewModelAttach);
		m_hLViewModelAttach = DNULL;
	}

	if (m_pViewModel)
	{
		pServerDE->RemoveObject(m_pViewModel->m_hObject);
		m_pViewModel = DNULL;
	}

	if (m_pLViewModel)
	{
		pServerDE->RemoveObject(m_pLViewModel->m_hObject);
		m_pLViewModel = DNULL;
	}

	if (m_hMuzzleFlash)
	{
		pServerDE->RemoveObject(m_hMuzzleFlash);
		m_hMuzzleFlash = DNULL;
	}

	// Reset the values for inventory...
	m_pLastCurrentItem = DNULL;
	m_pLastPrevItem = DNULL;
	m_pLastNextItem = DNULL;
	m_nLastCurrentItemCharge = 0;
	m_nLastPrevItemCharge = 0;
	m_nLastNextItemCharge = 0;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::HandleDestruction
//
//	PURPOSE:	Handle destruction
//
// ----------------------------------------------------------------------- //

void CInventoryMgr::HandleDestruction()
{
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CWeapon::CreateViewModel
//
//	PURPOSE:	Create the model associated with the weapon.
//
// ----------------------------------------------------------------------- //

CViewWeaponModel* CInventoryMgr::CreateViewModel(HATTACHMENT *phAttachment)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return DNULL;

	HCLASS hOwnerClass = pServerDE->GetObjectClass(m_hOwner);
	CViewWeaponModel *pViewModel = DNULL;

	// Create a view weapon model if the owner has a client
	if(IsPlayer(m_hOwner)) 
	{
		ObjectCreateStruct ocStruct;
		INIT_OBJECTCREATESTRUCT(ocStruct);

		DVector vPos;
		pServerDE->GetObjectPos(m_hOwner, &vPos);

		VEC_COPY(ocStruct.m_Pos, vPos);

		_mbscpy((unsigned char*)ocStruct.m_Filename, (const unsigned char*)"Models\\Weapons\\Beretta_pv.abc");
		_mbscpy((unsigned char*)ocStruct.m_SkinName, (const unsigned char*)"Skins\\Weapons\\C_Beretta_pv_t.dtx");

		HCLASS hClass = pServerDE->GetClass("CViewWeaponModel");
		pViewModel = (CViewWeaponModel*)pServerDE->CreateObject(hClass, &ocStruct);

		if (pViewModel && phAttachment)
		{
			DVector vOffset;
			DRotation rRotOffset;
			VEC_INIT(vOffset);
			ROT_INIT(rRotOffset);

			pServerDE->CreateAttachment(m_hOwner, pViewModel->m_hObject, DNULL, &vOffset, &rRotOffset, phAttachment);
		}
	}

	return pViewModel;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CInventoryMgr::ObtainWeapon()
//
//	PURPOSE:	Adds a particular weapon to the inventory.  If slot is not
//              -1, a particular slot is attempted for use.
//
// ----------------------------------------------------------------------- //

int CInventoryMgr::ObtainWeapon(DDWORD nWeapon, int slot)
{
	if(nWeapon >= WEAP_BASEINVENTORY)		// Need to use AddInventoryWeapon for these
		return CHWEAP_NOTAVAIL;

	CWeapon *w;
	DBOOL bLeftHand = DFALSE;
	int emptyslot = -1;

	// See if a particular slot is requested
	if (slot != -1)
	{
		w = m_Weapons[slot];
		if (!w)
			emptyslot = slot;
		else if (w->GetType() == nWeapon)
		{
			// Have it, see if it's dual-handed & we don't yet have 2.
			if (w->IsDualHanded() && !m_LWeapons[slot])
			{
				emptyslot = slot;
				bLeftHand = DTRUE;
			}
			else
			{
				return CHWEAP_ALREADYHAVE;
			}
		}
	}
	if (emptyslot == -1)
	{
		// Count down through the slots
		for (int i=0; i < SLOTCOUNT_WEAPONS; i++)
		{
			w = m_Weapons[i];
			if (w)		// See if we already have it..
			{
				if (w->GetType() == nWeapon) 
				{
					// Have it, see if it's dual-handed & we don't yet have 2.
					if (w->IsDualHanded() && !m_LWeapons[i])
					{
						emptyslot = i;
						bLeftHand = DTRUE;
						break;
					}
					else
					{
						return CHWEAP_ALREADYHAVE;
					}
				}
			}
			else if (emptyslot == -1) // Empty slot, mark it..
			{
				emptyslot = i;
			}
		}
	}

	if (emptyslot == -1) return CHWEAP_NOAVAILSLOTS;

#ifdef _DEMO
	if (!IsDemoWeapon(nWeapon) && IsPlayer(m_hOwner))
	{
		return(CHWEAP_NOTAVAIL);
	}
#endif

	switch(nWeapon)
	{
		case WEAP_BERETTA:
			w = new CBeretta;
			break;

		case WEAP_SHOTGUN:
			w = new CShotgun;
			break;

		case WEAP_SNIPERRIFLE:
			w = new CSniperRifle;
			break;

		case WEAP_ASSAULTRIFLE:
			w = new CAssaultRifle;
			break;

		case WEAP_SUBMACHINEGUN:
			w = new CSubMachineGun;
			break;

		case WEAP_FLAREGUN:
			w = new CFlareGun;
			break;

		case WEAP_HOWITZER:
			w = new CHowitzer;
			break;

		case WEAP_BUGSPRAY:
			w = new CBugSpray;
			break;

		case WEAP_NAPALMCANNON:
			w = new CNapalmCannon;
			break;

		case WEAP_MINIGUN:
			w = new CMiniGun;
			break;

		case WEAP_VOODOO:
			w = new CVoodooDoll;
			break;

		case WEAP_ORB:
			w = new COrb;
			break;

		case WEAP_DEATHRAY:
			w = new CDeathRay;
			break;

		case WEAP_LIFELEECH:
			w = new CLifeLeech;
			break;

		case WEAP_TESLACANNON:
			w = new CTeslaCannon;
			break;

		case WEAP_SINGULARITY:
			w = new CSingularity;
			break;

		case WEAP_MELEE:
			w = new CMelee;
			break;

#ifdef _ADD_ON

⌨️ 快捷键说明

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