📄 gameprojectiles.cpp
字号:
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CGasGrenade::DamageAndWonky()
//
// PURPOSE: Damage people in the gas and give them wonky vision
//
// ----------------------------------------------------------------------- //
void CGasGrenade::DamageAndWonky(DFLOAT fWonkyTime)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
// Get the head of the list of destructable objects
DLink* pLink = CDestructable::m_DestructableHead.m_pNext;
if(!pLink || (pLink == &CDestructable::m_DestructableHead)) return;
HOBJECT hObj;
HCLASS hCharacter = pServerDE->GetClass("CBaseCharacter");
HCLASS hPlayer = pServerDE->GetClass("CPlayerObj");
HCLASS hObjClass = DNULL;
// Get a forward vector and position of the player who shot the voodoo doll
DVector vGrenadePos;
pServerDE->GetObjectPos(m_hObject, &vGrenadePos);
// Go through the list of destructable objects and look for people within your FOV
while(pLink != &CDestructable::m_DestructableHead)
{
hObj = ((CDestructable*)pLink->m_pData)->GetObject();
if(!hObj) break;
hObjClass = pServerDE->GetObjectClass(hObj);
if(pServerDE->IsKindOf(hObjClass, hCharacter))
{
DVector vObjPos, vDir;
DFLOAT fDist, fNewDamage;
// Test the angle between this object and us
pServerDE->GetObjectPos(hObj, &vObjPos);
VEC_SUB(vDir, vObjPos, vGrenadePos);
fDist = VEC_MAG(vDir);
// If the target is too far away... skip it
if(fDist > GAS_GRENADE_DAMAGE_DIST)
{ pLink = pLink->m_pNext; continue; }
fNewDamage = GAS_GRENADE_MAX_DAMAGE - (GAS_GRENADE_MAX_DAMAGE * (fDist / GAS_GRENADE_DAMAGE_DIST));
DamageObject(m_hFiredFrom, this, hObj, fNewDamage, vDir, vObjPos, DAMAGE_TYPE_NORMAL);
if(pServerDE->IsKindOf(hObjClass, hPlayer))
{
CPlayerObj *pHit = (CPlayerObj*)pServerDE->HandleToObject(hObj);
HMESSAGEWRITE hMsg = pServerDE->StartMessage(pHit->GetClient(), SMSG_WONKYVISION);
pServerDE->WriteToMessageFloat(hMsg, fWonkyTime);
pServerDE->WriteToMessageByte(hMsg, 0); // bNoMove = DFALSE
pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLE);
}
}
pLink = pLink->m_pNext;
}
}
#endif
#ifndef _DEMO
BEGIN_CLASS(CTimeBomb)
END_CLASS_DEFAULT_FLAGS(CTimeBomb, CProjectile, NULL, NULL, CF_HIDDEN)
// ----------------------------------------------------------------------- //
//
// ROUTINE: CTimeBomb::CTimeBomb()
//
// PURPOSE: Constructor
//
// ----------------------------------------------------------------------- //
CTimeBomb::CTimeBomb() : CProjectile()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
m_bShockwave = DFALSE;
m_bExplosion = DTRUE;
m_pProjectileFilename = "Models\\Ammo\\c4.abc";
m_pProjectileSkin = "Skins\\Ammo\\c4_time.dtx";
m_nDamageType = DAMAGE_TYPE_EXPLODE;
m_dwFlags = m_dwFlags | FLAG_GRAVITY;
m_bArmed = DFALSE;
m_bExplode = DFALSE;
m_fStartTime = 0.0f;
m_fTimeDelay = 5.0f;
// Set up angular velocities
m_fPitch = 0.0f;
m_fYaw = 0.0f;
m_fPitchVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);
m_fYawVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);
m_damage.SetDeathDelay(0.25f); // .25 second delay if killed by explosion
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CTimeBomb::Update()
//
// PURPOSE: Do update
//
// ----------------------------------------------------------------------- //
DBOOL CTimeBomb::Update(DVector *pMovement)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return DFALSE;
pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);
DFLOAT fTime = pServerDE->GetTime();
pServerDE->GetObjectPos(m_hObject, &m_LastPos);
if(m_bExplode || m_damage.IsDead())
{
Explode();
return DFALSE;
}
if(m_bArmed)
{
DVector vVel;
VEC_INIT(vVel);
pServerDE->SetVelocity(m_hObject, &vVel);
// Count down to explode time
if (fTime > m_fStartTime + m_fTimeDelay)
m_bExplode = DTRUE;
}
else
{
DRotation rRot;
pServerDE->GetObjectRotation(m_hObject, &rRot);
// Rotate the object as it flys through the air
if (m_fPitchVel != 0 || m_fYawVel != 0)
{
DFLOAT fDeltaTime = pServerDE->GetFrameTime();
m_fPitch += m_fPitchVel * fDeltaTime;
m_fYaw += m_fYawVel * fDeltaTime;
pServerDE->SetupEuler(&rRot, m_fPitch, m_fYaw, 0.0f);
pServerDE->SetObjectRotation(m_hObject, &rRot);
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CTimeBomb::HandleTouch()
//
// PURPOSE: Handle touch notify message
//
// ----------------------------------------------------------------------- //
void CTimeBomb::HandleTouch(HOBJECT hObj)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
if(m_bArmed)
return;
if(hObj == m_hFiredFrom)
return;
if(hObj != pServerDE->GetWorldObject() && !(pServerDE->GetObjectFlags(hObj) & FLAG_SOLID))
return;
if (pServerDE->IsKindOf(pServerDE->GetObjectClass(hObj), pServerDE->GetClass("CBaseCharacter")))
{
CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(hObj);
if(pObj->IsDead()) return;
CProjectile::HandleTouch(hObj); // Explode on impact type.
}
else
{
CollisionInfo colInfo;
pServerDE->GetLastCollision( &colInfo );
DVector vU, vR, vF;
DRotation rRot;
VEC_SET(vU, 0.0f, 1.0f, 0.0f);
pServerDE->AlignRotation(&rRot, &colInfo.m_Plane.m_Normal, &vU);
pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
pServerDE->RotateAroundAxis(&rRot, &vR, MATH_PI * 0.5f);
pServerDE->SetObjectRotation(m_hObject, &rRot);
DDWORD dwFlags = pServerDE->GetObjectFlags(m_hObject);
dwFlags &= ~FLAG_GRAVITY;
pServerDE->SetObjectFlags(m_hObject, dwFlags);
m_bArmed = DTRUE;
m_fStartTime = pServerDE->GetTime();
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CTimeBomb::AddExplosion()
//
// PURPOSE: Add an explosion
//
// ----------------------------------------------------------------------- //
void CTimeBomb::AddExplosion(DVector vPos, DVector vNormal)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DDWORD nType = EXP_DEFAULT_SMALL;
HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&vPos);
pServerDE->WriteToMessageByte(hMessage, SFX_EXPLOSIONFX_ID);
pServerDE->WriteToMessageVector(hMessage, &vPos);
pServerDE->WriteToMessageVector(hMessage, &vNormal);
pServerDE->WriteToMessageDWord(hMessage, nType);
pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED);
PlaySoundFromPos(&vPos, "Sounds\\Weapons\\time\\explode.wav", 1000.0f, SOUNDPRIORITY_MISC_MEDIUM);
}
BEGIN_CLASS(CProximityBomb)
END_CLASS_DEFAULT_FLAGS(CProximityBomb, CProjectile, NULL, NULL, CF_HIDDEN)
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProximityBomb::CProximityBomb()
//
// PURPOSE: Constructor
//
// ----------------------------------------------------------------------- //
CProximityBomb::CProximityBomb() : CProjectile()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
m_bShockwave = DFALSE;
m_bExplosion = DTRUE;
m_pProjectileFilename = "Models\\Ammo\\c4.abc";
m_pProjectileSkin = "Skins\\Ammo\\c4_prox.dtx";
m_nDamageType = DAMAGE_TYPE_EXPLODE;
m_dwFlags = m_dwFlags | FLAG_GRAVITY;
m_bArmed = DFALSE;
m_bExplode = DFALSE;
m_fStartTime = 0.0f;
m_fDetectRadius = 225.0f;
m_fGetAwayTime = 0.75f;
m_fExplodeDelay = 0.5f;
m_bHitCharacter = DFALSE;
m_bPlayArmSound = DTRUE;
m_bPlayDetectSound = DTRUE;
// Set up angular velocities
m_fPitch = 0.0f;
m_fYaw = 0.0f;
m_fPitchVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);
m_fYawVel = pServerDE->Random(-MATH_CIRCLE, MATH_CIRCLE);
m_damage.SetDeathDelay(0.25f); // .25 second delay if killed by explosion
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProximityBomb::Update()
//
// PURPOSE: Do update
//
// ----------------------------------------------------------------------- //
DBOOL CProximityBomb::Update(DVector *pMovement)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return DFALSE;
pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);
DFLOAT fTime = pServerDE->GetTime();
pServerDE->GetObjectPos(m_hObject, &m_LastPos);
if(m_bExplode || m_damage.IsDead())
{
if(!m_bHitCharacter && (pServerDE->GetTime() < m_fStartTime + m_fExplodeDelay) && !m_damage.IsDead())
{
if(m_bPlayDetectSound)
{
PlaySoundFromPos(&m_LastPos, "Sounds\\Weapons\\proximities\\detect.wav", 500.0f, SOUNDPRIORITY_MISC_MEDIUM);
m_bPlayDetectSound = DFALSE;
}
return DTRUE;
}
else
{
Explode();
return DFALSE;
}
}
if(m_bArmed)
{
DVector vVel;
VEC_INIT(vVel);
pServerDE->SetVelocity(m_hObject, &vVel);
if(m_hFiredFrom)
{
HCLASS hClass = pServerDE->GetObjectClass(m_hFiredFrom);
if(pServerDE->IsKindOf(hClass, pServerDE->GetClass("AI_Mgr")))
m_fGetAwayTime = 2.0f;
}
// Wait a little while before going into detect mode
if(pServerDE->GetTime() < m_fStartTime + m_fGetAwayTime)
return DTRUE;
else if(m_bPlayArmSound)
{
PlaySoundFromPos(&m_LastPos, "Sounds\\Weapons\\proximities\\arm.wav", 500.0f, SOUNDPRIORITY_MISC_MEDIUM);
m_bPlayArmSound = DFALSE;
}
// Check to see if there's anyone in our radius of detection, then blow up
// Get the head of the list of destructable objects
DLink* pLink = CDestructable::m_DestructableHead.m_pNext;
if(!pLink || (pLink == &CDestructable::m_DestructableHead)) return DTRUE;
// Work with the squares of the distances so as to not have to get a square root.
HOBJECT hObj;
DVector vProxPos;
DFLOAT fRadiusSqr = m_fDetectRadius * m_fDetectRadius;
pServerDE->GetObjectPos(m_hObject, &vProxPos);
while(pLink != &CDestructable::m_DestructableHead)
{
hObj = ((CDestructable*)pLink->m_pData)->GetObject();
if(!hObj) break;
if(pServerDE->IsKindOf(pServerDE->GetObjectClass(hObj), pServerDE->GetClass("CBaseCharacter")))
{
CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(hObj);
if(!pObj->IsDead())
{
DVector vDir, vPos;
DFLOAT fDistSqr;
pServerDE->GetObjectPos(hObj, &vPos);
VEC_SUB(vDir, vPos, vProxPos);
fDistSqr = VEC_MAGSQR(vDir);
if(fDistSqr <= fRadiusSqr)
{
m_bExplode = DTRUE;
m_fStartTime = pServerDE->GetTime();
break;
}
}
}
pLink = pLink->m_pNext;
}
}
else
{
DRotation rRot;
pServerDE->GetObjectRotation(m_hObject, &rRot);
// Rotate the object as it flys through the air
if (m_fPitchVel != 0 || m_fYawVel != 0)
{
DFLOAT fDeltaTime = pServerDE->GetFrameTime();
m_fPitch += m_fPitchVel * fDeltaTime;
m_fYaw += m_fYawVel * fDeltaTime;
pServerDE->SetupEuler(&rRot, m_fPitch, m_fYaw, 0.0f);
pServerDE->SetObjectRotation(m_hObject, &rRot);
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProximityBomb::HandleTouch()
//
// PURPOSE: Handle touch notify message
//
// ----------------------------------------------------------------------- //
void CProximityBomb::HandleTouch(HOBJECT hObj)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if(!pServerDE) return;
if(m_bArmed)
return;
if(hObj == m_hFiredFrom)
return;
if(hObj != pServerDE->GetWorldObject() && !(pServerDE->GetObjectFlags(hObj) & FLAG_SOLID))
return;
if(pServerDE->IsKindOf(pServerDE->GetObjectClass(hObj), pServerDE->GetClass("CBaseCharacter")))
{
CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(hObj);
if(pObj->IsDead()) return;
CProjectile::HandleTouch(hObj); // Explode on impact type.
m_bHitCharacter = DTRUE;
}
else
{
CollisionInfo colInfo;
pServerDE->GetLastCollision( &colInfo );
DVector vU, vR, vF;
DRotation rRot;
VEC_SET(vU, 0.0f, 1.0f, 0.0f);
pServerDE->AlignRotation(&rRot, &colInfo.m_Plane.m_Normal, &vU);
pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
pServerDE->RotateAroundAxis(&rRot, &vR, MATH_PI * 0.5f);
pServerDE->SetObjectRotation(m_hObject, &rRot);
DDWORD dwFlags = pServerDE->GetObjectFlags(m_hObject);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -