📄 weaponfx.cpp
字号:
VEC_COPY(tr.vStartPos, m_vSourcePos);
ROT_COPY(tr.rRot, m_rRotation);
tr.fStartAlpha = 0.1f;
tr.fEndAlpha = 0.9f;
psfxMgr->CreateSFX(SFX_TRACER_ID, &tr, DFALSE, this);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::CreateSmoke
//
// PURPOSE: Create a smoke/water splash fx
//
// ----------------------------------------------------------------------- //
void CWeaponFX::CreateSmoke()
{
CSFXMgr* psfxMgr = g_pBloodClientShell->GetSFXMgr();
if(!psfxMgr) return;
if(IsLiquid(m_eDestCode) && m_eSurfaceType != SURFTYPE_LIQUID)
{
CreateBubbles(&m_vDestPos, 4);
return;
}
SMOKECREATESTRUCT sms;
VEC_COPY(sms.vNormal, m_vNormal);
sms.fOffset = 3.0f;
VEC_COPY(sms.vPos, m_vDestPos);
VEC_SET(sms.vVel, 0.0f, 0.0f, 0.0f);
VEC_SET(sms.vDecel, 0.0f, 0.0f, 0.0f);
VEC_SET(sms.vGravity, 0.0f, GetRandom(0.05f,0.1f), 0.0f);
sms.fDuration = 1.0f;
sms.fDelay = 0.0f;
sms.bUpdateScale = 1;
VEC_SET(sms.vMinScale, 0.1f, 0.1f, 0.0f);
VEC_SET(sms.vMaxScale, 0.35f, 0.35f, 0.0f);
sms.fInitAlpha = 0.65f;
sms.bFade = 1;
sms.bRotate = 0;
switch(m_eSurfaceType)
{
case SURFTYPE_WOOD:
VEC_SET(sms.vColor, 1.0f, 0.8f, 0.6f);
break;
}
int nMax = NRES(6) - 1;
sms.pSpriteFile = szSmokeSprites[GetRandom(0,nMax)];
if(m_vNormal.y > -0.3f)
sms.bMove = 1;
else
sms.bMove = 0;
psfxMgr->CreateSFX(SFX_SMOKEIMPACT_ID, &sms, DFALSE, this);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::CreateBubbles
//
// PURPOSE: Creates a group of bubbles
//
// ----------------------------------------------------------------------- //
void CWeaponFX::CreateBubbles(DVector* pvStartPos, DBYTE numBubbles)
{
CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
if (!m_pClientDE || !pShell) return;
if (m_nAmmoType != AMMO_BULLET && m_nAmmoType != AMMO_SHELL && m_nAmmoType != AMMO_BMG)
return;
CSFXMgr* psfxMgr = pShell->GetSFXMgr();
if (!psfxMgr) return;
char* pTexture = "\\SpriteTextures\\Particles\\ParticleBubble.dtx";
SCREATESTRUCT sp;
VEC_COPY(sp.vPos, *pvStartPos);
VEC_MULSCALAR(sp.vDir, m_vNormal, 15.0f);
sp.hstrTexture = m_pClientDE->CreateString(pTexture);
sp.hServerObj = DNULL;
sp.nSparks = numBubbles;
VEC_SET(sp.vColor1, 125.0f, 125.0f, 255.0f);
VEC_SET(sp.vColor2, 180.0f, 180.0f, 255.0f);
sp.fDuration = 1.25f;
sp.fEmissionRadius = 0.05f;
sp.fRadius = 600.0f;
sp.fGravity = 50.0f;
if (m_nAmmoType == AMMO_SHELL)
sp.nSparks = 1;
psfxMgr->CreateSFX(SFX_SPARKS_ID, &sp, DFALSE, this);
m_pClientDE->FreeString(sp.hstrTexture);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::GetMarkSprite()
//
// PURPOSE: Get a mark sprite associated with this weapon and surface
//
// ----------------------------------------------------------------------- //
char* CWeaponFX::GetMarkSprite(SurfaceType eSurfType)
{
char* pMark = DNULL;
/*
Blthole.spr-metal
Blthole2.spr-plastic and cloth
Blthole3.spr-concrete
Blthole4.spr-concrete
Blthole5.spr-wood
*/
switch(eSurfType)
{
case SURFTYPE_UNKNOWN:
case SURFTYPE_FLESH:
case SURFTYPE_SKY:
case SURFTYPE_GLASS:
break;
// pMark = GetRandom(0,1) ? "sprites/glshole1.spr" : "sprites/glshole2.spr";
// break;
case SURFTYPE_METAL:
pMark = "sprites/blthole.spr";
break;
case SURFTYPE_PLASTIC:
case SURFTYPE_CLOTH:
pMark = "sprites/blthole2.spr";
break;
case SURFTYPE_WOOD:
pMark = "sprites/blthole5.spr";
break;
case SURFTYPE_STONE:
default:
pMark = GetRandom(0,1) ? "sprites/blthole3.spr" : "sprites/blthole4.spr";
break;
}
return pMark;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::GetSparkTexture()
//
// PURPOSE: Get a spark texture associated with this weapon and surface
//
// ----------------------------------------------------------------------- //
char* CWeaponFX::GetSparkTexture(SurfaceType eSurfType, DVector* pvColor1, DVector* pvColor2)
{
char* pTexture = DNULL;
return (pTexture);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::CreateLightFX
//
// PURPOSE: Create a cool light fx
//
// ----------------------------------------------------------------------- //
void CWeaponFX::CreateLightFX(DVector* pvPos, DVector* pvColor)
{
CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
if (!m_pClientDE || !pShell || !pvPos || !pvColor) return;
/*
CSFXMgr* psfxMgr = g_pBloodClientShell->GetSFXMgr();
if (!psfxMgr) return;
DLCREATESTRUCT dl;
dl.hServerObj = DNULL;
VEC_COPY(dl.vColor, *pvColor);
VEC_COPY(dl.vPos, *pvPos);
dl.fMinRadius = 50.0f;
dl.fMaxRadius = 100.0f;
dl.fRampUpTime = 0.3f;
dl.fMaxTime = 0.1f;
dl.fMinTime = 0.0f;
dl.fRampDownTime = 0.2f;
psfxMgr->CreateSFX(SFX_DYNAMICLIGHT_ID, &dl, DFALSE, this);
*/
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::PlayImpactSound()
//
// PURPOSE: Play a surface impact sound if appropriate
//
// ----------------------------------------------------------------------- //
void CWeaponFX::PlayImpactSound()
{
if (!m_pClientDE) return;
// DVector vPos;
// m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
char* pImpactSound = GetImpactSound(0, m_nAmmoType, m_eSurfaceType);
DFLOAT fImpactSoundRadius = DEFAULT_IMPACT_SOUND_RADIUS;
if (pImpactSound)
PlaySoundFromPos(&m_vDestPos, pImpactSound, fImpactSoundRadius, SOUNDPRIORITY_MISC_LOW);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::CreateMuzzleSmoke()
//
// PURPOSE: Create muzzle specific fx
//
// ----------------------------------------------------------------------- //
void CWeaponFX::CreateMuzzleSmoke()
{
CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
if (!m_pClientDE || !pShell) return;
if (m_nAmmoType != AMMO_BULLET && m_nAmmoType != AMMO_SHELL && m_nAmmoType != AMMO_BMG)
return;
CSFXMgr* psfxMgr = pShell->GetSFXMgr();
if(!psfxMgr) return;
if(IsLiquid(m_eSourceCode) && m_eSurfaceType != SURFTYPE_LIQUID)
{
CreateBubbles(&m_vSourcePos, 4);
return;
}
SMOKECREATESTRUCT sms;
VEC_COPY(sms.vNormal, m_vNormal);
sms.fOffset = 0.0f;
VEC_COPY(sms.vPos, m_vSourcePos);
VEC_SET(sms.vGravity, GetRandom(-0.5f, 0.5f), GetRandom(-0.25f, 0.75f), GetRandom(-0.5f, 0.5f));
sms.fDelay = 0.0f;
sms.bUpdateScale = 1;
sms.bFade = 1;
sms.bRotate = 0;
sms.bMove = 1;
switch(GetRandom(1,NRES(6)))
{
case 1: sms.pSpriteFile = "Sprites\\smokepuff1.spr"; break;
case 2: sms.pSpriteFile = "Sprites\\smokepuff2.spr"; break;
case 3: sms.pSpriteFile = "Sprites\\smokepuff3.spr"; break;
case 4: sms.pSpriteFile = "Sprites\\smokepuff4.spr"; break;
case 5: sms.pSpriteFile = "Sprites\\smokepuff5.spr"; break;
case 6: sms.pSpriteFile = "Sprites\\smokepuff6.spr"; break;
}
if(m_nAmmoType == AMMO_SHELL)
{
sms.fDuration = 1.0f;
sms.fInitAlpha = 0.25f;
VEC_SET(sms.vMinScale, 0.04f, 0.04f, 0.0f);
VEC_SET(sms.vMaxScale, 0.25f, 0.25f, 0.0f);
VEC_MULSCALAR(sms.vVel, m_vDir, 2.0f);
VEC_SUB(sms.vVel, sms.vVel, m_vForward);
VEC_NORM(sms.vVel);
VEC_MULSCALAR(sms.vVel, sms.vVel, 3.0f);
VEC_MULSCALAR(sms.vDecel, m_vForward, -0.07f);
}
else
{
sms.fDuration = 1.5f;
sms.fInitAlpha = 0.5f;
VEC_SET(sms.vMinScale, 0.05f, 0.05f, 0.0f);
VEC_SET(sms.vMaxScale, 0.25f, 0.25f, 0.0f);
VEC_MULSCALAR(sms.vVel, m_vForward, 2.0f);
VEC_MULSCALAR(sms.vDecel, m_vDir, -0.035f);
}
psfxMgr->CreateSFX(SFX_SMOKEIMPACT_ID, &sms, DFALSE, this);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::CreateShellCasing
//
// PURPOSE: Eject a shell from this puppy..
//
// ----------------------------------------------------------------------- //
void CWeaponFX::CreateShellCasing()
{
CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
if (!pShell) return;
CSFXMgr* psfxMgr = pShell->GetSFXMgr();
if (!psfxMgr) return;
SHELLCREATESTRUCT sc;
// Fill in the structure for the shell
m_pClientDE->AlignRotation(&sc.rRot, &m_vDir, DNULL);
VEC_COPY(sc.vStartPos, m_vSourcePos);
sc.bLeftHanded = (m_nFXFlags & WFX_LEFTHANDED) ? DTRUE : DFALSE;
sc.nAmmoType = m_nAmmoType;
psfxMgr->CreateSFX(SFX_SHELLCASING_ID, &sc, DFALSE, this);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeaponFX::GetImpactSound()
//
// PURPOSE: Gets a sound to play based on weapon, ammo and surface
//
// ----------------------------------------------------------------------- //
char* CWeaponFX::GetImpactSound(DBYTE nWeaponType, DBYTE nAmmoType, SurfaceType eSurfType)
{
char* pSoundFile = DNULL;
char calc = 0;
switch(eSurfType)
{
case SURFTYPE_STONE:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\stone\\impact1.wav"; break; }
case SURFTYPE_METAL:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\metal\\impact1.wav"; break; }
case SURFTYPE_WOOD:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\wood\\impact1.wav"; break; }
case SURFTYPE_ENERGY:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\energy\\impact1.wav"; break; }
case SURFTYPE_GLASS:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\glass\\impact1.wav"; break; }
case SURFTYPE_BUILDING:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\stone\\impact1.wav"; break; }
case SURFTYPE_TERRAIN:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\terrain\\impact1.wav"; break; }
case SURFTYPE_CLOTH:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\cloth\\impact1.wav"; break; }
case SURFTYPE_PLASTIC:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\plastic\\impact1.wav"; break; }
case SURFTYPE_FLESH:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\flesh\\impact1.wav"; break; }
case SURFTYPE_LIQUID:
{ calc = 1; pSoundFile = "Sounds\\Weapons\\impacts\\water\\impact1.wav"; break; }
default:
{ break; }
}
if(calc)
{
int length = _mbstrlen(pSoundFile);
int nMax = NRES(4) - 1;
int random = GetRandom(0,nMax);
pSoundFile[length - 5] = '1' + random;
}
return pSoundFile;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -