📄 projectile.cpp
字号:
if (m_hHitObject)
{
g_pServerDE->BreakInterObjectLink(m_hObject, m_hHitObject);
m_hHitObject = DFALSE;
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::DamageObjectsWithinRadius()
//
// PURPOSE: Damage the objects within our radius
//
// ----------------------------------------------------------------------- //
void CProjectile::DamageObjectsWithinRadius()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DVector vPos;
pServerDE->GetObjectPos(m_hObject, &vPos);
DFLOAT fRadius = (DFLOAT)m_nRadius;
DamageObjectsInRadius(m_hFiredFrom, this, vPos, fRadius, m_fDamage, m_nDamageType);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::AddImpact()
//
// PURPOSE: Add impact objects
//
// ----------------------------------------------------------------------- //
void CProjectile::AddImpact(DVector vPoint, DVector vNormal, HOBJECT hObj)
{
// Compute a normal vector
// Cast a ray to see what we hit
DVector tempPos;
IntersectQuery iq;
IntersectInfo ii;
SurfaceType eType = SURFTYPE_UNKNOWN;
DBYTE nFX = 0;
VEC_NORM(m_vDir);
VEC_MULSCALAR(m_vDir, m_vDir, 2.0f);
VEC_SUB(iq.m_From, vPoint, m_vDir);
VEC_MULSCALAR(m_vDir, m_vDir, 10.0f);
VEC_ADD(iq.m_To, vPoint, m_vDir);
iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
iq.m_FilterFn = NULL;
iq.m_pUserData = NULL;
if (hObj && g_pServerDE->IntersectSegment(&iq, &ii))
{
VEC_COPY(vNormal, ii.m_Plane.m_Normal);
eType = GetSurfaceType(ii.m_hObject, ii.m_hPoly);
VEC_COPY(tempPos, ii.m_Point);
}
else // Fake it
{
VEC_NEGATE(vNormal, m_vDir);
VEC_COPY(tempPos, vPoint);
}
if(m_bExplosion)
{
AddExplosion(tempPos, vNormal);
nFX |= WFX_SCREENSHAKE;
}
if(m_bClientFX)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
/* ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
VEC_COPY(theStruct.m_Pos, vPoint);
HCLASS hClass = pServerDE->GetClass("CClientWeaponSFX");
CClientWeaponSFX *pWeaponFX = DNULL;
if(hClass)
pWeaponFX = (CClientWeaponSFX*)pServerDE->CreateObject(hClass, &theStruct);
*/
DDWORD nFX = WFX_SCREENSHAKE;
DDWORD nExtras = WFX_EXTRA_DAMAGE;
WeaponFXExtras ext;
ext.fDamage = m_fDamage;
// if(pWeaponFX)
SendWeaponSFXMessage(&vPoint, &vPoint, &vNormal, &vNormal, nFX, nExtras, &ext);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::AddBloodImpact()
//
// PURPOSE: Add blood impacts objects
//
// ----------------------------------------------------------------------- //
void CProjectile::AddBloodImpact(DVector *vPos, DVector *vNormal, DFLOAT fDamage)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
/* ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
VEC_COPY(theStruct.m_Pos, *vPos);
HCLASS hClass = pServerDE->GetClass("CClientWeaponSFX");
CClientWeaponSFX *pWeaponFX = DNULL;
if(hClass)
pWeaponFX = (CClientWeaponSFX*)pServerDE->CreateObject(hClass, &theStruct);
*/
DDWORD nFX = WFX_BLOODSPURT | WFX_SPARKS;
DDWORD nExtras = WFX_EXTRA_DAMAGE | WFX_EXTRA_SURFACETYPE;
WeaponFXExtras ext;
ext.fDamage = fDamage;
ext.nSurface = (DBYTE)SURFTYPE_FLESH;
// if(pWeaponFX)
SendWeaponSFXMessage(vPos, vPos, vNormal, vNormal, nFX, nExtras, &ext);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::AddExplosion()
//
// PURPOSE: Add an explosion
//
// ----------------------------------------------------------------------- //
void CProjectile::AddExplosion(DVector vPos, DVector vNormal)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DDWORD nType = EXP_GRENADE;
DVector vUp;
VEC_SET(vUp, 0.0f, 1.0f, 0.0f);
HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&vPos);
pServerDE->WriteToMessageByte(hMessage, SFX_EXPLOSIONFX_ID);
pServerDE->WriteToMessageVector(hMessage, &vPos);
pServerDE->WriteToMessageVector(hMessage, &vUp);
pServerDE->WriteToMessageDWord(hMessage, nType);
pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
PlaySoundFromPos(&vPos, "Sounds\\Weapons\\c4\\explosion_1.wav", 1000.0f, SOUNDPRIORITY_MISC_MEDIUM);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::AddSmokeTrail()
//
// PURPOSE: Add a client-side smoke trail
//
// ----------------------------------------------------------------------- //
void CProjectile::AddSmokeTrail(DVector vVel)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
ObjectCreateStruct theStruct;
INIT_OBJECTCREATESTRUCT(theStruct);
DVector vPos;
pServerDE->GetObjectPos(m_hObject, &vPos);
VEC_COPY(theStruct.m_Pos, vPos);
HCLASS hClass = pServerDE->GetClass("CClientSmokeTrail");
CClientSmokeTrail* pTrail = DNULL;
if (hClass)
{
pTrail = (CClientSmokeTrail*)pServerDE->CreateObject(hClass, &theStruct);
}
if (pTrail)
{
pTrail->Setup(vVel, DTRUE);
m_hSmokeTrail = pTrail->m_hObject;
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::AddLight()
//
// PURPOSE: Add a dynamic light
//
// ----------------------------------------------------------------------- //
void CProjectile::AddLight(DFLOAT fRadius, DFLOAT fRed, DFLOAT fGreen, DFLOAT fBlue)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
m_vLightColor.x = fRed;
m_vLightColor.y = fGreen;
m_vLightColor.z = fBlue;
if (fRadius)
{
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
ocStruct.m_Flags = FLAG_VISIBLE;
ocStruct.m_ObjectType = OT_LIGHT;
HCLASS hClass = pServerDE->GetClass("BaseClass");
LPBASECLASS pFlash = pServerDE->CreateObject(hClass, &ocStruct);
if (pFlash)
{
m_hLight = pFlash->m_hObject;
pServerDE->SetLightRadius(m_hLight, fRadius);
pServerDE->SetLightColor(m_hLight, m_vLightColor.x, m_vLightColor.y, m_vLightColor.z);
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::AddSparks
//
// PURPOSE: Add impact sparks
//
// ----------------------------------------------------------------------- //
void CProjectile::AddSparks(DVector vPos, DVector vNormal, DFLOAT fDamage, HOBJECT hObject)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
VEC_COPY(ocStruct.m_Pos, vPos);
HCLASS hClass = pServerDE->GetClass("CClientSparksSFX");
CClientSparksSFX *pSpark = DNULL;
if (hClass)
{
pSpark = (CClientSparksSFX *)pServerDE->CreateObject(hClass, &ocStruct);
}
if (pSpark)
{
DVector vColor1, vColor2;
char* pFile;
DBYTE nSparks = (DBYTE)fDamage;
SurfaceType eType = GetSurfaceType(hObject, DNULL);
switch(eType)
{
case SURFTYPE_FLESH:
{
VEC_SET(vColor1, 200.0f, 0.0f, 0.0f);
VEC_SET(vColor2, 255.0f, 0.0f, 0.0f);
pFile = "spritetextures\\particle1.dtx";
pSpark->Setup(&vNormal, &vColor1, &vColor2, pFile, nSparks, 0.6f, 2.0f, 500.0f);
break;
}
default:
{
VEC_SET(vColor1, 200.0f, 200.0, 200.0f);
VEC_SET(vColor2, 200.0f, 200.0f, 0.0f);
pFile = "spritetextures\\particle1.dtx";
pSpark->Setup(&vNormal, &vColor1, &vColor2, pFile, nSparks, 0.4f, 2.0f, 500.0f);
break;
}
}
}
return;
}
/*
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::GetSurfaceType
//
// PURPOSE: Determines the surface type of a hit object
//
// ----------------------------------------------------------------------- //
SurfaceType CProjectile::GetSurfaceType(HOBJECT hObject)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !hObject) return ST_UNKNOWN;
SurfaceType eType = ST_UNKNOWN;
if (pServerDE->GetWorldObject() == hObject)
{
eType = ST_WORLD;
}
else
{
HCLASS hObjClass = pServerDE->GetObjectClass(hObject);
HCLASS hCharacter = pServerDE->GetClass("CBaseCharacter");
if (pServerDE->IsKindOf(hObjClass, hCharacter))
{
eType = ST_CHARACTER;
}
}
return eType;
}
*/
void CProjectile::SetFlags(DDWORD dwFlags)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
m_dwFlags = dwFlags;
pServerDE->SetObjectFlags(m_hObject, m_dwFlags);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::Save
//
// PURPOSE: Save the object
//
// ----------------------------------------------------------------------- //
void CProjectile::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hWrite) return;
DFLOAT fTime = pServerDE->GetTime();
pServerDE->WriteToMessageVector(hWrite, &m_vDir);
pServerDE->WriteToMessageFloat(hWrite, m_fVelocity);
pServerDE->WriteToMessageDWord(hWrite, m_dwFlags);
pServerDE->WriteToMessageByte(hWrite, m_nDamageType);
// HOBJECT m_hFiredFrom; // Who fired us? Can't tell
pServerDE->WriteToMessageDWord(hWrite, m_nRadius);
pServerDE->WriteToMessageFloat(hWrite, m_fStartTime - fTime);
pServerDE->WriteToMessageByte(hWrite, m_bRemoveFromWorld);
pServerDE->WriteToMessageFloat(hWrite, m_fDamage);
pServerDE->WriteToMessageFloat(hWrite, m_fLifeTime);
pServerDE->WriteToMessageDWord(hWrite, m_nDamageMsgID);
// DBOOL m_bSmokeTrail; // Do we generate a smoke trail
pServerDE->WriteToMessageByte(hWrite, m_bShockwave);
pServerDE->WriteToMessageByte(hWrite, m_bExplosion);
pServerDE->WriteToMessageByte(hWrite, m_bSparks);
pServerDE->WriteToMessageVector(hWrite, &m_vShockwaveScaleMin);
pServerDE->WriteToMessageVector(hWrite, &m_vShockwaveScaleMax);
pServerDE->WriteToMessageVector(hWrite, &m_vLightColor);
pServerDE->WriteToMessageFloat(hWrite, m_fShockwaveDuration);
pServerDE->WriteToMessageHString(hWrite,m_hstrShockwaveFilename);
pServerDE->WriteToMessageVector(hWrite, &m_vDims);
pServerDE->WriteToMessageByte(hWrite, m_bExplode);
// Special members
pServerDE->WriteToMessageVector(hWrite, &m_LastPos);
pServerDE->WriteToMessageByte(hWrite, m_bArmed);
pServerDE->WriteToMessageFloat(hWrite, m_fPitchVel);
pServerDE->WriteToMessageFloat(hWrite, m_fYawVel);
pServerDE->WriteToMessageFloat(hWrite, m_fPitch);
pServerDE->WriteToMessageFloat(hWrite, m_fYaw);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CProjectile::Load
//
// PURPOSE: Load the object
//
// ----------------------------------------------------------------------- //
void CProjectile::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hRead) return;
DFLOAT fTime = pServerDE->GetTime();
pServerDE->ReadFromMessageVector(hRead, &m_vDir);
m_fVelocity = pServerDE->ReadFromMessageFloat(hRead);
m_dwFlags = pServerDE->ReadFromMessageDWord(hRead);
m_nDamageType = pServerDE->ReadFromMessageByte(hRead);
// HOBJECT m_hFiredFrom; // Who fired us? Can't tell
m_nRadius = pServerDE->ReadFromMessageDWord(hRead);
m_fStartTime = pServerDE->ReadFromMessageFloat(hRead) + fTime;
m_bRemoveFromWorld = pServerDE->ReadFromMessageByte(hRead);
m_fDamage = pServerDE->ReadFromMessageFloat(hRead);
m_fLifeTime = pServerDE->ReadFromMessageFloat(hRead);
m_nDamageMsgID = pServerDE->ReadFromMessageDWord(hRead);
// DBOOL m_bSmokeTrail; // Do we generate a smoke trail
m_bShockwave = pServerDE->ReadFromMessageByte(hRead);
m_bExplosion = pServerDE->ReadFromMessageByte(hRead);
m_bSparks = pServerDE->ReadFromMessageByte(hRead);
pServerDE->ReadFromMessageVector(hRead, &m_vShockwaveScaleMin);
pServerDE->ReadFromMessageVector(hRead, &m_vShockwaveScaleMax);
pServerDE->ReadFromMessageVector(hRead, &m_vLightColor);
m_fShockwaveDuration = pServerDE->ReadFromMessageFloat(hRead);
m_hstrShockwaveFilename = pServerDE->ReadFromMessageHString(hRead);
pServerDE->ReadFromMessageVector(hRead, &m_vDims);
m_bExplode = pServerDE->ReadFromMessageByte(hRead);
// Special members
pServerDE->ReadFromMessageVector(hRead, &m_LastPos);
m_bArmed = pServerDE->ReadFromMessageByte(hRead);
m_fPitchVel = pServerDE->ReadFromMessageFloat(hRead);
m_fYawVel = pServerDE->ReadFromMessageFloat(hRead);
m_fPitch = pServerDE->ReadFromMessageFloat(hRead);
m_fYaw = pServerDE->ReadFromMessageFloat(hRead);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -