📄 gameweapons.cpp
字号:
// ----------------------------------------------------------------------- //
//
// ROUTINE: CHandSqueeze::Fire()
//
// PURPOSE: Fires the weapon
//
// ----------------------------------------------------------------------- //
DDWORD CHandSqueeze::Fire()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE)
return 0;
DBOOL bAltFire = (m_eState == WS_ALT_FIRING);
int sound = pServerDE->IntRandom(0, 4);
if (sound < 1) m_szFireSound = "Sounds\\Slash1.wav";
else if (sound < 2) m_szFireSound = "Sounds\\Slash2.wav";
else if (sound < 3) m_szFireSound = "Sounds\\Slash3.wav";
else m_szFireSound = "Sounds\\Slash4.wav";
return CWeapon::Fire();
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CFlareGun::FireSpread()
//
// PURPOSE: Spread the flare shots
//
// ----------------------------------------------------------------------- //
void CFlareGun::FireSpread(Spread *spread, DDWORD shots, DFLOAT range, DBOOL bAltFire, DVector *rDir)
{
//***** Make sure the server and inventory systems are valid *****//
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !m_pInventoryMgr) return;
//***** Variables to calculate the spread of the weapon fire *****//
DFLOAT hOffset, vOffset;
DVector vTmp, vFire;
DVector vU, vR, vF;
DBOOL bTracer = DFALSE;
pServerDE->GetRotationVectors(&m_rRotation, &vU, &vR, &vF);
// Check to see if the player is standing too close to something, and we need
// to move the firing position back in order to hit it
if(IsPlayer(m_hOwner) && FiringTooClose(&vF, 60.0f, &vTmp))
{ VEC_COPY(m_vPosition, vTmp); }
for(int i = (shots - 1); i >= 0; i--)
{
VEC_COPY(vFire, vF)
if(shots - 1)
switch(i)
{
case 7: hOffset = 0.03f; vOffset = 0.03f; break;
case 6: hOffset = -0.03f; vOffset = -0.03f; break;
case 5: hOffset = -0.03f; vOffset = 0.03f; break;
case 4: hOffset = 0.03f; vOffset = -0.03f; break;
case 3: hOffset = 0.0f; vOffset = 0.08f; break;
case 2: hOffset = 0.0f; vOffset = -0.08f; break;
case 1: hOffset = -0.08f; vOffset = 0.0f; break;
case 0: hOffset = 0.08f; vOffset = 0.0f; break;
default: hOffset = 0.0f; vOffset = 0.0f; break;
}
else
{
hOffset = pServerDE->Random(-spread->h, spread->h) / 2000;
vOffset = pServerDE->Random(-spread->v, spread->v) / 2000;
}
VEC_MULSCALAR(vTmp, vR, hOffset)
VEC_ADD(vFire, vFire, vTmp)
VEC_MULSCALAR(vTmp, vU, vOffset)
VEC_ADD(vFire, vFire, vTmp)
VEC_NORM(vFire)
if(m_bAccuracyCheck && IsPlayer(m_hOwner))
AlignFireVector(&vFire, range);
FireProjectile(&vFire, range, (m_eState == WS_ALT_FIRING));
}
VEC_COPY(*rDir, vR);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CVoodooDoll::FireVector()
//
// PURPOSE: Fires a vector
//
// ----------------------------------------------------------------------- //
DBOOL CVoodooDoll::FireVector(DVector *vFire, DFLOAT dist, DBOOL bTracer)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if(!pServerDE) return DFALSE;
switch(m_nHitFX)
{
case 0: m_nHitType = DAMAGE_TYPE_NORMAL; break;
case 1: m_nHitType = DAMAGE_TYPE_NORMAL; break;
case 2: m_nHitType = DAMAGE_TYPE_BLIND; break;
case 3: m_nHitType = DAMAGE_TYPE_DROPWEAPON; break;
case 4: m_nHitType = DAMAGE_TYPE_SLOW; break;
default: m_nHitType = DAMAGE_TYPE_NORMAL; break;
}
if(m_eState == WS_FIRING)
{
DamageClosestInFOV();
}
else if(m_eState == WS_ALT_FIRING)
{
m_nHitFX = 5;
m_nHitType = DAMAGE_TYPE_VISION; // Wonkie vision (violet)
m_fDamage = pServerDE->Random(m_fMinAltDamage, m_fMaxAltDamage);
if (!WonkyThemAll(WONKY_VISION_DEFAULT_TIME))
{
// If you miss everyone with the alt fire, you just explode cause you suck
BaseClass *ffObj = pServerDE->HandleToObject(m_hOwner);
DVector vFire, vPos;
VEC_SET(vFire, 0.0f, -1.0f, 0.0f);
pServerDE->GetObjectPos(m_hOwner, &vPos);
HMESSAGEWRITE hMsg = pServerDE->StartMessageToObject(ffObj, m_hOwner, MID_DAMAGE);
pServerDE->WriteToMessageVector(hMsg, &vFire);
pServerDE->WriteToMessageFloat(hMsg, 100.0f);
pServerDE->WriteToMessageByte(hMsg, DAMAGE_TYPE_EXPLODE);
pServerDE->WriteToMessageObject(hMsg, m_hOwner);
pServerDE->WriteToMessageVector(hMsg, &vPos);
pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CVoodooDoll::SendDamageMsg()
//
// PURPOSE: VoodooDoll Damage Message
//
// ----------------------------------------------------------------------- //
DBOOL CVoodooDoll::SendDamageMsg(HOBJECT firedTo, DVector vPoint, int nNode, DVector *vFire, DFLOAT m_nDamage)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE)
return DFALSE;
BaseClass *ffObj = pServerDE->HandleToObject(m_hOwner);
// Send a damage message to the object
HMESSAGEWRITE hMsg = pServerDE->StartMessageToObject(ffObj, firedTo, MID_DAMAGE);
pServerDE->WriteToMessageVector(hMsg, vFire);
pServerDE->WriteToMessageFloat(hMsg, (float)m_nDamage * GetDamageMultiplier());
pServerDE->WriteToMessageByte(hMsg, (char)m_nHitType);
pServerDE->WriteToMessageObject(hMsg, m_hOwner);
pServerDE->WriteToMessageVector(hMsg, &vPoint);
pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CVoodooDoll::DamageClosestInFOV()
//
// PURPOSE: Search for the closest person to damage
//
// ----------------------------------------------------------------------- //
DBOOL CVoodooDoll::DamageClosestInFOV()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return DNULL;
// Get the head of the list of destructable objects
DLink* pLink = CDestructable::m_DestructableHead.m_pNext;
if(!pLink || (pLink == &CDestructable::m_DestructableHead)) return DNULL;
// Work with the squares of the distances so as to not have to get a square root.
HOBJECT hObj;
HOBJECT hDamageObj = DNULL;
DFLOAT fLastDist = 3000.0f;
DVector vPoint, vDirection;
HCLASS hCharacter = pServerDE->GetClass("CBaseCharacter");
HCLASS hPlayer = pServerDE->GetClass("CPlayerObj");
HCLASS hObjClass = DNULL;
DBOOL bHitSomething = DFALSE;
// Get a forward vector and position of the player who shot the voodoo doll
CPlayerObj *pObj = (CPlayerObj*)pServerDE->HandleToObject(m_hOwner);
DVector vOwnerF, vOwnerPos;
pObj->GetPlayerForward(&vOwnerF);
pServerDE->GetObjectPos(m_hOwner, &vOwnerPos);
VEC_NORM(vOwnerF);
CPlayerObj* pOwnerPlayer = pObj;
// 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, fAngle;
// If it's us... skip to the next in the list
if(hObj == m_hOwner)
{ pLink = pLink->m_pNext; continue; }
// Test the angle between this object and us
pServerDE->GetObjectPos(hObj, &vObjPos);
VEC_SUB(vDir, vObjPos, vOwnerPos);
fDist = VEC_MAG(vDir);
// If the target is too far away... skip it
if(fDist > VOODOO_WONKY_DIST)
{ pLink = pLink->m_pNext; continue; }
VEC_NORM(vDir);
fAngle = VEC_DOT(vDir, vOwnerF);
// If the target isn't within our square FOV, then skip it
if(fAngle < VOODOO_PRIMARY_FOV)
{ pLink = pLink->m_pNext; continue; }
// Make sure there's nothing blocking our view of the character
IntersectQuery iq;
IntersectInfo ii;
VEC_COPY(iq.m_From, vOwnerPos);
VEC_COPY(iq.m_To, vObjPos);
VEC_MULSCALAR(vDir, vDir, 15.0f);
VEC_ADD(iq.m_To, iq.m_To, vDir);
iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
iq.m_FilterFn = LiquidFilterFn;
iq.m_pUserData = NULL;
if(pServerDE->IntersectSegment(&iq, &ii))
{
if(ii.m_hObject == hObj)
{
if(fDist < fLastDist)
{
fLastDist = fDist;
hDamageObj = hObj;
bHitSomething = DTRUE;
VEC_COPY(vPoint, ii.m_Point);
VEC_COPY(vDirection, vDir);
}
}
}
}
pLink = pLink->m_pNext;
}
// Handle the object damage and effect
if(hDamageObj)
{
hObjClass = pServerDE->GetObjectClass(hDamageObj);
if(pServerDE->IsKindOf(hObjClass, hPlayer))
{
CPlayerObj *pObj = (CPlayerObj*)pServerDE->HandleToObject(hDamageObj);
if (!pOwnerPlayer->IsPlayerDamageOk(pObj)) // [blg] check for team-play and friendly-fire
{
return(DTRUE);
}
if(m_nHitFX == 2)
{
HMESSAGEWRITE hMsg = pServerDE->StartMessage(pObj->GetClient(), SMSG_BLIND);
pServerDE->WriteToMessageFloat(hMsg, 5.0f);
pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
}
if(m_nHitFX == 3)
{
// Make the character holster his weapon
}
if(m_nHitFX == 4)
{
pObj->Slow(5.0f);
}
}
//******************************************************************
if(m_nHitFX == 1)
SendDamageMsg(hDamageObj, vPoint, 999, &vDirection, m_fDamage * 2.0f);
else
SendDamageMsg(hDamageObj, vPoint, 999, &vDirection, m_fDamage);
//******************************************************************
// Create a particle effect around the hit character
DVector offset;
DDWORD fxType = OBJFX_VOODOO_1 + m_nHitFX;
VEC_SET(offset, 0.0f, 0.0f, 0.0f);
HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&offset);
pServerDE->WriteToMessageByte(hMessage, SFX_OBJECTFX_ID);
pServerDE->WriteToMessageObject(hMessage, hDamageObj);
pServerDE->WriteToMessageVector(hMessage, &offset);
pServerDE->WriteToMessageFloat(hMessage, 0.0f);
pServerDE->WriteToMessageDWord(hMessage, 0);
pServerDE->WriteToMessageDWord(hMessage, fxType);
pServerDE->WriteToMessageDWord(hMessage, 0);
pServerDE->EndMessage2(hMessage, MESSAGE_GUARANTEED | MESSAGE_NAGGLEFAST);
//******************************************************************
if(m_nHitFX == 4)
pServerDE->SetVelocity(hDamageObj, &offset);
}
else
{
SendDamageMsg(m_hOwner, vOwnerPos, 999, &vDirection, m_fDamage / 3.0f);
}
return bHitSomething;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CVoodooDoll::WonkyThemAll()
//
// PURPOSE: Search for people to wonky
//
// ----------------------------------------------------------------------- //
DBOOL CVoodooDoll::WonkyThemAll(DFLOAT fWonkyTime)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return DNULL;
// Get the head of the list of destructable objects
DLink* pLink = CDestructable::m_DestructableHead.m_pNext;
if(!pLink || (pLink == &CDestructable::m_DestructableHead)) return DNULL;
// Work with the squares of the distances so as to not have to get a square root.
HOBJECT hObj;
HCLASS hCharacter = pServerDE->GetClass("CBaseCharacter");
HCLASS hPlayer = pServerDE->GetClass("CPlayerObj");
HCLASS hObjClass = DNULL;
DBOOL bHitSomething = DFALSE;
// Get a forward vector and position of the player who shot the voodoo doll
CPlayerObj *pObj = (CPlayerObj*)pServerDE->HandleToObject(m_hOwner);
DVector vOwnerF, vOwnerPos;
pObj->GetPlayerForward(&vOwnerF);
pServerDE->GetObjectPos(m_hOwner, &vOwnerPos);
VEC_NORM(vOwnerF);
CPlayerObj* pOwnerPlayer = pObj;
// 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, fAngle;
// If it's us... skip to the next in the list
if(hObj == m_hOwner)
{ pLink = pLink->m_pNext; continue; }
// Test the angle between this object and us
pServerDE->GetObjectPos(hObj, &vObjPos);
VEC_SUB(vDir, vObjPos, vOwnerPos);
fDist = VEC_MAG(vDir);
// If the target is too far away... skip it
if(fDist > VOODOO_WONKY_DIST)
{ pLink = pLink->m_pNext; continue; }
VEC_NORM(vDir);
fAngle = VEC_DOT(vDir, vOwnerF);
// If the target isn't within our square FOV, then skip it
if(fAngle < VOODOO_WONKY_FOV)
{ pLink = pLink->m_pNext; continue; }
// If it's a team-mate and there's no friendly-fire, then skip it
if (!pOwnerPlayer->IsPlayerDamageOk(hObj))
{
pLink = pLink->m_pNext;
bHitSomething = DTRUE;
continue;
}
// Make sure there's nothing blocking our view of the character
IntersectQuery iq;
IntersectInfo ii;
VEC_COPY(iq.m_From, vOwnerPos);
VEC_COPY(iq.m_To, vObjPos);
VEC_MULSCALAR(vDir, vDir, 15.0f);
VEC_ADD(iq.m_To, iq.m_To, vDir);
iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
iq.m_FilterFn = LiquidFilterFn;
iq.m_pUserData = NULL;
if(pServerDE->IntersectSegment(&iq, &ii))
{
if(ii.m_hObject == hObj)
{
bHitSomething = DTRUE;
VEC_NORM(vDir);
SendDamageMsg(ii.m_hObject, ii.m_Point, 999, &vDir, m_fDamage);
//******************************************************************
// Create a particle effect around the hit character
DVector offset;
VEC_SET(offset, 0.0f, 0.0f, 0.0f);
HMESSAGEWRITE hMessage = pServerDE->StartInstantSpecialEffectMessage(&offset);
pServerDE->WriteToMessageByte(hMessage, SFX_OBJECTFX_ID);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -