📄 weapon.cpp
字号:
bEnemyChar = DTRUE;
}
#endif
}
// Copy over the filenames so we preserver the originals
_mbscpy((unsigned char*)model, (const unsigned char*)pModelFilename);
_mbscpy((unsigned char*)skin, (const unsigned char*)m_pViewModelSkinname);
// Change the weapon skin to the correct character
change = strstr(skin, start);
change[0] = firstChar;
// Change the knife model to the correct character
if(m_nType == WEAP_MELEE)
{
change = strstr(model, start);
change[0] = firstChar;
}
// Check for generic orb
#ifdef _ADDON
if (m_nType == WEAP_ORB && bEnemyChar)
{
}
#endif
// Continue
change = DNULL;
if(m_nFlags & FLAG_ENVIRONMENTMAP)
{
pServerDE->SetObjectColor(m_pViewModel->m_hObject, 1.0f, 1.0f, 1.0f, m_fChromeValue);
DDWORD f = pServerDE->GetObjectFlags(m_pViewModel->m_hObject);
pServerDE->SetObjectFlags(m_pViewModel->m_hObject, f | FLAG_ENVIRONMENTMAP | FLAG_VISIBLE);
}
else
{
pServerDE->SetObjectColor(m_pViewModel->m_hObject, 0.0f, 0.0f, 0.0f, 1.0f);
DDWORD f = pServerDE->GetObjectFlags(m_pViewModel->m_hObject);
f |= FLAG_VISIBLE;
pServerDE->SetObjectFlags(m_pViewModel->m_hObject, f & ~FLAG_ENVIRONMENTMAP);
}
// Set the new model filenames
pServerDE->SetObjectFilenames(m_pViewModel->m_hObject, model, skin);
pServerDE->SetModelLooping(m_pViewModel->m_hObject, DFALSE);
pServerDE->SetModelAnimation(m_pViewModel->m_hObject, -1);
// Tell it that this weapon this is it's parent for now.
m_pViewModel->Init(this);
m_pViewModel->UseModelKeys(DTRUE);
m_nRestAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "static_model");
m_nIdleAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "idle");
m_nDrawAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "draw");
m_nDrawDuelAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "dh_draw");
m_nHolsterAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "holster");
m_nHolsterDuelAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "dh_holster");
m_nStartFireAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "start_fire");
m_nFireAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "fire");
m_nStopFireAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "end_fire");
m_nStartAltFireAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "start_alt_fire");
m_nAltFireAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "alt_fire");
m_nStopAltFireAnim = pServerDE->GetAnimIndex(m_pViewModel->m_hObject, "end_alt_fire");
if (m_nIdleAnim == INVALID_ANI)
m_nIdleAnim = m_nRestAnim;
if (m_nAltFireAnim == INVALID_ANI)
{
m_nStartAltFireAnim = m_nStartFireAnim;
m_nAltFireAnim = m_nFireAnim;
m_nStopAltFireAnim = m_nStopFireAnim;
}
PlayAnimation(m_nDrawAnim);
m_fIdleDelay = pServerDE->Random(m_fMinIdleDelay, m_fMaxIdleDelay);
m_fIdleStartTime = pServerDE->GetTime();
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::CreateMuzzleFlash()
//
// PURPOSE: Creates a muzzle flash
//
// ----------------------------------------------------------------------- //
void CWeapon::SetupMuzzleFlash()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
WeaponData *wd = &g_WeaponDefaults[m_nType-1];
if (m_hFlash && wd)
{
pServerDE->SetLightRadius(m_hFlash, wd->m_fFlashRadius);
pServerDE->SetLightColor(m_hFlash, VEC_EXPAND(wd->m_vFlashColor));
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::ShowMuzzleFlash()
//
// PURPOSE: Makes the muzzle flash visible
//
// ----------------------------------------------------------------------- //
void CWeapon::ShowMuzzleFlash(DVector *vPos)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
WeaponData *wd = &g_WeaponDefaults[m_nType-1];
DFLOAT fRadius = wd->m_fFlashRadius;
if(m_hFlash && fRadius)
{
if(!m_bFlashShowing)
{
// Set visible
DDWORD dwFlags = pServerDE->GetObjectFlags(m_hFlash);
dwFlags |= FLAG_VISIBLE;
pServerDE->SetObjectFlags(m_hFlash, dwFlags);
// Move to current position
pServerDE->TeleportObject(m_hFlash, vPos);
m_fFlashStartTime = pServerDE->GetTime();
m_bFlashShowing = DTRUE;
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::UpdateMuzzleFlash()
//
// PURPOSE: Checks the muzzle flash
//
// ----------------------------------------------------------------------- //
void CWeapon::UpdateMuzzleFlash()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (m_hFlash && m_bFlashShowing)
{
if (pServerDE->GetTime() > m_fFlashStartTime + m_fFlashDuration)
{
DDWORD dwFlags = pServerDE->GetObjectFlags(m_hFlash);
dwFlags &= ~FLAG_VISIBLE;
pServerDE->SetObjectFlags(m_hFlash, dwFlags);
m_bFlashShowing = DFALSE;
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::SendDamageMsg()
//
// PURPOSE: Weapon Damage Message
//
// ----------------------------------------------------------------------- //
DBOOL CWeapon::SendDamageMsg(HOBJECT firedTo, DVector vPoint, DVector *vFire, DFLOAT fDamage)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE)
return DFALSE;
BaseClass *ffObj = pServerDE->HandleToObject(m_hOwner);
// Send a damage message to the object
if(g_pBloodServerShell->IsMultiplayerGame() && m_bMultiDamageBoost)
DamageObject(m_hOwner, ffObj, firedTo, fDamage * GetDamageMultiplier() * 2.0f, *vFire, vPoint, m_nDamageType);
else
DamageObject(m_hOwner, ffObj, firedTo, fDamage * GetDamageMultiplier(), *vFire, vPoint, m_nDamageType);
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::OnFireKey()
//
// PURPOSE: The view model or the weapon model has fired..
//
// ----------------------------------------------------------------------- //
void CWeapon::OnFireKey()
{
DBYTE nFiredType = (DBYTE)Fire();
SendClientFiring(nFiredType);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::SendClientInfo()
//
// PURPOSE: Sends info that the client needs to show weapon.
//
// ----------------------------------------------------------------------- //
void CWeapon::SendClientInfo(DBYTE slot)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !IsOwnerAPlayer())
return;
CPlayerObj *pPlayer = (CPlayerObj*)pServerDE->HandleToObject(m_hOwner);
if (!pPlayer->IsActivated())
return;
HMESSAGEWRITE hMsg = pServerDE->StartMessage(m_hClient, SMSG_NEWWEAPON);
pServerDE->WriteToMessageByte(hMsg, slot);
pServerDE->WriteToMessageByte(hMsg, (DBYTE)m_nType);
pServerDE->WriteToMessageByte(hMsg, (DBYTE)m_bLeftHand);
/* pServerDE->WriteToMessageObject(hMsg, m_pViewModel->m_hObject);
if(m_nWeaponNameID)
{
HSTRING hstr = pServerDE->FormatString(m_nWeaponNameID);
pServerDE->WriteToMessageString(hMsg, pServerDE->GetStringData(hstr));
pServerDE->FreeString(hstr);
}
else
pServerDE->WriteToMessageString(hMsg, m_szWeaponName);
pServerDE->WriteToMessageString(hMsg, m_szFlashSprite);
pServerDE->WriteToMessageString(hMsg, m_szAltFlashSprite);
pServerDE->WriteToMessageFloat(hMsg, m_fFlashDuration);
pServerDE->WriteToMessageFloat(hMsg, m_fFlashScale);
pServerDE->WriteToMessageVector(hMsg, &m_vViewModelOffset);
pServerDE->WriteToMessageVector(hMsg, &m_vMuzzleOffset);
pServerDE->WriteToMessageVector(hMsg, &m_vFlash);
pServerDE->WriteToMessageFloat(hMsg, m_fEjectInterval);
pServerDE->WriteToMessageFloat(hMsg, m_fViewKick);
pServerDE->WriteToMessageByte(hMsg, (DBYTE)m_bCumulativeKick);
pServerDE->WriteToMessageHString(hMsg, m_szPic);
pServerDE->WriteToMessageHString(hMsg, m_szPicH);
*/
pServerDE->EndMessage(hMsg);
m_bClientNotified = DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::SendClientFiring()
//
// PURPOSE: Sends info that the client needs to show a weapon firing.
//
// ----------------------------------------------------------------------- //
void CWeapon::SendClientFiring(DBYTE type)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !IsOwnerAPlayer())
return;
HMESSAGEWRITE hMsg = pServerDE->StartMessage(m_hClient, SMSG_FIREDWEAPON);
pServerDE->WriteToMessageByte(hMsg, type);
pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLE);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::PlayAnimation()
//
// PURPOSE: Set model to new animation
//
// ----------------------------------------------------------------------- //
DBOOL CWeapon::PlayAnimation(DDWORD dwNewAni)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !m_pViewModel || dwNewAni == INVALID_ANI) return DFALSE;
DDWORD dwAni = pServerDE->GetModelAnimation(m_pViewModel->m_hObject);
DDWORD dwState = pServerDE->GetModelPlaybackState(m_pViewModel->m_hObject);
if (dwAni == dwNewAni && (dwState & MS_PLAYDONE))
{
return DFALSE;
}
else if (dwAni != dwNewAni)
{
pServerDE->SetModelAnimation(m_pViewModel->m_hObject, dwNewAni);
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::AddImpact
//
// PURPOSE: Add an impact sprite
//
// ----------------------------------------------------------------------- //
void CWeapon::AddImpact(DVector *pvSource, DVector *pvDest, DVector *pvForward, DVector *pvNormal, DDWORD nFX, DDWORD nExtras, WeaponFXExtras *ext)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DVector vAdjDest;
// ObjectCreateStruct theStruct;
// INIT_OBJECTCREATESTRUCT(theStruct);
VEC_MULSCALAR(vAdjDest, *pvNormal, 1.25f);
VEC_ADD(vAdjDest, vAdjDest, *pvDest);
// VEC_ADD(theStruct.m_Pos, *pvDest, temp);
// ROT_COPY(theStruct.m_Rotation, m_rRotation);
// HCLASS hClass = pServerDE->GetClass("CClientWeaponSFX");
// CClientWeaponSFX *pWeaponFX = DNULL;
// if(hClass)
// pWeaponFX = (CClientWeaponSFX*)pServerDE->CreateObject(hClass, &theStruct);
// if(pWeaponFX)
SendWeaponSFXMessage(pvSource, &vAdjDest, pvForward, pvNormal, nFX, nExtras, ext);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::AddSplash
//
// PURPOSE: Make a water splash
//
// ----------------------------------------------------------------------- //
void CWeapon::AddSplash(DVector vPos, DVector vNormal, HOBJECT hObject, DVector vColor1, DVector vColor2)
{
ServerDE* pServerDE = BaseClass::GetServerDE();
if(!pServerDE) return;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
VEC_COPY(ocStruct.m_Pos, vPos);
HCLASS hClass = pServerDE->GetClass("CClientSplashSFX");
CClientSplashSFX *pSplash = DNULL;
if(hClass)
pSplash = (CClientSplashSFX *)pServerDE->CreateObject(hClass, &ocStruct);
if(pSplash)
{
DBOOL bRipple;
DFLOAT fRadius, fPosRadius, fHeight, fDensity, fSpread, fSprayTime, fDuration, fGravity;
DVector vRipScale;
char *pParticle;
fRadius = 100.0f;
fPosRadius = 1.0f;
fHeight = 175.0f;
fDensity = 4.0f;
fSpread = 10.0f;
VEC_SET(vRipScale, 0.1f, 0.1f, 0.0f);
bRipple = DTRUE;
fSprayTime = 0.3f;
fDuration = 0.75f;
fGravity = -500.0f;
pParticle = "spritetextures\\drop32_1.dtx";
pSplash->Setup(&vPos, &vNormal, fRadius, fPosRadius, fHeight, fDensity, fSpread, &vColor1,
&vColor2, &vRipScale, bRipple, fSprayTime, fDuration, fGravity, pParticle);
}
return;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::AddSparks
//
// PURPOSE: Add impact sparks
//
// ----------------------------------------------------------------------- //
void CWeapon::AddSparks(DVector vPos, DVector vNormal, DFLOAT fDamage, HOBJECT hObject, SurfaceType eType)
{
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 *pTextureFile;
switch(eType)
{
case SURFTYPE_FLESH:
{
DVector temp;
VEC_INIT(temp);
temp.y = 50.0f;
VEC_ADD(temp, temp, vNormal);
VEC_SET(vColor1, 200.0f, 0.0f, 0.0f);
VEC_SET(vColor2, 255.0f, 0.0f, 0.0f);
switch(pServerDE->IntRandom(1,NRES(4)))
{
case 1: pTextureFile = "spritetextures\\particles\\blooddrop_1.dtx"; break;
case 2: pTextureFile = "spritetextures\\particles\\blooddrop_2.dtx"; break;
case 3: pTextureFile = "spritetextures\\particles\\blooddrop_3.dtx"; break;
case 4: pTextureFile = "spritetextures\\particles\\blooddrop_4.dtx"; break;
}
pSpark->Setup(&temp, &vColor1, &vColor2, pTextureFile, (DBYTE)(fDamage * 3), 2.0f, 5.0f, 200.0f, -150.0f);
return;
}
case SURFTYPE_METAL:
{
VEC_SET(vColor1, 200.0f, 200.0f, 200.0f);
VEC_SET(vColor2, 255.0f, 255.0f, 0.0f);
VEC_MULSCALAR(vNormal, vNormal, 75.0f);
pTextureFile = "spritetextures\\particles\\particle2.dtx";
pSpark->Setup(&vNormal, &vColor1, &vColor2, pTextureFile, (DBYTE)pServerDE->IntRandom(5, 30), 0.15f, 0.5f, 200.0f, -200.0f);
return;
}
case SURFTYPE_STONE:
case SURFTYPE_WOOD:
break;
default:
{
VEC_SET(vColor1, 200.0f, 200.0, 200.0f);
VEC_SET(vColor2, 200.0f, 200.0f, 0.0f);
VEC_MULSCALAR(vNormal, vNormal, 100.0f);
pTextureFile = "spritetextures\\particles\\particle2.dtx";
pSpark->Setup(&vNormal, &vColor1, &vColor2, pTextureFile, (DBYTE)fDamage, 0.15f, 0.5f, 200.0f, -200.0f);
break;
}
}
}
return;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CWeapon::AddWorldModelMark
//
// PURPOSE: Adds bullet mark to the wall.This is ONLY used for WorldModels,
// normal wall marks use a ClientWeaponFX WFX_MARK flag.
//
// ----------------------------------------------------------------------- //
void CWeapon::AddWorldModelMark(DVector vPos, DVector vNormal, HOBJECT hObject, SurfaceType eType)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
DVector vTmp;
VEC_MULSCALAR(vTmp, vNormal, 0.5f);
VEC_COPY(ocStruct.m_Pos, vPos);
VEC_ADD(ocStruct.m_Pos, ocStruct.m_Pos, vTmp);
HCLASS hClass = pServerDE->GetClass("CClientMarkSFX");
if (hClass)
{
CClientMarkSFX *pMark = DNULL;
pMark = (CClientMarkSFX *)pServerDE->CreateObject(hClass, &ocStruct);
DBOOL bAltFire = (m_eState == WS_ALT_FIRING);
if (pMark)
{
pMark->Setup( &vPos, &vNormal, m_nType, GetAmmoType(bAltFire), eType, hObject );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -