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

📄 viewweapon.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				DFLOAT fReloadTime;
				if (m_bLastFireAlt)
					fReloadTime = m_fAltReloadTime;
				else
					fReloadTime = m_fReloadTime;

				fReloadTime *= 1;	// m_pInventoryMgr->GetFireRateMultiplier();

				// See if we should play an idle animation
				if((m_pClientDE->GetTime() - m_fIdleStartTime) > m_fIdleDelay)
				{
					m_pClientDE->SetModelLooping(m_hObject, DFALSE);

					PlayAnimation(m_nIdleAnim);
					m_eState = WS_IDLE;
				}
				// Make sure enough time has gone by to allow firing
				if(((fTime - m_fLastShotTime) > fReloadTime))
				{
					if (bFiring && (CheckAmmo(DFALSE) >= m_nAmmoUse))
					{
						m_fLastShotTime = fTime;
	
						m_eState = WS_START_FIRING;
						if (!PlayAnimation(m_nStartFireAnim))
						{
							m_pClientDE->SetModelLooping(m_hObject, m_bLoopAnim);

							PlayAnimation(m_nFireAnim);
							m_eState = WS_FIRING;
						}
					}
					else if (bAltFiring && !IsAltFireZoom() && (CheckAmmo(DTRUE) >= m_nAltAmmoUse))
					{
						m_fLastShotTime = fTime;

						m_eState = WS_START_ALT_FIRING;
						if (!PlayAnimation(m_nStartAltFireAnim))
						{
							m_pClientDE->SetModelLooping(m_hObject, m_bAltLoopAnim);

							PlayAnimation(m_nAltFireAnim);
							m_eState = WS_ALT_FIRING;
						}
					}
				}
			}
			break;

		case WS_DRAW:
			{
				if(!PlayAnimation(m_nDrawAnim))
				{	
					PlayAnimation(m_nRestAnim);
					m_eState = WS_REST;

					m_pClientDE->SetModelLooping(m_hObject, m_bLoopStatic);
					m_fIdleStartTime = fTime;
				}
			}
			break;

		case WS_HOLSTER:
			{
				if(!PlayAnimation(m_nHolsterAnim))
				{	
					m_eState = WS_HOLSTERED;

					m_pClientDE->SetModelLooping(m_hObject, DFALSE);
				}
			}
			break;

		case WS_START_ALT_FIRING:
		case WS_START_FIRING:
			{
				bAltFire = (m_eState == WS_START_ALT_FIRING);
				if (!PlayAnimation(bAltFire ? m_nStartAltFireAnim : m_nStartFireAnim))
				{
					if (bAltFire ? m_bAltLoopAnim : m_bLoopAnim)
						m_pClientDE->SetModelLooping(m_hObject, DTRUE);
					else
						m_pClientDE->SetModelLooping(m_hObject, DFALSE);

					PlayAnimation(bAltFire ? m_nAltFireAnim : m_nFireAnim);
					m_eState = bAltFire ? WS_ALT_FIRING : WS_FIRING;
				}
				m_fIdleStartTime = fTime;
			}
			break;

		case WS_ALT_FIRING:
		case WS_FIRING:
			{
				bAltFire = (m_eState == WS_ALT_FIRING);
				DBOOL bLoopAnim;
				DDWORD nFireAnim;
				DBOOL  bNowFiring;
				DFLOAT fReloadTime;
				DDWORD nAmmoUse;
				DFLOAT fAmmo;
				WeaponState eNextState;

				if (bAltFire)
				{
					bLoopAnim	= m_bAltLoopAnim;
					nFireAnim	= m_nAltFireAnim;
					bNowFiring	= bAltFiring;
					fReloadTime = m_fAltReloadTime;
					eNextState	= WS_STOP_ALT_FIRING;
					nAmmoUse	= m_nAltAmmoUse;
					fAmmo		= CheckAmmo(DTRUE);
				}
				else
				{
					bLoopAnim	= m_bLoopAnim;
					nFireAnim	= m_nFireAnim;
					bNowFiring	= bFiring;
					fReloadTime = m_fReloadTime;
					eNextState	= WS_STOP_FIRING;
					nAmmoUse	= m_nAmmoUse;
					fAmmo		= CheckAmmo(DFALSE);
				}

				// No fire anim, so fire right away
				if (nFireAnim == INVALID_ANI && !bLoopAnim)
				{
					if(fAmmo >= nAmmoUse)
						Fire();

					m_eState = eNextState;
				}
				// Else looping anim, so fire based on rate of fire
				else if (bLoopAnim)
				{
					if (!bNowFiring || (fAmmo < nAmmoUse))
					{
						m_eState = eNextState;
						m_pClientDE->SetModelLooping(m_hObject, DFALSE);
					}
				}
				else if (m_bSemiAuto && !bAltFire)
				{
					// Stopped firing
					if (!m_bLastFiring && bNowFiring && (fAmmo >= nAmmoUse))
					{
						m_pClientDE->ResetModelAnimation(m_hObject);
					}
					else if (!PlayAnimation(bAltFire ? m_nAltFireAnim : m_nFireAnim))
					{
						m_eState = eNextState;
					}
				}
				// Else just wait for the animation to stop
				else if (!PlayAnimation(bAltFire ? m_nAltFireAnim : m_nFireAnim))
				{
					m_eState = eNextState;
				}
				// check if there is a fire rate multiplier
				/// TODO: This may need to be copied from the server? GK
//				else if (m_pInventoryMgr->GetFireRateMultiplier() < 1.0f)
//				{
//					if (!m_bLastFiring && bNowFiring && (fTime - m_fLastShotTime) > fReloadTime * m_pInventoryMgr->GetFireRateMultiplier())
//						m_pClientDE->ResetModelAnimation(m_hObject);
//				}
				m_fIdleStartTime = fTime;
			}
			break;

		case WS_STOP_ALT_FIRING:
		case WS_STOP_FIRING:
			{
				bAltFire = (m_eState == WS_STOP_ALT_FIRING);
				if (!PlayAnimation(bAltFire ? m_nStopAltFireAnim : m_nStopFireAnim))
				{
					PlayAnimation(m_nRestAnim);
					m_eState = WS_REST;

					m_pClientDE->SetModelLooping(m_hObject, m_bLoopStatic);
				}
				m_fIdleStartTime = fTime;
			}
			break;

		default : break;
	}
	m_bLastFiring = bFiring | bAltFiring;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CViewWeapon::CancelFiringState
//
//	PURPOSE:	Cancel the current weapon state and reset
//
// ----------------------------------------------------------------------- //

void CViewWeapon::CancelFiringState()
{
	if (!m_pClientDE) return;

	m_pClientDE->ResetModelAnimation(m_hObject);
	PlayAnimation(m_nRestAnim);
	m_pClientDE->ResetModelAnimation(m_hObject);
	m_eState = WS_REST;

	SendSoundMsg(DNULL, 0x02);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CViewWeapon::SetupViewModel
//
//	PURPOSE:	Sets the model filenames and animations.
//
// ----------------------------------------------------------------------- //

void CViewWeapon::SetupViewModel()
{
	if (!m_pClientDE) return;

	CBloodClientShell *pShell = (CBloodClientShell*)m_pClientDE->GetClientShell();
	HLOCALOBJ hPlayerObj = m_pClientDE->GetClientObject();

	// Choose the right or lefthanded model
	char	*pModelFilename;
	if(m_bLeftHand)		pModelFilename = m_pLeftViewModelFilename;
		else			pModelFilename = m_pViewModelFilename;

	if(pModelFilename && m_pViewModelSkinname)
	{
		char	firstChar = 0;
		char	start[] = "C_";
		char	*change = DNULL;

		ObjectCreateStruct createStruct;
		INIT_OBJECTCREATESTRUCT(createStruct);

		// Get the character to use for the skin

#ifdef _ADDON
		DBOOL bEnemyChar = DFALSE;
		if (pShell->GetCharacter() >= CHARACTER_M_CULTIST)
		{
			bEnemyChar = DTRUE;
		}
#endif
		switch(pShell->GetCharacter())
		{
			case	CHARACTER_CALEB:		firstChar = 'C'; break;
			case	CHARACTER_OPHELIA:		firstChar = 'O'; break;
			case	CHARACTER_ISHMAEL:		firstChar = 'I'; break;
			case	CHARACTER_GABREILLA:	firstChar = 'G'; break;

#ifdef _ADDON
			case	CHARACTER_M_CULTIST:	firstChar = 'C'; break;
			case	CHARACTER_F_CULTIST:	firstChar = 'O'; break;
			case	CHARACTER_SOULDRUDGE:	firstChar = 'C'; break;
			case	CHARACTER_PROPHET:		firstChar = 'I'; break;
#endif

		}

		// Copy over the filenames so we preserver the originals
		strcpy(createStruct.m_Filename, pModelFilename);
		strcpy(createStruct.m_SkinName, m_pViewModelSkinname);

		strupr(createStruct.m_Filename);	// [blg]
		strupr(createStruct.m_SkinName);

		createStruct.m_Flags = FLAG_MODELGOURAUDSHADE | FLAG_REALLYCLOSE | FLAG_VISIBLE | m_nFlags;

		// Change the weapon skin to the correct character
		change = strstr(createStruct.m_SkinName, start);
		if (change) change[0] = firstChar;

		// Change the knife model to the correct character
		if(m_nType == WEAP_MELEE)
		{
			change = strstr(createStruct.m_Filename, start);
			if (change) change[0] = firstChar;
		}

		// Change to the generic orb skin if necessary

#ifdef _ADDON
		if (m_nType == WEAP_ORB && bEnemyChar)
		{
			strcpy(createStruct.m_SkinName, "skins_ao\\weapons_ao\\generic_orb_pv_t.dtx");
		}
#endif

		// Set the remaining info
		change = DNULL;
		createStruct.m_ObjectType = OT_MODEL;
		m_pClientDE->GetObjectPos(hPlayerObj, &createStruct.m_Pos);

		// Delete the object to avoid duplicates
/*		if(m_hObject)
		{
			m_pClientDE->DeleteObject(m_hObject);
			m_hObject = DNULL;
		}
*/
		m_hObject = m_pClientDE->CreateObject(&createStruct);

		if(m_nFlags & FLAG_ENVIRONMENTMAP)
			m_pClientDE->SetObjectColor(m_hObject, 1.0f, 1.0f, 1.0f, m_fChromeValue);
		else
			m_pClientDE->SetObjectColor(m_hObject, 0.0f, 0.0f, 0.0f, 1.0f);

		m_pClientDE->SetObjectClientFlags(m_hObject, CF_NOTIFYMODELKEYS);

		// Set the new model filenames
//		m_pClientDE->SetObjectFilenames(m_hObject, model, skin);

		m_pClientDE->SetModelLooping(m_hObject, DFALSE);
		m_pClientDE->SetModelAnimation(m_hObject, -1);

		// Tell it that this weapon this is it's parent for now.

		m_nRestAnim			= m_pClientDE->GetAnimIndex(m_hObject, "static_model");
		m_nIdleAnim			= m_pClientDE->GetAnimIndex(m_hObject, "idle");
		m_nDrawAnim			= m_pClientDE->GetAnimIndex(m_hObject, "draw");
		m_nDrawDuelAnim		= m_pClientDE->GetAnimIndex(m_hObject, "dh_draw");
		m_nHolsterAnim		= m_pClientDE->GetAnimIndex(m_hObject, "holster");
		m_nHolsterDuelAnim	= m_pClientDE->GetAnimIndex(m_hObject, "dh_holster");
		m_nStartFireAnim	= m_pClientDE->GetAnimIndex(m_hObject, "start_fire");
		m_nFireAnim			= m_pClientDE->GetAnimIndex(m_hObject, "fire");
		m_nStopFireAnim		= m_pClientDE->GetAnimIndex(m_hObject, "end_fire");
		m_nStartAltFireAnim	= m_pClientDE->GetAnimIndex(m_hObject, "start_alt_fire");
		m_nAltFireAnim		= m_pClientDE->GetAnimIndex(m_hObject, "alt_fire");
		m_nStopAltFireAnim	= m_pClientDE->GetAnimIndex(m_hObject, "end_alt_fire");

		if (m_nIdleAnim == INVALID_ANI)
			m_nIdleAnim = m_nRestAnim;

		if (m_nAltFireAnim == INVALID_ANI)
		{
			m_nStartAltFireAnim = m_nStartFireAnim;
			m_nAltFireAnim = m_nFireAnim;
			m_nStopAltFireAnim = m_nStopFireAnim;
		}

		PlayAnimation(m_nDrawAnim);
		m_fIdleDelay = GetRandom(m_fMinIdleDelay, m_fMaxIdleDelay);
		m_fIdleStartTime = m_pClientDE->GetTime();
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CViewWeapon::PlayAnimation()
//
//	PURPOSE:	Set model to new animation
//
// ----------------------------------------------------------------------- //

DBOOL CViewWeapon::PlayAnimation(DDWORD dwNewAni)
{
	if (!m_pClientDE || dwNewAni == INVALID_ANI) return DFALSE;

	DDWORD dwAni	= m_pClientDE->GetModelAnimation(m_hObject);
	DDWORD dwState	= m_pClientDE->GetModelPlaybackState(m_hObject);

	if (dwAni == dwNewAni && (dwState & MS_PLAYDONE))
	{
		return DFALSE;
	}
	else if (dwAni != dwNewAni)
	{
		m_pClientDE->SetModelAnimation(m_hObject, dwNewAni);
	}

	return DTRUE;
}



// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CViewWeapon::OnModelKey()
//
//	PURPOSE:	Handle animation command
//
// ----------------------------------------------------------------------- //

void CViewWeapon::OnModelKey(HLOCALOBJ hObj, ArgList* pArgList)
{
	char*	pKey;
	int		count = pArgList->argc;

	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();

	for(int i = 0; i < count; i++)
	{
		pKey = pArgList->argv[i];
		if(!pKey) break;

		if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_FIRE) == 0)
		{
			Fire();
		}
		else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SOUND) == 0)
		{
			char*	pSound = pArgList->argv[++i];
			char	pDir[100];

			if(pSound)
			{
				_mbscpy((unsigned char*)pDir, (const unsigned char*)"Sounds\\Weapons\\");
				_mbscat((unsigned char*)pDir, (const unsigned char*)pSound);

				SendSoundMsg(pDir, 0x00);
//				PlaySoundFromObject(m_hObject, pDir, 1000, SOUNDPRIORITY_PLAYER_HIGH,
//					DFALSE, DFALSE, DFALSE, 100 );
			}
		}
		else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SOUNDLOOP) == 0)
		{
			char*	pSound = pArgList->argv[++i];
			char	pDir[100];

			if(pSound && !m_hLoopSound)
			{
				_mbscpy((unsigned char*)pDir, (const unsigned char*)"Sounds\\Weapons\\");
				_mbscat((unsigned char*)pDir, (const unsigned char*)pSound);

				SendSoundMsg(pDir, 0x01);
//				m_hLoopSound = PlaySoundFromObject(m_hObject, pDir, 1000, SOUNDPRIORITY_PLAYER_HIGH, DTRUE, DTRUE);
			}
		}
		else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SOUNDSTOP) == 0)
		{
			SendSoundMsg(DNULL, 0x02);

//			if(m_hLoopSound)
//				m_pClientDE->KillSound(m_hLoopSound);
//			m_hLoopSound = DNULL;
		}
		else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_HIDE) == 0)
		{
			char*	pNode = pArgList->argv[++i];
			DBOOL	nodeStat;
			m_pClientDE->GetModelNodeHideStatus(m_hObject, pNode, &nodeStat);

			if(!nodeStat)
				m_pClientDE->SetModelNodeHideStatus(m_hObject, pNode, DTRUE);
		}
		else if(_mbsicmp((const unsigned char*)pKey, (const unsigned char*)WEAPON_KEY_SHOW) == 0)
		{
			char*	pNode = pArgList->argv[++i];
			DBOOL	nodeStat;
			m_pClientDE->GetModelNodeHideStatus(m_hObject, pNode, &nodeStat);

			if(nodeStat)
				m_pClientDE->SetModelNodeHideStatus(m_hObject, pNode, DFALSE);
		}
	}
	/*
	else if (stricmp(pKey, WEAPON_KEY_SOUND) == 0)
	{
		if (pArgList->argc > 1)
		{
			char* pSound = pArgList->argv[1];
			if (pSound)
			{
				char buf[100];
				sprintf(buf,"Sounds\\Weapons\\%s.wav", pSound);

				PlaySoundLocal(buf, SOUNDPRIORITY_PLAYER_HIGH, DFALSE, DFALSE, 100, DTRUE );

				// Send message to Server so that other client's can hear this sound...

				HSTRING hSound = m_pClientDE->CreateString(buf);

				HMESSAGEWRITE hWrite = m_pClientDE->StartMessage(CMSG_WEAPON_SOUND);
				m_pClientDE->WriteToMessageByte(hWrite, WEAPON_SOUND_KEY);
				m_pClientDE->WriteToMessageByte(hWrite, m_nWeaponId);
				m_pClientDE->WriteToMessageVector(hWrite, &m_vFlashPos);
				m_pClientDE->WriteToMessageHString(hWrite, hSound);
				m_pClientDE->EndMessage2(hWrite, MESSAGE_NAGGLEFAST|MESSAGE_GUARANTEED);

				m_pClientDE->FreeString(hSound);
			}
		}
	}
	*/
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CViewWeapon::SendSoundMsg
//
//	PURPOSE:	Send fire message to server
//
// ----------------------------------------------------------------------- //

void CViewWeapon::SendSoundMsg(char *szSound, DBYTE byFlags)
{
	if (!m_pClientDE) return;

	HSTRING	sSound = m_pClientDE->CreateString(szSound);

	// Send Sound message to server...
	HMESSAGEWRITE hWrite = m_pClientDE->StartMessage(CMSG_WEAPON_SOUND);
	m_pClientDE->WriteToMessageByte(hWrite, byFlags);

	if(byFlags != 0x02)
		m_pClientDE->WriteToMessageHString(hWrite, sSound);

	m_pClientDE->EndMessage2(hWrite, MESSAGE_NAGGLEFAST|MESSAGE_GUARANTEED);

	if(sSound)	m_pClientDE->FreeString(sSound);
}

⌨️ 快捷键说明

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