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

📄 destructable.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		if(pObj->IsTrapped()) return;
	}

	if (VEC_MAGSQR(*pvDir) < 0.01) return;

	DVector vTemp, vVel;

	pServerDE->GetVelocity(m_hObject, &vVel);

	VEC_COPY(vTemp, *pvDir);
	VEC_NORM(vTemp);

	if (m_fMass <= 0) m_fMass = 1;
	
	DFLOAT fMultiplier = (fDamage * PA_DAMAGE_VEL_MUTLIPLIER) / m_fMass;

	VEC_MULSCALAR(vTemp, vTemp, fMultiplier);
	VEC_ADD(vVel, vTemp, vVel);

	// Accumulate damage velocity for player objects to send to the client..
	if (IsPlayer(m_hObject))
	{
		VEC_ADD(m_vAddVelocity, m_vAddVelocity, vTemp);
		m_bAddVelocity = DTRUE;
	}

	pServerDE->SetVelocity(m_hObject, &vVel);
}



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

void CDestructable::HandleDestruction()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	if (m_hstrDeathTriggerTarget)
	{
		LPBASECLASS pD = pServerDE->HandleToObject(m_hObject);
		SendTriggerMsgToObjects(pD, m_hstrDeathTriggerTarget, m_hstrDeathTriggerMessage);
	}

	// See if we need to spawn anything
	if (m_hstrSpawnObject)
	{
		DVector vPos;
		DRotation rRot;

		pServerDE->GetObjectPos(m_hObject, &vPos);
		pServerDE->GetObjectRotation(m_hObject, &rRot);

		SpawnObject(pServerDE->GetStringData(m_hstrSpawnObject), &vPos, &rRot, &m_vSpawnObjectVel);
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::HandleHeal
//
//	PURPOSE:	Handle heal message.
// 
// ----------------------------------------------------------------------- //

void CDestructable::HandleHeal(HOBJECT hSender, HMESSAGEREAD hRead)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	DFLOAT fAmount = pServerDE->ReadFromMessageFloat(hRead);

	Heal(fAmount);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::Heal
//
//	PURPOSE:	Add some value to hit points
// 
// ----------------------------------------------------------------------- //

DBOOL CDestructable::Heal(DFLOAT fAmount)
{
	// Sanity checks...

	if (m_fHitPoints >= m_fMaxHitPoints)
		return DFALSE;


	// Check if this is a humiliated player in a multiplayer game...

	if (g_pBloodServerShell->IsMultiplayerGame())
	{
		if (IsPlayer(m_hObject))
		{
			CPlayerObj* pPlayer = (CPlayerObj*)g_pServerDE->HandleToObject(m_hObject);
			if (pPlayer && pPlayer->IsInSlowDeath())
			{
				return(DFALSE);
			}
		}
	}


	// Heal...

	m_bDead = DFALSE;

	m_fHitPoints += fAmount;
	if(m_fHitPoints > m_fMaxHitPoints)
		m_fHitPoints = m_fMaxHitPoints;
	m_fDeathHitPoints = m_fHitPoints;


	// All done...

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::MegaHeal
//
//	PURPOSE:	Add some value to hit points
// 
// ----------------------------------------------------------------------- //

DBOOL CDestructable::MegaHeal(DFLOAT fAmount)
{
	if (m_fHitPoints >= m_fMaxMegaHitPoints)
		return DFALSE;

	m_bDead = DFALSE;

	m_fHitPoints += fAmount;
	if(m_fHitPoints > m_fMaxMegaHitPoints)
		m_fHitPoints = m_fMaxMegaHitPoints;
	m_fDeathHitPoints = m_fHitPoints;
	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::HandleRepair()
//
//	PURPOSE:	Handle Repair message
//
// ----------------------------------------------------------------------- //

void CDestructable::HandleRepair(HOBJECT hSender, HMESSAGEREAD hRead)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	DFLOAT fAmount = pServerDE->ReadFromMessageFloat(hRead);

	AddWard(fAmount);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::AddWard()
//
//	PURPOSE:	Add some value to armor
//
// ----------------------------------------------------------------------- //
DBOOL CDestructable::AddWard(DFLOAT fAmount)
{
	if (m_fArmorPoints >= m_fMaxArmorPoints)
		return DFALSE;

	m_fArmorPoints += fAmount;

	if(m_fArmorPoints > m_fMaxArmorPoints) 
		m_fArmorPoints = m_fMaxArmorPoints;

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::AddNecroWard()
//
//	PURPOSE:	Add some value to armor
//
// ----------------------------------------------------------------------- //
DBOOL CDestructable::AddNecroWard(DFLOAT fAmount)
{
	if (m_fArmorPoints >= m_fMaxNecroArmorPoints)
		return DFALSE;

	m_fArmorPoints += fAmount;

	if(m_fArmorPoints > m_fMaxNecroArmorPoints) 
		m_fArmorPoints = m_fMaxNecroArmorPoints;

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::Reset
//
//	PURPOSE:	Reset
//
// ----------------------------------------------------------------------- //

void CDestructable::Reset()
{
	AddWard(m_fMaxArmorPoints);
	Heal(m_fMaxHitPoints);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::Save
//
//	PURPOSE:	Save the object
//
// ----------------------------------------------------------------------- //

void CDestructable::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !hWrite) return;
	pServerDE->WriteToMessageDWord(hWrite, 0xcececece);

	pServerDE->WriteToLoadSaveMessageObject(hWrite, m_hObject);
	pServerDE->WriteToMessageByte(hWrite, (DBYTE)m_bApplyDamagePhysics);
	pServerDE->WriteToMessageFloat(hWrite, m_fMass);
	pServerDE->WriteToMessageFloat(hWrite, m_fMaxHitPoints);
	pServerDE->WriteToMessageFloat(hWrite, m_fMaxMegaHitPoints);
	if( m_bDestructable )
		pServerDE->WriteToMessageFloat(hWrite, m_fHitPoints);
	else
		pServerDE->WriteToMessageFloat( hWrite, 1.0e6f );
	pServerDE->WriteToMessageFloat(hWrite, m_fDeathHitPoints);

	pServerDE->WriteToMessageFloat(hWrite, m_fMaxArmorPoints);
	pServerDE->WriteToMessageFloat(hWrite, m_fMaxNecroArmorPoints);
	pServerDE->WriteToMessageFloat(hWrite, m_fArmorPoints);
	pServerDE->WriteToMessageFloat(hWrite, m_fResistance);
	pServerDE->WriteToMessageByte(hWrite, (DBYTE)m_bDead);
	pServerDE->WriteToMessageByte(hWrite, (DBYTE)m_bNighInvulnerable);

	pServerDE->WriteToMessageByte(hWrite, m_nLastDamageType);
	pServerDE->WriteToMessageByte(hWrite, m_nLastDamageLocation);

	pServerDE->WriteToMessageVector(hWrite, &m_vLastDamageDirection);
	pServerDE->WriteToMessageFloat(hWrite, m_fLastDamageAmount);
	pServerDE->WriteToMessageFloat(hWrite, m_fLastDamagePercent);
	pServerDE->WriteToMessageHString(hWrite, m_hstrDamageTriggerTarget);
	pServerDE->WriteToMessageHString(hWrite, m_hstrDamageTriggerMessage);
	pServerDE->WriteToMessageHString(hWrite, m_hstrDeathTriggerTarget);
	pServerDE->WriteToMessageHString(hWrite, m_hstrDeathTriggerMessage);

	pServerDE->WriteToMessageHString(hWrite, m_hstrSpawnObject);
	pServerDE->WriteToMessageVector(hWrite, &m_vSpawnObjectVel);

	pServerDE->WriteToMessageByte(hWrite, m_bGodMode);
	pServerDE->WriteToMessageByte(hWrite, m_bTriggerOnly);

	pServerDE->WriteToMessageFloat(hWrite, m_fDeathDelay);

	pServerDE->WriteToMessageDWord(hWrite, 0xcececece);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::Load
//
//	PURPOSE:	Load the object
//
// ----------------------------------------------------------------------- //

void CDestructable::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !hRead) return;

	DDWORD dwTest						= pServerDE->ReadFromMessageDWord(hRead);

	// Gross hack because PlayerObj hObject deoesn't seem to be loaded.
	// Don't reload m_hObject if it is already set to something.
	HOBJECT hObjectTmp;
	if (!m_hObject)
		pServerDE->ReadFromLoadSaveMessageObject(hRead, &m_hObject);
	else
		pServerDE->ReadFromLoadSaveMessageObject(hRead, &hObjectTmp);
	m_bApplyDamagePhysics		= (DBOOL)pServerDE->ReadFromMessageByte(hRead);
	m_fMass						= pServerDE->ReadFromMessageFloat(hRead);
	m_fMaxHitPoints				= pServerDE->ReadFromMessageFloat(hRead);
	m_fMaxMegaHitPoints			= pServerDE->ReadFromMessageFloat(hRead);
	m_fHitPoints				= pServerDE->ReadFromMessageFloat(hRead);
	m_fDeathHitPoints			= pServerDE->ReadFromMessageFloat(hRead);

	m_fMaxArmorPoints			= pServerDE->ReadFromMessageFloat(hRead);
	m_fMaxNecroArmorPoints		= pServerDE->ReadFromMessageFloat(hRead);
	m_fArmorPoints				= pServerDE->ReadFromMessageFloat(hRead);
	m_fResistance				= pServerDE->ReadFromMessageFloat(hRead);
	m_bDead						= (DBOOL)pServerDE->ReadFromMessageByte(hRead);
	m_bNighInvulnerable			= (DBOOL)pServerDE->ReadFromMessageByte(hRead);

	m_nLastDamageType			= pServerDE->ReadFromMessageByte(hRead);
	m_nLastDamageLocation		= pServerDE->ReadFromMessageByte(hRead);
	pServerDE->ReadFromMessageVector(hRead, &m_vLastDamageDirection);
	m_fLastDamageAmount			= pServerDE->ReadFromMessageFloat(hRead);
	m_fLastDamagePercent		= pServerDE->ReadFromMessageFloat(hRead);
	m_hstrDamageTriggerTarget	= pServerDE->ReadFromMessageHString(hRead);
	m_hstrDamageTriggerMessage	= pServerDE->ReadFromMessageHString(hRead);
	m_hstrDeathTriggerTarget	= pServerDE->ReadFromMessageHString(hRead);
	m_hstrDeathTriggerMessage	= pServerDE->ReadFromMessageHString(hRead);

	m_hstrSpawnObject			= pServerDE->ReadFromMessageHString(hRead);
	pServerDE->ReadFromMessageVector(hRead, &m_vSpawnObjectVel);

	m_bGodMode					= pServerDE->ReadFromMessageByte(hRead);
	m_bTriggerOnly				= pServerDE->ReadFromMessageByte(hRead);

	m_fDeathDelay				= pServerDE->ReadFromMessageFloat(hRead);

	m_bDestructable = ( m_fHitPoints >= 1.0e6f ) ? DFALSE : DTRUE;

	dwTest						= pServerDE->ReadFromMessageDWord(hRead);

	if (!m_Link.m_pData)
	{
		dl_Insert( &m_DestructableHead, &m_Link );
		m_Link.m_pData = ( void * )this;
		m_dwNumDestructables++;
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::IsPlayerToPlayerDamageOk
//
//	PURPOSE:	Determines if it's ok for a player to damage this player
//
// ----------------------------------------------------------------------- //

DBOOL CDestructable::IsPlayerToPlayerDamageOk(HOBJECT hDamager, HOBJECT hOwner)
{
	// Sanity checks...

	if (m_hObject == hDamager) return(DTRUE);
	if (m_hObject == hOwner) return(DTRUE);


	// Check if we are playing a multiplayer game that has the right options set...

	if (!g_pBloodServerShell->IsMultiplayerTeamBasedGame()) return(DTRUE);
	if (g_pBloodServerShell->GetNetGameInfo()->m_bFriendlyFire) return(DTRUE);


	// Make sure we're a player...

	if (!IsPlayer(m_hObject)) return(DTRUE);


	// Get the attacker player for this damager or projectile...

	HOBJECT hHitter = DNULL;

	if (IsPlayer(hDamager))
	{
		hHitter = hDamager;
	}
	else if (IsPlayer(hOwner))
	{
		hHitter = hOwner;
	}

	if (!hHitter) return(DTRUE);


	// Get the player pointers...

	CPlayerObj* pVictim = (CPlayerObj*)g_pServerDE->HandleToObject(m_hObject);
	if (!pVictim) return(DTRUE);

	CPlayerObj* pDamager = (CPlayerObj*)g_pServerDE->HandleToObject(hHitter);
	if (!pDamager) return(DTRUE);


	// Check if these players are on the same team...

	if (pVictim->GetTeamID() == pDamager->GetTeamID()) return(DFALSE);


	// If we get here, it's ok to do the damage...

	return(DTRUE);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDestructable::SetStartingCharacterValues
//
//	PURPOSE:	Sets the starting values for a player character
//
// ----------------------------------------------------------------------- //

void CDestructable::SetStartingCharacterValues()
{
	// Sanity checks...

	if (!m_hObject) return;
	if (!IsPlayer(m_hObject)) return;


	// Set the health...

	m_fHitPoints = 100;


	// Set the armor...

	m_fArmorPoints = 0;
}






⌨️ 快捷键说明

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