📄 gameprojectiles.cpp
字号:
// ----------------------------------------------------------------------- //
DBOOL CNapalmFireball::Update(DVector *pMovement)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return DFALSE;
DVector vScale, vVel, vPos;
DFLOAT fTime = pServerDE->GetTime();
pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);
VEC_SET(vScale, 0.25f, 0.25f, 0.25f);
pServerDE->ScaleObject(m_hObject, &vScale);
if(m_nBounces >= 3)
return DFALSE;
if(m_bExplode)
{
Explode();
m_bExplode = DFALSE;
}
pServerDE->GetVelocity(m_hObject, &vVel);
pServerDE->GetObjectPos(m_hObject, &vPos);
if (m_hLight)
pServerDE->SetObjectPos(m_hLight, &vPos);
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CNapalmFireball::HandleTouch()
//
// PURPOSE: Handle touch notify message
//
// ----------------------------------------------------------------------- //
void CNapalmFireball::HandleTouch(HOBJECT hObj)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
// return if it hit a non solid object
if (hObj != pServerDE->GetWorldObject() && !(pServerDE->GetObjectFlags(hObj) & FLAG_SOLID)) // Ignore non-solid objects
return;
// return if it hit another of this same class
if (pServerDE->GetObjectClass(hObj) == pServerDE->GetObjectClass(m_hObject))
return;
m_nBounces++;
m_bExplode = DTRUE;
m_hHitObject = hObj;
// Cast a ray from our last known position to see what we hit
IntersectQuery iq;
IntersectInfo ii;
DVector vVel, vLift;
pServerDE->GetVelocity(m_hObject, &vVel);
VEC_COPY(vLift, vVel);
pServerDE->GetObjectPos(m_hObject, &m_LastPos);
VEC_COPY(iq.m_From, m_LastPos); // Get start point at the last known position.
VEC_MULSCALAR(iq.m_To, vVel, 1.1f);
VEC_ADD(iq.m_To, iq.m_To, iq.m_From); // Get destination point slightly past where we should be
iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
iq.m_FilterFn = NULL;
iq.m_pUserData = NULL;
if(pServerDE->IntersectSegment(&iq, &ii))
{
VEC_MULSCALAR(vVel, vVel, 0.35f);
pServerDE->SetVelocity(m_hObject, &vVel);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CNapalmFireball::AddExplosion()
//
// PURPOSE: Add an explosion
//
// ----------------------------------------------------------------------- //
void CNapalmFireball::AddExplosion(DVector vPos, DVector vNormal)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DDWORD nType = EXP_NAPALM_FIREBALL;
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\\c4\\explosion_1.wav", 1000.0f, SOUNDTYPE_MISC, SOUNDPRIORITY_MEDIUM);
}
BEGIN_CLASS(CBugSprayProjectile)
END_CLASS_DEFAULT_FLAGS(CBugSprayProjectile, CProjectile, NULL, NULL, CF_HIDDEN)
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBugSprayProjectile::CBugSprayProjectile()
//
// PURPOSE: Constructor
//
// ----------------------------------------------------------------------- //
CBugSprayProjectile::CBugSprayProjectile() : CProjectile(OT_SPRITE)
{
m_bShockwave = DFALSE;
m_bExplosion = DTRUE;
m_bClientFX = DFALSE;
m_pProjectileFilename = "Sprites\\napalmprime.spr";
m_pProjectileSkin = 0;
m_nDamageType = DAMAGE_TYPE_EXPLODE;
m_dwFlags = m_dwFlags | FLAG_GRAVITY | FLAG_POINTCOLLIDE | FLAG_NOSLIDING;
m_fStartTime = g_pServerDE->GetTime();
m_fLifeTime = 10.0f;
m_fDelay = 0.01f;
VEC_INIT(m_vInitScale);
m_dwTrailFXID = OBJFX_BUGSPRAY_1;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBugSprayProjectile::Update()
//
// PURPOSE: Do update
//
// ----------------------------------------------------------------------- //
DBOOL CBugSprayProjectile::Update(DVector *pMovement)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return DFALSE;
DBOOL bRet = CProjectile::Update(pMovement);
return bRet;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBugSprayProjectile::AddExplosion()
//
// PURPOSE: Add an explosion
//
// ----------------------------------------------------------------------- //
void CBugSprayProjectile::AddExplosion(DVector vPos, DVector vNormal)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DDWORD nType = EXP_BUGSPRAY_PRIMARY;
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\\Bugbuster\\impact.wav", 750.0f, SOUNDPRIORITY_MISC_MEDIUM);
}
BEGIN_CLASS(CBugSprayAltProjectile)
END_CLASS_DEFAULT_FLAGS(CBugSprayAltProjectile, CProjectile, NULL, NULL, CF_HIDDEN)
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBugSprayAltProjectile::CBugSprayAltProjectile()
//
// PURPOSE: Constructor
//
// ----------------------------------------------------------------------- //
CBugSprayAltProjectile::CBugSprayAltProjectile() : CProjectile(OT_SPRITE)
{
m_bShockwave = DFALSE;
m_bExplosion = DTRUE;
m_bClientFX = DFALSE;
m_pProjectileFilename = "Sprites\\napalmprime.spr";
m_pProjectileSkin = 0;
m_nDamageType = DAMAGE_TYPE_FIRE;
m_fStartTime = g_pServerDE->GetTime();
m_dwFlags = m_dwFlags | FLAG_GRAVITY | FLAG_POINTCOLLIDE | FLAG_NOSLIDING;
m_fLifeTime = 10.0f;
m_fDelay = 0.01f;
VEC_INIT(m_vInitScale);
m_dwTrailFXID = OBJFX_BUGSPRAY_2;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBugSprayAltProjectile::Update()
//
// PURPOSE: Do update
//
// ----------------------------------------------------------------------- //
DBOOL CBugSprayAltProjectile::Update(DVector *pMovement)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return DFALSE;
DBOOL bRet = CProjectile::Update(pMovement);
return bRet;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBugSprayAltProjectile::AddExplosion()
//
// PURPOSE: Add an explosion
//
// ----------------------------------------------------------------------- //
void CBugSprayAltProjectile::AddExplosion(DVector vPos, DVector vNormal)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DDWORD nType = EXP_BUGSPRAY_ALT;
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\\Bugbuster\\altimpact.wav", 750.0f, SOUNDPRIORITY_MISC_MEDIUM);
}
BEGIN_CLASS(CDeathRayProjectile)
END_CLASS_DEFAULT_FLAGS(CDeathRayProjectile, CProjectile, NULL, NULL, CF_HIDDEN)
// ----------------------------------------------------------------------- //
//
// ROUTINE: CDeathRayProjectile::CDeathRayProjectile()
//
// PURPOSE: Constructor
//
// ----------------------------------------------------------------------- //
CDeathRayProjectile::CDeathRayProjectile() : CProjectile(OT_NORMAL)
{
m_bShockwave = DFALSE;
m_bExplosion = DTRUE;
m_bClientFX = DFALSE;
m_nDamageType = DAMAGE_TYPE_ELECTRIC;
m_dwFlags = m_dwFlags | FLAG_POINTCOLLIDE;
m_fLifeTime = 0.0f;
m_fStartTime = 0.0f;
m_fBounceDist = 0.0f;
m_bFirstUpdate = DTRUE;
m_bFirstShot = DTRUE;
VEC_INIT(m_vInitScale);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CDeathRayProjectile::Update()
//
// PURPOSE: Do update
//
// ----------------------------------------------------------------------- //
DBOOL CDeathRayProjectile::Update(DVector *pMovement)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if(!pServerDE) return DFALSE;
pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);
if(m_bFirstUpdate)
{
DRotation rRot;
DVector vTemp;
// Find a forward vector to fire with...
pServerDE->GetObjectRotation(m_hObject, &rRot);
pServerDE->GetRotationVectors(&rRot, &vTemp, &vTemp, &m_vBeamDir);
m_bFirstUpdate = DFALSE;
}
// If it's time to reflect off of something... then cast a new ray
if(pServerDE->GetTime() - m_fStartTime > DEATHRAY_BOUNCE_DELAY)
{
IntersectQuery iq;
IntersectInfo ii;
DVector vDist;
// Set the start and dest points for the intersection
pServerDE->GetObjectPos(m_hObject, &(iq.m_From));
VEC_MULSCALAR(vDist, m_vBeamDir, 3000.0f)
VEC_ADD(iq.m_To, iq.m_From, vDist);
iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
iq.m_FilterFn = LiquidFilterFn;
iq.m_pUserData = NULL;
DBOOL bHit;
if(bHit = pServerDE->IntersectSegment(&iq, &ii))
{
if(m_bFirstShot && m_hFiredFrom == ii.m_hObject)
{
VEC_COPY(iq.m_From, ii.m_Point);
bHit = pServerDE->IntersectSegment(&iq, &ii);
}
}
m_bFirstShot = DFALSE;
// Test to see if we hit anything...
if(bHit)
{
HCLASS hObjClass = pServerDE->GetObjectClass(ii.m_hObject);
// Create the client side laser effect
HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&(iq.m_From));
pServerDE->WriteToMessageByte(hMessage, SFX_LASERBEAM_ID);
pServerDE->WriteToMessageVector(hMessage, &(iq.m_From));
pServerDE->WriteToMessageVector(hMessage, &(ii.m_Point));
pServerDE->WriteToMessageByte(hMessage, LASER_GREEN_SMALL);
pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED);
// Add a little effect and damage the object we hit
AddExplosion(ii.m_Point, ii.m_Plane.m_Normal);
DamageObject(m_hFiredFrom, this, ii.m_hObject, m_fDamage, vDist, ii.m_Point, m_nDamageType);
// If we hit a destructable object, don't reflect...
if(pServerDE->IsKindOf(hObjClass, pServerDE->GetClass("CBaseCharacter")))
return DFALSE;
// End the beam if we hit the sky (don't reflect)
SurfaceType eType = GetSurfaceType(ii.m_hObject, ii.m_hPoly);
if (eType == SURFTYPE_SKY)
return DFALSE;
// Add the distance to the bounce distance
VEC_SUB(vDist, ii.m_Point, iq.m_From);
m_fBounceDist += VEC_MAG(vDist);
if(m_fBounceDist > DEATHRAY_BOUNCE_DIST)
return DFALSE;
// Otherwise, find a new direction to reflect
pServerDE->TeleportObject(m_hObject, &ii.m_Point);
DVector vTemp;
VEC_COPY(vTemp, ii.m_Plane.m_Normal);
VEC_NORM(vDist);
VEC_NORM(vTemp);
// Calculate a reflection vector
DFLOAT dot = VEC_DOT(vTemp, vDist);
VEC_MULSCALAR(m_vBeamDir, vTemp, 2.0f * -dot);
VEC_ADD(m_vBeamDir, vDist, m_vBeamDir);
VEC_NORM(m_vBeamDir);
m_fStartTime = pServerDE->GetTime();
}
else
{
// We didn't hit anything... so create the beam from start to end
// Create the client side laser effect
HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&(iq.m_From));
pServerDE->WriteToMessageByte(hMessage, SFX_LASERBEAM_ID);
pServerDE->WriteToMessageVector(hMessage, &(iq.m_From));
pServerDE->WriteToMessageVector(hMessage, &(iq.m_To));
pServerDE->WriteToMessageByte(hMessage, LASER_GREEN_SMALL);
pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED);
return DFALSE;
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CDeathRayProjectile::AddExplosion()
//
// PURPOSE: Add an explosion
//
// ----------------------------------------------------------------------- //
void CDeathRayProjectile::AddExplosion(DVector vPos, DVector vNormal)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DDWORD nType = EXP_DEATHRAY_PRIMARY;
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\\laser\\impact.wav", 750.0f, SOUNDPRIORITY_MISC_MEDIUM);
}
BEGIN_CLASS(CLeechPrimeProjectile)
END_CLASS_DEFAU
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -