📄 destructable.cpp
字号:
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 + -