Example #1
0
void CWeaponFX::PlayImpactSound()
{
	IMPACTFX* pImpactFX = m_pAmmo->pImpactFX;

	if (IsLiquid(m_eCode))
	{
		pImpactFX = m_pAmmo->pUWImpactFX;
	}

	if (!pImpactFX) return;


	if (m_pAmmo->eType == VECTOR)
	{
		if ((m_nDetailLevel == RS_LOW) && GetRandom(1, 2) != 1) return;
		else if ((m_nDetailLevel == RS_MED) && GetRandom(1, 3) == 1) return;
	}

	char* pSnd = GetImpactSound(m_eSurfaceType, m_nAmmoId);
    LTFLOAT fSndRadius = (LTFLOAT) pImpactFX->nSoundRadius;

	if (pSnd)
	{
		uint32 dwFlags = 0;
		float fPitchShift = 1.0f;
		if (g_cvarImpactPitchShift.GetFloat() > 0.0f)
		{
			dwFlags |= PLAYSOUND_CTRL_PITCH;
		}

        uint8 nVolume = IsLiquid(m_eCode) ? 50 : 100;
		g_pClientSoundMgr->PlaySoundFromPos(m_vPos, pSnd, fSndRadius,
			SOUNDPRIORITY_MISC_LOW, dwFlags, nVolume, fPitchShift);
	}
}
Example #2
0
// find the place to go for air when bot is underwater
Vector CBotNav::AirGoal()
{
   if (!m_pBot->IsInWater() && !m_pBot->IsInLava() && !m_pBot->IsInSlime())
      return NULLVEC; // bot isn't underwater, don't bother

   Vector start = m_pBot->GetOrigin(), end = m_pBot->GetOrigin() + Vector(0, 0, 1000);

   // trace up until we hit solid
   traceresult_t tr = TestLine(start, end, true, NULL);

   end = tr.endpos;
   end.z -= 16; // lower a bit

   if (IsLiquid(end) || !PointBelongsToWorld(end))
      return NULLVEC; // no enough space above water, fail

   // find the surface of the water
   while (end.z - start.z > 1) {
      // find the mid point
      Vector mid(start.x, start.y, (start.z + end.z) / 2);
      if (IsLiquid(mid)) {
         start.z = mid.z; // surface is ABOVE the mid point
      } else {
         end.z = mid.z; // surface is BELOW the mid point
      }
   }

   end.z += 16; // raise the point a bit to make sure bot will get air
   return end; // success!
}
Example #3
0
//=========================================================
// FVisible - returns true if a line can be traced from
// the caller's eyes to the target
//=========================================================
bool CEntity::FVisible(const Vector &vecDest)
{
    // don't look through water
    if (IsLiquid(GetGunPosition()) != IsLiquid(vecDest))
        return false;

    // check if line of sight to object is not blocked (i.e. visible)
    return (TestLine(EyePosition(), vecDest).fraction >= 1.0);
}
Example #4
0
void Tile::Sort()
{
    for (int i=0;i<MAXMAT;i++)
        for (int j=i+1;j<MAXMAT;j++)
        {
            Material *mm;
            if ((IsLiquid(i)&&IsSolid(j))||(IsGas(i)&&(IsLiquid(j)||IsSolid(j))))
            {
                mm=mats[i];
                mats[i]=mats[j];
                mats[j]=mm;
            }
        }
}
Example #5
0
void Tile::TransferMass(ITile *t)
{
    int &myh=matterh;//GetHeight();
    if (myh<0) return ;
    if (//(t->GetHeight()<myh)&&
        (t->GetHeight()<MAXMAT+1))
        if (IsLiquid(myh)||IsGas(myh))
        {
            TransferTemp(t);
            //t->mats[t->GetHeight()+1]=mats[myh];
            t->AddTop(mats[myh]);
            RemoveMatter();
            //if (myh==0)temp=0;//actual ambient temp? neturetu but svarbu nes VV metodas taip veikia
        }
    if(stack)
        for(unsigned i=0;i<stack->GetCount();i++)
        {
            IItem *it=stack->GetItem(i);
            if(it->GetSize()<=SIZE_CAT)
            {
                stack->RemoveItem(i);
                t->AddItem(it);
                return;
            }
        }
}
Example #6
0
void CWeaponFX::CreateMark(LTVector vPos, LTVector vNorm, LTRotation rRot,
						   SurfaceType eType)
{
	IMPACTFX* pImpactFX = m_pAmmo->pImpactFX;

	if (IsLiquid(m_eCode))
	{
		pImpactFX = m_pAmmo->pUWImpactFX;
	}

	if (!pImpactFX) return;

	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr) return;

	MARKCREATESTRUCT mark;

	mark.m_vPos = vPos;
	mark.m_Rotation = rRot;

	// Randomly rotate the bullet hole...

    g_pLTClient->RotateAroundAxis(&mark.m_Rotation, &vNorm, GetRandom(0.0f, MATH_CIRCLE));

	mark.m_fScale		= pImpactFX->fMarkScale;
	mark.nAmmoId		= m_nAmmoId;
	mark.nSurfaceType   = eType;

	psfxMgr->CreateSFX(SFX_MARK_ID, &mark);
}
Example #7
0
bool Tile::IsLiquid()
{
    int top=GetHeight();
    if (top<0)
        return false;
    return IsLiquid(top);
    //   return (temp > mymat->MeltTemp)&&(temp<mymat->BoilTemp);
};
Example #8
0
int Tile::GetDeepness()
{
    int h=0;
    for (int i=MAXMAT-1;i>=0;i--)
        if (mats[i])
            if (IsLiquid(i))
                h++;

    return h;
}
Example #9
0
void CWeaponFX::CreateExitDebris()
{
	int i;

	// Create the surface specific exit fx...

	SURFACE* pSurf = g_pSurfaceMgr->GetSurface(m_eExitSurface);
	if (!pSurf || !pSurf->bCanShootThrough) return;

	if (IsLiquid(m_eExitCode))
	{
		// Create underwater fx...

		// Create any exit particle shower fx associated with this surface...

		for (i=0; i < pSurf->nNumUWExitPShowerFX; i++)
		{
			CPShowerFX* pPShowerFX = g_pSurfaceMgr->GetPShowerFX(pSurf->aUWExitPShowerFXIds[i]);
			g_pFXButeMgr->CreatePShowerFX(pPShowerFX, m_vExitPos, m_vExitNormal, m_vSurfaceNormal);
		}
	}
	else
	{
		// Create normal fx...

		// Create any exit scale fx associated with this surface...

		for (i=0; i < pSurf->nNumExitScaleFX; i++)
		{
			CScaleFX* pScaleFX = g_pSurfaceMgr->GetScaleFX(pSurf->aExitScaleFXIds[i]);
			g_pFXButeMgr->CreateScaleFX(pScaleFX, m_vExitPos, m_vExitNormal, &m_vExitNormal, &m_rSurfaceRot);
		}

		// Create any exit particle shower fx associated with this surface...

		for (i=0; i < pSurf->nNumExitPShowerFX; i++)
		{
			CPShowerFX* pPShowerFX = g_pSurfaceMgr->GetPShowerFX(pSurf->aExitPShowerFXIds[i]);
			g_pFXButeMgr->CreatePShowerFX(pPShowerFX, m_vExitPos, m_vExitNormal, m_vSurfaceNormal);
		}

		// Create any exit poly debris fx associated with this surface...

		for (i=0; i < pSurf->nNumExitPolyDebrisFX; i++)
		{
			CPolyDebrisFX* pPolyDebrisFX = g_pSurfaceMgr->GetPolyDebrisFX(pSurf->aExitPolyDebrisFXIds[i]);
			g_pFXButeMgr->CreatePolyDebrisFX(pPolyDebrisFX, m_vExitPos, m_vExitNormal, m_vExitNormal);
		}
	}


	// Determine if we should create a beam of light through the surface...

	CreateLightBeamFX(pSurf);
}
void CGibFX::CreateLingeringSmoke(int nIndex)
{
	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr) return;

	CGameSettings* pSettings = g_pInterfaceMgr->GetSettings();
	if (!pSettings) return;

    uint8 nDetailLevel = pSettings->SpecialFXSetting();
	if (nDetailLevel == RS_LOW) return;

	SMCREATESTRUCT sm;

	char* pTexture = "Sprites\\SmokeTest.spr";

	VEC_SET(sm.vColor1, 100.0f, 100.0f, 100.0f);
	VEC_SET(sm.vColor2, 125.0f, 125.0f, 125.0f);
	VEC_SET(sm.vMinDriftVel, -10.0f, 25.0f, -10.0f);
	VEC_SET(sm.vMaxDriftVel, 10.0f, 50.0f, 10.0f);

    LTFLOAT fVolumeRadius        = 10.0f;
    LTFLOAT fLifeTime            = GetRandom(m_fLifeTime * 0.75f, m_fLifeTime);
    LTFLOAT fRadius              = 1500;
    LTFLOAT fParticleCreateDelta = 0.1f;
    LTFLOAT fMinParticleLife     = 1.0f;
    LTFLOAT fMaxParticleLife     = 5.0f;
    uint8  nNumParticles        = 3;
    LTBOOL  bIgnoreWind          = LTFALSE;

	if (IsLiquid(m_eCode))
	{
		GetLiquidColorRange(m_eCode, &sm.vColor1, &sm.vColor2);
		pTexture			= DEFAULT_BUBBLE_TEXTURE;
		fRadius				= 750.0f;
        bIgnoreWind         = LTTRUE;
		fMinParticleLife	= 1.0f;
		fMaxParticleLife	= 1.5f;
	}

	sm.vPos					= m_Emitters[nIndex].m_vPos;
	sm.hServerObj 		    = m_hGib[nIndex];
	sm.fVolumeRadius		= fVolumeRadius;
	sm.fLifeTime			= fLifeTime;
	sm.fRadius				= fRadius;
	sm.fParticleCreateDelta	= fParticleCreateDelta;
	sm.fMinParticleLife		= fMinParticleLife;
	sm.fMaxParticleLife		= fMaxParticleLife;
	sm.nNumParticles		= nNumParticles;
	sm.bIgnoreWind			= bIgnoreWind;
	sm.hstrTexture			= m_pClientDE->CreateString(pTexture);

	psfxMgr->CreateSFX(SFX_SMOKE_ID, &sm);

	m_pClientDE->FreeString(sm.hstrTexture);
}
void CGibFX::CreateMiniBloodExplosion(int nIndex)
{
	// Add a mini blood explosion...

	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr) return;

	CGameSettings* pSettings = g_pInterfaceMgr->GetSettings();
	if (!pSettings) return;

    uint8 nDetailLevel = pSettings->SpecialFXSetting();
	if (nDetailLevel == RS_LOW) return;

	char* szBlood[2] = { "SpecialFX\\ParticleTextures\\Blood_1.dtx",
					     "SpecialFX\\ParticleTextures\\Blood_2.dtx" };

	PARTICLESHOWERCREATESTRUCT ps;

	ps.vPos = m_Emitters[nIndex].m_vPos;
	ps.vPos.y += 30.0f;

	ps.vDir.Init(0, 100, 0);
	VEC_SET(ps.vColor1, 200.0f, 200.0f, 200.0f);
	VEC_SET(ps.vColor2, 255.0f, 255.0f, 255.0f);
	ps.pTexture			= szBlood[GetRandom(0,1)];;
	ps.nParticles		= 50;
	ps.fDuration		= 1.0f;
	ps.fEmissionRadius	= 0.3f;
	ps.fRadius			= 800.0f;
	ps.fGravity			= PSFX_DEFAULT_GRAVITY;

	if (IsLiquid(m_eCode))
	{
		ps.vDir	*= 3.0f;
		ps.fEmissionRadius	= 0.2f;
		ps.fRadius			= 700.0f;
	}

	psfxMgr->CreateSFX(SFX_PARTICLESHOWER_ID, &ps);

	// Play appropriate sound...

	char* pSound = GetGibDieSound();

	if (pSound)
	{
		g_pClientSoundMgr->PlaySoundFromPos(ps.vPos, pSound, 300.0f,
			SOUNDPRIORITY_MISC_LOW);
	}
}
Example #12
0
void CWeaponFX::CreateWeaponSpecificFX()
{
	// Do fire fx beam fx...

	if (m_pAmmo->pFireFX && m_pAmmo->pFireFX->nNumBeamFX > 0)
	{
		for (int i=0; i < m_pAmmo->pFireFX->nNumBeamFX; i++)
		{
			g_pFXButeMgr->CreateBeamFX(m_pAmmo->pFireFX->pBeamFX[i],
				m_vFirePos, m_vPos);
		}
	}

	// Only do impact fx if the client can see the impact position
	// or the impact fx may last a little while...

	if (g_bCanSeeImpactPos || m_pAmmo->fProgDamage > 0.0f || m_pAmmo->nAreaDamage > 0)
	{
		if (IsLiquid(m_eCode))
		{
			// Create underwater weapon fx...

			IFXCS cs;
			cs.eCode		= m_eCode;
			cs.eSurfType	= m_eSurfaceType;
			cs.rSurfRot		= m_rSurfaceRot;
			cs.vDir			= m_vDir;
			cs.vPos			= m_vPos;
			cs.vSurfNormal	= m_vSurfaceNormal;
			cs.fBlastRadius = (LTFLOAT) m_pAmmo->nAreaDamageRadius;
			cs.fTintRange   = (LTFLOAT) (m_pAmmo->nAreaDamageRadius * 5);

			g_pFXButeMgr->CreateImpactFX(m_pAmmo->pUWImpactFX, cs);
		}
		else
		{
			IFXCS cs;
			cs.eCode		= m_eCode;
			cs.eSurfType	= m_eSurfaceType;
			cs.rSurfRot		= m_rSurfaceRot;
			cs.vDir			= m_vDir;
			cs.vPos			= m_vPos;
			cs.vSurfNormal	= m_vSurfaceNormal;
			cs.fBlastRadius = (LTFLOAT) m_pAmmo->nAreaDamageRadius;
			cs.fTintRange   = (LTFLOAT) (m_pAmmo->nAreaDamageRadius * 5);

			g_pFXButeMgr->CreateImpactFX(m_pAmmo->pImpactFX, cs);
		}
	}
}
Example #13
0
void CWeaponFX::CreateMuzzleFX()
{
	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr) return;


	char* pTexture = "SFX\\Impact\\Spr\\Smoke.spr";

	if (IsLiquid(m_eFirePosCode))
	{
		pTexture = DEFAULT_BUBBLE_TEXTURE;
	}

	PARTICLESHOWERCREATESTRUCT sp;

	sp.vPos				= m_vFirePos;
	sp.vDir				= m_vSurfaceNormal * 10.0f;
	sp.pTexture			= pTexture;
	sp.nParticles		= 1;
	sp.fRadius			= 400.0f;
	sp.fDuration		= 1.0f;
	sp.fEmissionRadius	= 0.05f;
	sp.fRadius			= 800.0f;
	sp.fGravity			= 0.0f;

	sp.vColor1.Init(100.0f, 100.0f, 100.0f);
	sp.vColor2.Init(125.0f, 125.0f, 125.0f);

	if (IsLiquid(m_eFirePosCode))
	{
		GetLiquidColorRange(m_eFirePosCode, &sp.vColor1, &sp.vColor2);
		sp.fRadius		= 600.0f;
		sp.fGravity		= 50.0f;
	}

	psfxMgr->CreateSFX(SFX_PARTICLESHOWER_ID, &sp);
}
Example #14
0
int Tile::GetPic()
{
    const unsigned int LEVEL_PIX[]={250,',','_','-',223,176,177,178};

    int h=GetHeight(); //performance!!!
    if (h<0)
        return ' ';
    if (IsSolid(h))
        return LEVEL_PIX[h];
    if (IsLiquid(h))
        //return '0'+h+1;
        return (h%2)?126:184;
    if (IsGas(h))
        if (h>2)
            return '%';
        else
            return '.';
    return ' ';
}
Example #15
0
void InitMovingObject(MovingObject *pObject, DVector *pPos, DVector *pVelocity)
{
	memset(pObject, 0, sizeof(MovingObject));
	VEC_COPY(pObject->m_Pos, *pPos);
	VEC_COPY(pObject->m_LastPos, *pPos);
	VEC_COPY(pObject->m_Velocity, *pVelocity);

	ClientDE* pClientDE = g_normalPhysicsState.m_pClientDE;
	if (!pClientDE) return;

	// Determine if we are in any containers (like liquid) that would
	// affect physics...

	DDWORD dwUserFlags;
	HLOCALOBJ objList[1];
	DDWORD dwNum = pClientDE->GetPointContainers(&pObject->m_Pos, objList, 1);

	if (dwNum > 0 && objList[0])
	{
		pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags);
	}

	if(dwNum > 0)
	{
		D_WORD code;
		if (pClientDE->GetContainerCode(objList[0], &code))
		{
			ContainerCode eCode = (ContainerCode)code;

			if (IsLiquid(eCode))
			{
				pObject->m_PhysicsFlags |= MO_LIQUID;
			}
		}
	}
}
Example #16
0
LTBOOL CWeaponFX::CreateObject(ILTClient* pClientDE)
{
    if (!CSpecialFX::CreateObject(pClientDE) || !g_pWeaponMgr) return LTFALSE;

	CGameSettings* pSettings = g_pInterfaceMgr->GetSettings();
    if (!pSettings) return LTFALSE;

	// Set up our data members...

	// Set the local client id...

    uint32 dwId;
    g_pLTClient->GetLocalClientID(&dwId);
    m_nLocalId = (uint8)dwId;


	m_nDetailLevel = pSettings->SpecialFXSetting();

	// Fire pos may get tweaked a little...

	m_vFirePos = CalcFirePos(m_vFirePos);

	m_vDir = m_vPos - m_vFirePos;
	m_fFireDistance = m_vDir.Mag();
	m_vDir.Norm();

    g_pLTClient->AlignRotation(&m_rSurfaceRot, &m_vSurfaceNormal, LTNULL);
    g_pLTClient->AlignRotation(&m_rDirRot, &m_vDir, LTNULL);

	SetupExitInfo();



	// Calculate if the camera can see the fire position and the impact
	// position...

	g_bCanSeeImpactPos	= LTTRUE;
	g_bCanSeeFirePos	= LTTRUE;
	g_bDistantImpactPos	= LTFALSE;
	g_bDistantFirePos	= LTFALSE;

	if (g_vtWeaponFXUseFOVPerformance.GetFloat())
	{
		HOBJECT hCamera = g_pGameClientShell->GetCamera();
		LTVector vCameraPos, vU, vR, vF, vDir;
		LTRotation rCameraRot;
		g_pLTClient->GetObjectPos(hCamera, &vCameraPos);
		g_pLTClient->GetObjectRotation(hCamera, &rCameraRot);
		g_pLTClient->GetRotationVectors(&rCameraRot, &vU, &vR, &vF);

		vDir = m_vPos - vCameraPos;
		LTFLOAT fImpactDist = vDir.Mag();

		if (fImpactDist > g_vtWeaponFXMaxImpactDist.GetFloat())
		{
			g_bDistantImpactPos = LTTRUE;
		}

		vDir.Norm();

		LTFLOAT fMul = VEC_DOT(vDir, vF);
		g_bCanSeeImpactPos = (fMul < g_vtWeaponFXMinImpactDot.GetFloat() ? LTFALSE : LTTRUE);

		// In multiplayer we need to account for impacts that occur around
		// our camera that we didn't cause (this is also an issue in single
		// player, but due to the singler player gameplay dynamics it isn't
		// as noticeable)...

		if (!g_bCanSeeImpactPos && IsMultiplayerGame())
		{
			// Somebody else shot this...if the impact is close enough, we 
			// "saw" it...
			if (m_nLocalId != m_nShooterId && fImpactDist <= g_vtWeaponFXMaxMultiImpactDist.GetFloat())
			{
				g_bCanSeeImpactPos = LTTRUE;
			}
		}

		vDir = m_vFirePos - vCameraPos;

		if (vDir.Mag() > g_vtWeaponFXMaxFireDist.GetFloat())
		{
			g_bDistantFirePos = LTTRUE;
		}

		vDir.Norm();

		fMul = VEC_DOT(vDir, vF);
		g_bCanSeeFirePos = (fMul < g_vtWeaponFXMinFireDot.GetFloat() ? LTFALSE : LTTRUE);
	}



	// Determine what container the sfx is in...

	HLOCALOBJ objList[1];
    LTVector vTestPos = m_vPos + m_vSurfaceNormal;  // Test a little closer...
    uint32 dwNum = g_pLTClient->GetPointContainers(&vTestPos, objList, 1);

	if (dwNum > 0 && objList[0])
	{
        uint32 dwUserFlags;
        g_pLTClient->GetObjectUserFlags(objList[0], &dwUserFlags);

		if (dwUserFlags & USRFLG_VISIBLE)
		{
            uint16 dwCode;
            if (g_pLTClient->GetContainerCode(objList[0], &dwCode))
			{
				m_eCode = (ContainerCode)dwCode;
			}
		}
	}

	// Determine if the fire point is in liquid

	vTestPos = m_vFirePos + m_vDir;  // Test a little further in...
    dwNum = g_pLTClient->GetPointContainers(&vTestPos, objList, 1);

	if (dwNum > 0 && objList[0])
	{
        uint32 dwUserFlags;
        g_pLTClient->GetObjectUserFlags(objList[0], &dwUserFlags);

		if (dwUserFlags & USRFLG_VISIBLE)
		{
            uint16 dwCode;
            if (g_pLTClient->GetContainerCode(objList[0], &dwCode))
			{
				m_eFirePosCode = (ContainerCode)dwCode;
			}
		}
	}


	if (IsLiquid(m_eCode))
	{
		m_wImpactFX	= m_pAmmo->pUWImpactFX ? m_pAmmo->pUWImpactFX->nFlags : 0;
	}
	else
	{
		m_wImpactFX	= m_pAmmo->pImpactFX ? m_pAmmo->pImpactFX->nFlags : 0;
	}

	m_wFireFX = m_pAmmo->pFireFX ? m_pAmmo->pFireFX->nFlags : 0;

	// Assume alt-fire, silenced, and tracer...these will be cleared by
	// IgnoreFX if not used...

	m_wFireFX |= WFX_ALTFIRESND | WFX_SILENCED | WFX_TRACER;

	// Assume impact ding, it will be cleared if not used...

	m_wImpactFX |= WFX_IMPACTDING;

	// Clear all the fire fx we want to ignore...

	m_wFireFX &= ~m_wIgnoreFX;
	m_wImpactFX &= ~m_wIgnoreFX;


	// See if this is a redundant weapon fx (i.e., this client shot the
	// weapon so they've already seen this fx)...

	if (g_pGameClientShell->IsMultiplayerGame())
	{
		if (m_pAmmo->eType != PROJECTILE)
		{
			if (!m_bLocal && m_nLocalId >= 0 && m_nLocalId == m_nShooterId)
			{
				if (m_wImpactFX & WFX_IMPACTDING)
				{
					if (g_vtMultiDing.GetFloat())
					{
						PlayImpactDing();
					}
				}

                return LTFALSE;
			}
		}
	}


	// Show the fire path...(debugging...)

	if (g_cvarShowFirePath.GetFloat() > 0)
	{
		PLFXCREATESTRUCT pls;

		pls.vStartPos			= m_vFirePos;
		pls.vEndPos				= m_vPos;
        pls.vInnerColorStart    = LTVector(GetRandom(127.0f, 255.0f), GetRandom(127.0f, 255.0f), GetRandom(127.0f, 255.0f));
		pls.vInnerColorEnd		= pls.vInnerColorStart;
        pls.vOuterColorStart    = LTVector(0, 0, 0);
        pls.vOuterColorEnd      = LTVector(0, 0, 0);
		pls.fAlphaStart			= 1.0f;
		pls.fAlphaEnd			= 1.0f;
		pls.fMinWidth			= 0;
		pls.fMaxWidth			= 10;
		pls.fMinDistMult		= 1.0f;
		pls.fMaxDistMult		= 1.0f;
		pls.fLifeTime			= 10.0f;
		pls.fAlphaLifeTime		= 10.0f;
		pls.fPerturb			= 0.0f;
        pls.bAdditive           = LTFALSE;
		pls.nWidthStyle			= PLWS_CONSTANT;
		pls.nNumSegments		= 2;

		CSpecialFX* pFX = g_pGameClientShell->GetSFXMgr()->CreateSFX(SFX_POLYLINE_ID, &pls);
		if (pFX) pFX->Update();
	}


	// If the surface is the sky, don't create any impact related fx...

	if (m_eSurfaceType != ST_SKY || (m_wImpactFX & WFX_IMPACTONSKY))
	{
		CreateWeaponSpecificFX();

		if (g_bCanSeeImpactPos)
		{
			if ((m_wImpactFX & WFX_MARK) && ShowsMark(m_eSurfaceType) && (LTBOOL)GetConsoleInt("MarkShow", 1))
			{
				LTBOOL bCreateMark = LTTRUE;
				if (g_bDistantImpactPos && m_nLocalId == m_nShooterId)
				{
					// Assume we'll see the mark if we're zoomed in ;)
					bCreateMark = g_pGameClientShell->IsZoomed();
				}

				if (bCreateMark)
				{
					CreateMark(m_vPos, m_vSurfaceNormal, m_rSurfaceRot, m_eSurfaceType);
				}
			}

			CreateSurfaceSpecificFX();
		}

		PlayImpactSound();
	}


	if (IsBulletTrailWeapon())
	{
		if (IsLiquid(m_eFirePosCode))
		{
			if (m_nDetailLevel != RS_LOW)
			{
				CreateBulletTrail(&m_vFirePos);
			}
		}
	}


	// No tracers under water...

	if ((LTBOOL)GetConsoleInt("Tracers", 1) && (m_wFireFX & WFX_TRACER) && !IsLiquid(m_eCode))
	{
		CreateTracer();
	}

	if (g_bCanSeeFirePos)
	{
		// Only do muzzle fx for the client (not for AIs)...

		if ((m_wFireFX & WFX_MUZZLE) && (m_nLocalId == m_nShooterId))
		{
			CreateMuzzleFX();
		}

		if (!g_bDistantFirePos &&
			(LTBOOL)GetConsoleInt("ShellCasings", 1) &&
			(m_wFireFX & WFX_SHELL))
		{
			CreateShell();
		}

		if ((m_wFireFX & WFX_LIGHT))
		{
			CreateMuzzleLight();
		}
	}

	if ((m_wFireFX & WFX_FIRESOUND) || (m_wFireFX & WFX_ALTFIRESND) || (m_wFireFX & WFX_SILENCED))
	{
		PlayFireSound();
	}

	// Only do fly-by sounds for weapons that leave bullet trails...

	if (IsBulletTrailWeapon())
	{
		PlayBulletFlyBySound();
	}


    return LTFALSE;  // Just delete me, I'm done :)
}
LTBOOL CParticleTrailSegmentFX::CreateObject(ILTClient *pClientDE)
{
    if (!pClientDE || !m_hServerObject) return LTFALSE;

	if (m_nType & PT_SMOKE_LONG)
	{
		m_pTextureName = "SFX\\Smoke\\Spr\\WhiteTrailLong.spr";

        m_basecs.bAdjustParticleScale = LTTRUE;
		m_basecs.fStartParticleScale  = g_cvarSmokeTrailStartScale.GetFloat();
		m_basecs.fEndParticleScale	  = g_cvarSmokeTrailLWEndScale.GetFloat();

        m_basecs.bAdjustParticleAlpha = LTTRUE;
		m_basecs.fStartParticleAlpha  = g_cvarSmokeTrailStartAlpha.GetFloat();
		m_basecs.fEndParticleAlpha	  = g_cvarSmokeTrailEndAlpha.GetFloat();
	}
	else if (m_nType & PT_SMOKE)
	{
		m_pTextureName = "SFX\\Smoke\\Spr\\WhiteTrailShort.spr";

        m_basecs.bAdjustParticleScale = LTTRUE;
		m_basecs.fStartParticleScale  = g_cvarSmokeTrailStartScale.GetFloat();
		m_basecs.fEndParticleScale	  = g_cvarSmokeTrailSWEndScale.GetFloat();

        m_basecs.bAdjustParticleAlpha = LTTRUE;
		m_basecs.fStartParticleAlpha  = g_cvarSmokeTrailStartAlpha.GetFloat();
		m_basecs.fEndParticleAlpha	  = g_cvarSmokeTrailEndAlpha.GetFloat();
	}
	else if (m_nType & PT_SMOKE_BLACK)
	{
		m_pTextureName = "SFX\\Smoke\\Spr\\BlackTrailShort.spr";

        m_basecs.bAdjustParticleScale = LTTRUE;
		m_basecs.fStartParticleScale  = g_cvarSmokeTrailStartScale.GetFloat();
		m_basecs.fEndParticleScale	  = g_cvarSmokeTrailSBEndScale.GetFloat();

        m_basecs.bAdjustParticleAlpha = LTTRUE;
		m_basecs.fStartParticleAlpha  = g_cvarSmokeTrailStartAlpha.GetFloat();
		m_basecs.fEndParticleAlpha	  = g_cvarSmokeTrailEndAlpha.GetFloat();
	}
	else if ((m_nType & PT_GIBSMOKE))
	{
		m_pTextureName = "SFX\\Impact\\Spr\\Smoke.spr";

        m_basecs.bAdjustParticleScale = LTTRUE;
		m_basecs.fStartParticleScale  = g_cvarSmokeTrailStartScale.GetFloat();
		m_basecs.fEndParticleScale	  = g_cvarSmokeTrailSWEndScale.GetFloat();

        m_basecs.bAdjustParticleAlpha = LTTRUE;
		m_basecs.fStartParticleAlpha  = g_cvarSmokeTrailStartAlpha.GetFloat();
		m_basecs.fEndParticleAlpha	  = g_cvarSmokeTrailEndAlpha.GetFloat();
	}
	else if (m_nType & PT_BLOOD)
	{
		if (GetRandom(0, 1) == 0)
		{
			m_pTextureName = "SFX\\Particle\\Blood_1.dtx";
		}
		else
		{
			m_pTextureName = "SFX\\Particle\\Blood_2.dtx";
		}
	}

	// Determine if we are in a liquid...

    LTVector vPos;
	pClientDE->GetObjectPos(m_hServerObject, &vPos);

	HLOCALOBJ objList[1];
    uint32 dwNum = pClientDE->GetPointContainers(&vPos, objList, 1);

	if (dwNum > 0 && objList[0])
	{
        uint32 dwUserFlags;
		pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags);

		if (dwUserFlags & USRFLG_VISIBLE)
		{
            uint16 dwCode;
			if (pClientDE->GetContainerCode(objList[0], &dwCode))
			{
				if (IsLiquid((ContainerCode)dwCode))
				{
					// Don't create blood under water...

					if (m_nType & PT_BLOOD)
					{
                        m_bWantRemove = LTTRUE;
						m_fLifeTime = 0.0f;
						m_fFadeTime = 0.0f;
                        return LTFALSE;
					}

					m_fRadius = 500.0f;
					m_fGravity = 5.0f;
					m_nNumPerPuff *= 3;
                    m_bIgnoreWind = LTTRUE;
					m_pTextureName = DEFAULT_BUBBLE_TEXTURE;
					GetLiquidColorRange((ContainerCode)dwCode, &m_vColor1, &m_vColor2);
				}
			}
		}
	}

	return CBaseParticleSystemFX::CreateObject(pClientDE);
}
Example #18
0
void CLipstickProx::UpdateGrenade()
{
	CGrenade::UpdateGrenade();

	// If we're doing normal (in-air) updates, don't do any more
	// processing...

	if (m_bUpdating || !m_pClassData) return;


	// Make sure we aren't moving anymore...
		
	LTVector vVel(0, 0, 0);
	g_pLTServer->SetVelocity(m_hObject, &vVel);


	// Waiting to go boom...

	if (m_bActivated && m_DetonateTime.Stopped())
	{
        Detonate(LTNULL);
		return;
	}


	// See if it is time to arm yet...

	if (!m_bArmed && m_ArmTime.Stopped())
	{
        m_bArmed = LTTRUE;

		// Play armed sound...

		if (m_pClassData->szArmSound[0])
		{
			int nVolume = IsLiquid(m_eContainerCode) ? 50 : 100;

            LTVector vPos;
            g_pLTServer->GetObjectPos(m_hObject, &vPos);

			g_pServerSoundMgr->PlaySoundFromPos(vPos, m_pClassData->szArmSound,
                (LTFLOAT)m_pClassData->nArmSndRadius, SOUNDPRIORITY_MISC_MEDIUM,
				0, nVolume);
		}
	}


	// Is there anything close enough to cause us to go boom?

	if (!m_bActivated && m_bArmed)
	{
		if (!m_pAmmoData) return;

        LTFLOAT fRadius = (LTFLOAT) m_pClassData->nActivateRadius;

		// NEED TO FIGURE OUT A BETTER WAY TO DO THIS!!!

        LTVector vPos;
        g_pLTServer->GetObjectPos(m_hObject, &vPos);
        ObjectList* pList = g_pLTServer->FindObjectsTouchingSphere(&vPos, fRadius);
		if (!pList) return;

		ObjectLink* pLink = pList->m_pFirstLink;
		while (pLink)
		{
			if (g_pGameServerShell->GetGameType() == COOPERATIVE_ASSAULT && IsPlayer(pLink->m_hObject) && IsPlayer(m_hFiredFrom) && g_vtNetFriendlyFire.GetFloat() < 1.0f)
			{
				CPlayerObj* pPlayer1 = (CPlayerObj*) g_pLTServer->HandleToObject(m_hFiredFrom);
				CPlayerObj* pPlayer2 = (CPlayerObj*) g_pLTServer->HandleToObject(pLink->m_hObject);
				if (pPlayer1 != pPlayer2 && pPlayer1->GetTeamID() == pPlayer2->GetTeamID())
				{
					//go to next obj
					pLink = pLink->m_pNext;
					continue;
				}
			}
			if (IsCharacter(pLink->m_hObject))
			{
                m_bActivated = LTTRUE;

                LTFLOAT fDelay = g_vtProxGrenadeDetonateDelay.GetFloat() < 0.0f ?
					m_pClassData->fActivateDelay : g_vtProxGrenadeDetonateDelay.GetFloat();

				m_DetonateTime.Start(fDelay);

				// Play activation sound...

				if (m_pClassData->szActivateSound[0])
				{
					int nVolume = IsLiquid(m_eContainerCode) ? 50 : 100;

                    LTVector vPos;
                    g_pLTServer->GetObjectPos(m_hObject, &vPos);

					g_pServerSoundMgr->PlaySoundFromPos(vPos, m_pClassData->szActivateSound,
                        (LTFLOAT) m_pClassData->nActivateSndRadius,
						SOUNDPRIORITY_MISC_MEDIUM, 0, nVolume);
				}

				break;
			}

			pLink = pLink->m_pNext;
		}
        g_pLTServer->RelinquishList(pList);
	}
}
Example #19
0
void VolumeBrush::UpdatePhysics(ContainerPhysics* pCPStruct)
{
    CServerDE* pServerDE = GetServerDE();
    if (m_bHidden || !pServerDE || !pCPStruct || !pCPStruct->m_hObject) return;

    DFLOAT fUpdateDelta = pServerDE->GetFrameTime();

    // Check to see if this object is the player object...

    if (!pServerDE->IsKindOf(pServerDE->GetObjectClass(pCPStruct->m_hObject), m_hPlayerClass))
    {
        // Check to see if this object is a character object...

        DBOOL bCharacter = DFALSE;
        HCLASS hBaseCharClass = pServerDE->GetClass("CBaseCharacter");

        if (pServerDE->IsKindOf(pServerDE->GetObjectClass(pCPStruct->m_hObject), hBaseCharClass))
        {
            bCharacter = DTRUE;

            if (m_bLocked)
            {
                // See if they have the key we need to unlock
                HMESSAGEWRITE hMessage = pServerDE->StartMessageToObject((LPBASECLASS)this, pCPStruct->m_hObject, MID_KEYQUERY);
                pServerDE->WriteToMessageHString(hMessage, m_hstrKeyName);
                pServerDE->EndMessage(hMessage);
            }
        }


        // Update velocity...

        // Dampen velocity and acceleration based on the viscosity of the container...

        if (m_fViscosity > 0.0f)
        {
            VEC_MULSCALAR(pCPStruct->m_Velocity, pCPStruct->m_Velocity, m_fViscosity);
            VEC_MULSCALAR(pCPStruct->m_Acceleration, pCPStruct->m_Acceleration, m_fViscosity);
        }


        // Do special liquid / zero gravity handling...

        if (IsLiquid(m_eContainerCode))
        {
            UpdateLiquidPhysics(pCPStruct, bCharacter);
        }


        // Add any current...

        // Make current relative to update delta (actually change the REAL velocity)...

        DVector vCurrent;
        VEC_MULSCALAR(vCurrent, m_vCurrent, fUpdateDelta);

        VEC_ADD(pCPStruct->m_Velocity, pCPStruct->m_Velocity, vCurrent);
    }

    // Update damage...

    // Make damage relative to update delta...

    if (m_fDamage)
    {
        DFLOAT fTime = pServerDE->GetTime();
        DFLOAT fDamageDeltaTime = fTime - m_fLastDamageTime;

        if (fDamageDeltaTime >= DAMAGE_UPDATE_DELTA || fTime == m_fLastDamageTime)
        {
            m_fLastDamageTime = fTime;

            DVector vDir;
            VEC_INIT(vDir);

            DamageObject(m_hObject, this, pCPStruct->m_hObject, m_fDamage * DAMAGE_UPDATE_DELTA, vDir, vDir, m_nDamageType);
        }
    }

}
Example #20
0
void VolumeBrush::UpdatePhysics(ContainerPhysics* pCPStruct)
{
	if (m_bHidden || !pCPStruct || !pCPStruct->m_hObject) return;

    LTFLOAT fUpdateDelta = g_pLTServer->GetFrameTime();


	// Let the character know if they are in liquid...

	if (IsLiquid(m_eContainerCode) && IsCharacter(pCPStruct->m_hObject))
	{
        CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(pCPStruct->m_hObject);
		if (pCharacter)
		{
			pCharacter->UpdateInLiquid(this, pCPStruct);
		}
	}


	// Player container physics is done on the client...

	if (!IsPlayer(pCPStruct->m_hObject))
	{
		// Dampen velocity based on the viscosity of the container...

        LTVector vVel, vCurVel;
		vVel = vCurVel = pCPStruct->m_Velocity;

		if (m_fViscosity > 0.0f && VEC_MAG(vCurVel) > 1.0f)
		{
            LTVector vDir;
			VEC_COPY(vDir, vCurVel);
			VEC_NORM(vDir);

            LTFLOAT fAdjust = MAX_CONTAINER_VISCOSITY * m_fViscosity * fUpdateDelta;

			vVel = (vDir * fAdjust);

			if (VEC_MAG(vVel) < VEC_MAG(vCurVel))
			{
				VEC_SUB(vVel, vCurVel, vVel);
			}
			else
			{
				VEC_INIT(vVel);
			}

			vVel += (m_vCurrent * fUpdateDelta);

			pCPStruct->m_Velocity = vVel;
		}


		// Do special liquid handling...

		if (IsLiquid(m_eContainerCode))
		{
			UpdateLiquidPhysics(pCPStruct);
		}
	}


	// Update damage...

	// Make damage relative to update delta...

    LTFLOAT fDamage = 0.0f;
	if (m_fDamage > 0.0f)
	{
		fDamage = m_fDamage * fUpdateDelta;
	}

	// Damage using progressive damage.  This insures that the correct
	// damage effect is shown on the client...

	if (fDamage)
	{
		DamageStruct damage;

		damage.eType	  = m_eDamageType;
		damage.fDamage	  = fDamage;
		damage.hDamager   = m_hObject;

		// Use progressive damage...
		damage.fDuration  = 0.25f;
		damage.hContainer = m_hObject;

		damage.DoDamage(this, pCPStruct->m_hObject);
	}
}
Example #21
0
void CWeaponFX::CreateSurfaceSpecificFX()
{
	CGameSettings* pSettings = g_pInterfaceMgr->GetSettings();
	if (!pSettings) return;

	// Don't do gore fx...

	if (m_eSurfaceType == ST_FLESH)
	{
		if (!pSettings->Gore())
		{
			return;
		}

		if (m_pAmmo->eType == VECTOR && m_pAmmo->eInstDamageType == DT_BULLET)
		{
			CreateBloodSplatFX();
		}
	}

	if ((m_wFireFX & WFX_EXITMARK) && ShowsMark(m_eExitSurface))
	{
		CreateExitMark();
	}

	if (m_wFireFX & WFX_EXITDEBRIS)
	{
		CreateExitDebris();
	}

	if (!m_pAmmo || !m_pAmmo->pImpactFX) return;
	if (!m_pAmmo->pImpactFX->bDoSurfaceFX) return;


	// Create the surface specific fx...

	int i;
	SURFACE* pSurf = g_pSurfaceMgr->GetSurface(m_eSurfaceType);
	if (pSurf)
	{
		if (IsLiquid(m_eCode))
		{
			// Create underwater fx...

			// Create any impact particle shower fx associated with this surface...

			for (i=0; i < pSurf->nNumUWImpactPShowerFX; i++)
			{
				CPShowerFX* pPShowerFX = g_pSurfaceMgr->GetPShowerFX(pSurf->aUWImpactPShowerFXIds[i]);
				g_pFXButeMgr->CreatePShowerFX(pPShowerFX, m_vPos, m_vDir, m_vSurfaceNormal);
			}
		}
		else
		{
			// Create normal fx...

			// Create any impact scale fx associated with this surface...

			for (i=0; i < pSurf->nNumImpactScaleFX; i++)
			{
				CScaleFX* pScaleFX = g_pSurfaceMgr->GetScaleFX(pSurf->aImpactScaleFXIds[i]);
				g_pFXButeMgr->CreateScaleFX(pScaleFX, m_vPos, m_vDir, &m_vSurfaceNormal, &m_rSurfaceRot);
			}

			// Create any impact particle shower fx associated with this surface...

			for (i=0; i < pSurf->nNumImpactPShowerFX; i++)
			{
				CPShowerFX* pPShowerFX = g_pSurfaceMgr->GetPShowerFX(pSurf->aImpactPShowerFXIds[i]);
				g_pFXButeMgr->CreatePShowerFX(pPShowerFX, m_vPos, m_vDir, m_vSurfaceNormal);
			}

			// Create any impact poly debris fx associated with this surface...

			if (g_vtCreatePolyDebris.GetFloat())
			{
				for (i=0; i < pSurf->nNumImpactPolyDebrisFX; i++)
				{
					CPolyDebrisFX* pPolyDebrisFX = g_pSurfaceMgr->GetPolyDebrisFX(pSurf->aImpactPolyDebrisFXIds[i]);
					g_pFXButeMgr->CreatePolyDebrisFX(pPolyDebrisFX, m_vPos, m_vDir, m_vSurfaceNormal);
				}
			}
		}
	}
}
Example #22
0
void CGrenade::HandleImpact(HOBJECT hObj)
{
	if (!g_vtGrenadeDampenPercent.IsInitted())
	{
        g_vtGrenadeDampenPercent.Init(g_pLTServer, "GrenadeDampenPercent", LTNULL, DEFAULT_GRENADE_DAMPEN_PERCENT);
	}

	if (!g_vtGrenadeMinVelMag.IsInitted())
	{
        g_vtGrenadeMinVelMag.Init(g_pLTServer, "GrenadeMinVelMag", LTNULL, DEFAULT_GRENADE_MIN_VELOCITY);
	}


    LTVector vVel;
    g_pLTServer->GetVelocity(m_hObject, &vVel);


	// See if we are impacting on liquid...

    LTBOOL bEnteringLiquid = LTFALSE;
    uint16 code;
    if (g_pLTServer->GetContainerCode(hObj, &code))
	{
		if (IsLiquid((ContainerCode)code))
		{
            bEnteringLiquid = LTTRUE;
		}
	}


	CollisionInfo info;
    g_pLTServer->GetLastCollision(&info);


	// Do the bounce, if the object we hit isn't liquid...

	if (!bEnteringLiquid)
	{
		vVel += (info.m_vStopVel * 2.0f);
	}


	// Dampen the grenade's new velocity based on the surface type...

    LTFLOAT fDampenPercent = g_vtGrenadeDampenPercent.GetFloat();

	m_eLastHitSurface = GetSurfaceType(info);
	SURFACE* pSurf = g_pSurfaceMgr->GetSurface(m_eLastHitSurface);
	if (pSurf)
	{
		// Play a bounce sound (based on the surface type) if one isn't
		// already playing...

		if ( ShouldPlayBounceSound(pSurf) )
		{
			// Only play one sound at a time...

			if (m_hBounceSnd)
			{
                g_pLTServer->KillSound(m_hBounceSnd);
                m_hBounceSnd = LTNULL;
			}

            uint32 dwFlags = PLAYSOUND_GETHANDLE | PLAYSOUND_TIME;

			int nVolume	= IsLiquid(m_eContainerCode) ? 50 : 100;

            LTVector vPos;
            g_pLTServer->GetObjectPos(m_hObject, &vPos);

			m_hBounceSnd = g_pServerSoundMgr->PlaySoundFromPos(vPos, (char*)GetBounceSound(pSurf),
				pSurf->fGrenadeSndRadius, SOUNDPRIORITY_MISC_MEDIUM, dwFlags, nVolume);
		}

		fDampenPercent = (1.0f - pSurf->fHardness);
	}

	fDampenPercent = fDampenPercent > 1.0f ? 1.0f : (fDampenPercent < 0.0f ? 0.0f : fDampenPercent);

	vVel *= (1.0f - fDampenPercent);


	// See if we should come to a rest...

    LTVector vTest = vVel;
	vTest.y = 0.0f;

	if (vTest.Mag() < g_vtGrenadeMinVelMag.GetFloat())
	{
		// If we're on the ground (or an object), stop movement...

		CollisionInfo standingInfo;
        g_pLTServer->GetStandingOn(m_hObject, &standingInfo);

		CollisionInfo* pInfo = standingInfo.m_hObject ? &standingInfo : &info;

		if (pInfo->m_hObject)
		{
			// Don't stop on walls...

			if (pInfo->m_Plane.m_Normal.y > 0.75f)
			{
				vVel.Init();

				// Turn off gravity, solid, and touch notify....

                uint32 dwFlags = g_pLTServer->GetObjectFlags(m_hObject);
				dwFlags &= ~(FLAG_GRAVITY | FLAG_TOUCH_NOTIFY | FLAG_SOLID);

                g_pLTServer->SetObjectFlags(m_hObject, dwFlags);

				// Rotate to rest...

				RotateToRest();
			}
		}
	}


	// Reset rotation velocities due to the bounce...

	ResetRotationVel(&vVel, pSurf);


	// We need to subtact this out because the engine will add it back in,
	// kind of a kludge but necessary...

	vVel -= info.m_vStopVel;


    g_pLTServer->SetVelocity(m_hObject, &vVel);

	m_cBounces++;
}