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

📄 playerobj.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				else if (m_dwControlFlags & CTRLFLAG_STRAFELEFT)
					DoStrafeLeftAnim();
				else if (m_dwControlFlags & CTRLFLAG_STRAFERIGHT)
					DoStrafeRightAnim();
				else if (m_dwControlFlags & CTRLFLAG_RUN)
					DoFireRunAnim();
				else 
					DoFireWalkAnim();
			}
			else if (m_dwControlFlags & CTRLFLAG_CROUCH)
			{
				DoFireCrouchAnim();
			}
			else
			{
				DoFireStandAnim();
			}
		}
		else
		{
			if (m_dwControlFlags & CTRLFLAG_JUMP && !m_bForcedCrouch)
			{
				DoJumpAnim();
			}
			else if (m_dwControlFlags & CTRLFLAG_FORWARD || m_dwControlFlags & CTRLFLAG_BACKWARD ||
				m_dwControlFlags & CTRLFLAG_LEFT || m_dwControlFlags & CTRLFLAG_RIGHT || 
				m_dwControlFlags & CTRLFLAG_STRAFELEFT || m_dwControlFlags & CTRLFLAG_STRAFERIGHT)
			{
				if (m_dwControlFlags & CTRLFLAG_CROUCH)
					DoCrawlAnim();
				else if (m_dwControlFlags & CTRLFLAG_STRAFELEFT)
					DoStrafeLeftAnim();
				else if (m_dwControlFlags & CTRLFLAG_STRAFERIGHT)
					DoStrafeRightAnim();
				else if (m_dwControlFlags & CTRLFLAG_RUN)
					DoRunAnim();
				else 
					DoWalkAnim();
			}
			else if (m_dwControlFlags & CTRLFLAG_CROUCH)
			{
				DoCrouchAnim();
			}
			else 
			{
				IdleTime();
			}
		}
	}
}


// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerObj::Update()
//
//	PURPOSE:	Handles the update for the player object.
//
// --------------------------------------------------------------------------- //
DBOOL CPlayerObj::Update(DVector *pMovement)
{
	CServerDE* pServerDE = GetServerDE();
	DBOOL	bNothingHappened = DTRUE;


	// Dev code to help us find the "ghost player" bug...
	if (m_hPlrPosVar)
	{
		if( pServerDE->GetVarValueFloat( m_hPlrPosVar ) > 0.0f )
			pServerDE->SetNetFlags( m_hObject, 0 );
		else
			pServerDE->SetNetFlags(m_hObject, NETFLAG_POSUNGUARANTEED|NETFLAG_ROTUNGUARANTEED|NETFLAG_ANIMUNGUARANTEED);
	}

	// Set our next update
	pServerDE->SetNextUpdate(m_hObject, (DFLOAT).001);

	// Sanity check
	if (!m_hClient)
		return DTRUE;

	// Update timers
	m_fSlowDeathSafeTimer -= g_pServerDE->GetFrameTime();
	if (m_fSlowDeathSafeTimer < 0) m_fSlowDeathSafeTimer = 0;

	m_fSlowDeathStayTimer -= g_pServerDE->GetFrameTime();
	if (m_fSlowDeathStayTimer < 0) m_fSlowDeathStayTimer = 0;


	// Check for first update
	if (m_bFirstUpdate)
	{
		SetMoveVel(gMoveVel[m_nAttribSpeed-1]);
		SetJumpVel(DEFAULT_JUMPVEL);
	
		m_PStateChangeFlags = PSTATE_ALL;
		UpdateClientPhysics(); // (to make sure they have their model around)
		TeleportClientToServerPos();

		// Initial update for some stats..
		m_nStatsFlags = PLAYERSTATS_HEALTH | PLAYERSTATS_AMMO | PLAYERSTATS_ALTAMMO | PLAYERSTATS_ARMOR | PLAYERSTATS_FOCUS;
		SendMessageToClient( SMSG_PLAYERSTATSUPDATE );
		
		m_bFirstUpdate = DFALSE;
	}

	// Check for sound completion
	if (m_hCurSound)
	{
		DBOOL bSoundDone = DFALSE;
		if (pServerDE->IsSoundDone(m_hCurSound, &bSoundDone) == LT_OK && bSoundDone)
		{
			g_pServerDE->KillSound( m_hCurSound );
			m_hCurSound = DNULL;
		}
	}
/*
	 // Check to see if the status bar display items have changed
	DDWORD nItem;

	// See if the health has changed, send to client
	nItem = (DDWORD)m_damage.GetHitPoints();
	if (m_nLastHitPoints != nItem)
	{
		// If we took damage, tell the client
		if (m_nLastHitPoints > nItem)
		{
			m_nLastDamage = m_nLastHitPoints - nItem;
			SendMessageToClient(SMSG_TOOKDAMAGE);
		}

		m_nLastHitPoints = nItem;
		SendMessageToClient(SMSG_HEALTH);
	}

	// See if the ammo has changed, send to client
	nItem = (DDWORD)m_InventoryMgr.GetCurrentWeaponAmmoCount();
	if (m_nLastAmmo != nItem)
	{
		m_nLastAmmo = nItem;
		SendMessageToClient(SMSG_AMMO);
	}

	// See if the armor has changed, send to client
	nItem = (DDWORD)m_damage.GetArmorPoints();
	if (m_nLastArmor != nItem)
	{
		m_nLastArmor = nItem;
		SendMessageToClient(SMSG_ARMOR);
	}

	// See if the focus has changed, send to client
	nItem = (DDWORD)m_InventoryMgr.GetAmmoCount(AMMO_FOCUS);
	if (m_nLastFocus != nItem)
	{
		m_nLastFocus = nItem;
		SendMessageToClient(SMSG_FOCUS);
	}
*/

	// Keep the client updated.
	UpdateClientPhysics();

	// Update air level...
	UpdateAirLevel();

	// Update the player stats to the client...
	UpdateStats( );

	// Update any powerup timers..
	CheckPowerups();

	// Update based on active inventory items or spells
	CheckItemsAndSpells();
	UpdateControlFlags();

	// Check for player movement
	if (!HandleMovement())
		bNothingHappened = DFALSE;

//	if (!HandleFiring())
//		bNothingHappened = DFALSE;

	if (m_dwControlFlags & CTRLFLAG_GRAB)
		GrabObject();

	if (m_dwControlFlags & CTRLFLAG_TAUNT)
		DoTaunt();

	UpdateAnim();

// 11/10/97 added auto smell maker...
	if (!m_damage.IsDead() && !m_bSpectatorMode && m_hObject)
	{
		if ((pServerDE->GetTime() > m_fSmellTime + m_fSmellDelay) )
		{
	    	DVector vPos, vHintPos;
    		pServerDE->GetObjectPos(m_hObject, &vPos);

			if(SmellHint::m_SmellHead.m_pPrev && SmellHint::m_SmellHead.m_pPrev->m_pData)
			{
				SmellHint* pPrevHint = (SmellHint*)SmellHint::m_SmellHead.m_pPrev->m_pData;
				pServerDE->GetObjectPos(pPrevHint->m_hObject, &vHintPos);
			
				if(VEC_DIST(vHintPos, vPos) >= 10.0f)
				{
					ObjectCreateStruct theStruct;
					INIT_OBJECTCREATESTRUCT(theStruct);
    
					DRotation rRot;
    				ROT_INIT(rRot);

    				ROT_COPY(theStruct.m_Rotation, rRot);
	    			VEC_COPY(theStruct.m_Pos, vPos);

			        m_fSmellTime = pServerDE->GetTime();

					pServerDE->CreateObject(pServerDE->GetClass("SmellHint"), &theStruct);
				}
			}
			else
			{
				ObjectCreateStruct theStruct;
				INIT_OBJECTCREATESTRUCT(theStruct);
        
				DRotation rRot;
    			ROT_INIT(rRot);

    			ROT_COPY(theStruct.m_Rotation, rRot);
	    		VEC_COPY(theStruct.m_Pos, vPos);
	
				m_fSmellTime = pServerDE->GetTime();

				pServerDE->CreateObject(pServerDE->GetClass("SmellHint"), &theStruct);
			}
		}

	}
	else if (m_damage.IsDead())  // I'm dead according to m_damage.
	{
		if (!m_bDead)	// Just died handled here.
			HandleDeath();

		bNothingHappened = DFALSE;
	}

	// Get current gun ID for the client
	CWeapon *w = m_InventoryMgr.GetCurrentWeapon();
	DBOOL bChange = DFALSE;
	if (!w && m_CurGun != WEAP_NONE)
	{
		m_CurGun = WEAP_NONE;
		m_CurGunSlot = m_InventoryMgr.GetCurrentWeaponSlot();
		bChange = DTRUE;
	}
	if (w && m_CurGun != w->GetType())
	{
		m_CurGun = w->GetType();
		m_CurGunSlot = m_InventoryMgr.GetCurrentWeaponSlot();
		bChange = DTRUE;
	}
	if (bChange)
	{
		// Toggle binoculars off if they are active
		if (m_InventoryMgr.IsItemActive(INV_BINOCULARS))
			m_InventoryMgr.SetActiveItem(INV_BINOCULARS);

		SendMessageToClient(SMSG_CHANGEWEAPON);
	}

	if (m_bDead)
	{
		m_InventoryMgr.ShowHandModels(DFALSE);

		int nRet = m_InventoryMgr.ChangeWeaponSlot(1);

		if (nRet == CHWEAP_NOTAVAIL)
		{
			m_InventoryMgr.ChangeWeaponSlot(0);
		}
	}

	// See if we should be cloaked, and set alpha if so.
/*	if (IsItemActive(INV_CLOAKING) && !m_bInvisible)
	{
		pServerDE->SetObjectColor(m_hObject, 0.0f, 0.0f, 0.0f, ALPHA_CLOAKED);
	}

	if (bNothingHappened)
	{
		IdleTime();
	}
	else
	{
		m_startIdle = pServerDE->GetTime();
	}
*/

	// [blg] Check for idle time

	if (bNothingHappened && (m_dwControlFlags == 0 || m_dwControlFlags == CTRLFLAG_RUN) && !m_bDead)
	{
		m_fIdleTime += pServerDE->GetFrameTime();

		if (m_fIdleTime > MAX_IDLE_TIME)
		{
			ResetIdleTime();
			PlayVoiceGroupEventOnClient(VME_IDLE, DTRUE);
		}
	}
	else
	{
		ResetIdleTime();
	}


	// Set client view pos to the camera level

	pServerDE->GetObjectPos(m_hObject, &m_vLastPos);

	DVector vListenPos;
	if (!g_hActiveCamera)
	{
		if (IsItemActive(INV_THEEYE))
		{ 
			CInvTheEye* pEye = (CInvTheEye*)m_InventoryMgr.GetItem(INV_THEEYE);
			if (pEye)
			{
				DVector vListenPos;
				HOBJECT hObj = pEye->GetEyeObject();
				if (hObj)
				{
					pServerDE->GetObjectPos(hObj, &vListenPos);
					pServerDE->SetClientViewPos(m_hClient, &vListenPos);
				}
			}
		}
		else if(m_hOrbObj)
		{
			DVector vListenPos;
			pServerDE->GetObjectPos(m_hOrbObj, &vListenPos);
			pServerDE->SetClientViewPos(m_hClient, &vListenPos);
		}
		else	// not the eye
		{
			VEC_COPY(vListenPos, m_vLastPos);
			vListenPos.y += m_fEyeLevel;
			pServerDE->SetClientViewPos(m_hClient, &vListenPos);

			if( pServerDE->GetTime( ) > m_fNextPingTime )
			{
				m_fNextPingTime = pServerDE->GetTime( ) + PINGPERIOD;
				pServerDE->PingObjects(m_hObject);
			}
		}
	}
	else
	{
		pServerDE->GetObjectPos(g_hActiveCamera, &vListenPos);
		pServerDE->SetClientViewPos(m_hClient, &vListenPos);

		if( pServerDE->GetTime( ) > m_fNextPingTime )
		{
			m_fNextPingTime = pServerDE->GetTime( ) + PINGPERIOD;
			pServerDE->PingObjects(g_hActiveCamera);
		}

	}


	// If we're outside the world in a multiplayer game, we deserve to die...
		
	if (g_pBloodServerShell->IsMultiplayerGame())
	{
		DVector vPos, vMin, vMax;
		pServerDE->GetWorldBox(vMin, vMax);
		pServerDE->GetObjectPos(m_hObject, &vPos);	

		if (vPos.x < vMin.x || vPos.y < vMin.y || vPos.z < vMin.z ||
			vPos.x > vMax.x || vPos.y > vMax.y || vPos.z > vMax.z)
		{
			DVector vNull;
			VEC_INIT(vNull);
			DamageObject(m_hObject, (LPBASECLASS)this, m_hObject, 100.0f, vNull, vNull, DAMAGE_TYPE_DEATH);
		}
	}


	// All done...

	return DTRUE;
}



// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerObj::UpdateStats()
//
//	PURPOSE:	Updates player stats.
//
// --------------------------------------------------------------------------- //
void CPlayerObj::UpdateStats()
{
	 // Check to see if the status bar display items have changed
	DDWORD nItem;

	m_nStatsFlags = 0;

	// See if the health has changed, send to client
	nItem = (DDWORD)m_damage.GetHitPoints();
	if (m_nLastHitPoints != nItem)
	{
		// If we took damage, tell the client
		if (m_nLastHitPoints > nItem)
		{
			m_nLastDamage = m_nLastHitPoints - nItem;
			m_nStatsFlags |= PLAYERSTATS_TOOKDAMAGE;

			if (IsRandomChance(69 + m_nLastDamage))
			{
				if (m_damage.GetLastDamageType() == DAMAGE_TYPE_FIRE)
				{
					PlayVoiceGroupEventOnClient(VME_BURNING, DTRUE);
				}
				else
				{
					PlayVoiceGroupEventOnClient(VME_PAIN, DTRUE);
				}
			}
		}

		m_nLastHitPoints = nItem;
		m_nStatsFlags |= PLAYERSTATS_HEALTH;
	}

	// See if the ammo has changed, send to client
	nItem = (DDWORD)m_InventoryMgr.GetCurrentWeaponAmmoCount();
	if (m_nLastAmmo != nItem)
	{
		m_nLastAmmo = nItem;
		m_nStatsFlags |= PLAYERSTATS_AMMO;
	}

	// See if the ammo has changed, send to client
	nItem = (DDWORD)m_InventoryMgr.GetCurrentWeaponAltFireAmmoCount();
	if (m_nLastAltAmmo != nItem)
	{
		m_nLastAltAmmo = nItem;
		m_nStatsFlags |= PLAYERSTATS_ALTAMMO;
	}

	// See if the armor has changed, send to client
	nItem = (DDWORD)m_damage.GetArmorPoints();
	if (m_nLastArmor != nItem)
	{
		m_nLastArmor = nItem;
		m_nStatsFlags |= PLAYERSTATS_ARMOR;
	}

	// See if the focus has changed, send to client
	nItem = (DDWORD)m_InventoryMgr.GetAmmoCount(AMMO_FOCUS);
	if (m_nLastFocus != nItem)
	{
		m_nLastFocus = nItem;
		m_nStatsFlags |= PLAYERSTATS_FOCUS;
	}


	// See if air level has changed...

	if (m_fOldAirLevel != m_fAirLevel)
	{
		m_fOldAirLevel = m_fAirLevel;
		m_nStatsFlags |= PLAYERSTATS_AIRLEVEL;
	}

	if( m_nStatsFlags )
		SendMessageToClient( SMSG_PLAYERSTATSUPDATE );
}

// --------------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerObj::ToggleSpectatorMode()
//
//	PURPOSE:	Toggles spectator mode on or off.
//
// --------------------------------------------------------------------------- //
void CPlayerObj::ToggleSpectatorMode()
{
	CServerDE* pServerDE = GetServerDE();

	m_bSpectatorMode = !m_bSpectatorMode;
	SendMessageToClient(SMSG_SPECTATORMODE);

	// Kludge to fix problem with sinking through floor...
	if (m_bSpectatorMode)
	{
		DVector pos;
		

⌨️ 快捷键说明

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