示例#1
0
void CWeaponFX::CreateTracer()
{
	if (!m_pAmmo || !m_pAmmo->pTracerFX) return;

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

	if (m_nDetailLevel != RS_HIGH && GetRandom(1, 2) == 1) return;

	// Create tracer...

	if (m_fFireDistance > 100.0f)
	{
		TRCREATESTRUCT tracer;

		// Make tracer start in front of gun a little ways...

		tracer.vStartPos	= m_vFirePos; // + (m_vDir * 25.0f);
		tracer.vEndPos		= m_vPos;
		tracer.pTracerFX	= m_pAmmo->pTracerFX;

		CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_TRACER_ID, &tracer);
		if (pFX) pFX->Update();
	}
}
void CGibFX::CreateBloodSpray()
{
	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr) return;

	BSCREATESTRUCT sc;

	VEC_COPY(sc.vPos, m_vPos);
	sc.vPos.y += 30.0f;
	VEC_SET(sc.vVel, 0.0f, -20.0f, 0.0f);
	VEC_SET(sc.vInitialScale, GetRandom(2.0f, 4.0f), GetRandom(2.0f, 4.0f), 1.0f);
	VEC_SET(sc.vFinalScale, GetRandom(0.5f, 0.8f), GetRandom(0.5f, 0.8f), 1.0f);

	sc.dwFlags			= FLAG_VISIBLE | FLAG_SPRITEBIAS | FLAG_NOLIGHT;
	sc.fLifeTime		= 0.5f;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.nType			= OT_SPRITE;

	char* pBloodFiles[] =
	{
		"Sprites\\BloodSplat1.spr",
		"Sprites\\BloodSplat2.spr",
		"Sprites\\BloodSplat3.spr",
		"Sprites\\BloodSplat4.spr"
	};

	sc.pFilename = pBloodFiles[GetRandom(0,3)];


	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_SCALE_ID, &sc);
	if (pFX) pFX->Update();
}
示例#3
0
void CWeaponFX::CreateBulletTrail(LTVector *pvStartPos)
{
	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
	if (!psfxMgr || !pvStartPos) return;

    LTVector vColor1, vColor2;
	vColor1.Init(200.0f, 200.0f, 200.0f);
	vColor2.Init(255.0f, 255.0f, 255.0f);

	BTCREATESTRUCT bt;

	bt.vStartPos		= *pvStartPos;
	bt.vDir				= m_vDir;
	bt.vColor1			= vColor1;
	bt.vColor2			= vColor2;
	bt.fLifeTime		= 0.5f;
	bt.fFadeTime		= 0.3f;
	bt.fRadius			= 400.0f;
	bt.fGravity			= 0.0f;
	bt.fNumParticles	= (m_nDetailLevel == RS_MED) ? 15.0f : 30.0f;

	CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_BULLETTRAIL_ID, &bt);

	// Let each bullet trail do its initial update...

	if (pFX) pFX->Update();
}
示例#4
0
LTBOOL CParticleTrailFX::Update()
{
	CSFXMgr* psfxMgr = g_pRiotClientShell->GetSFXMgr();
	if (!psfxMgr || !m_pClientDE || !m_hServerObject) return LTFALSE;

	LTFLOAT fTime = m_pClientDE->GetTime();

	// Check to see if we should go away...

	if (m_bWantRemove)
	{
		return LTFALSE;
	}


	// See if it is time to create a new trail segment...

	if ((m_fStartTime < 0) || (fTime > m_fStartTime + m_fSegmentTime))
	{
		PTSCREATESTRUCT pts;

		pts.hServerObj = m_hServerObject;
		VEC_COPY(pts.vColor1, m_vColor1);
		VEC_COPY(pts.vColor2, m_vColor2);
		VEC_COPY(pts.vDriftOffset, m_vDriftOffset);
		pts.nType			= m_nType;
		pts.bSmall			= m_bSmall;
		pts.fLifeTime		= m_fLifeTime;
		pts.fFadeTime		= m_fFadeTime;
		pts.fOffsetTime		= m_fOffsetTime;
		pts.fRadius			= 2000.0f;
		pts.fGravity		= 0.0f;
		pts.nNumPerPuff		= m_nNumPerPuff;

		if (m_nType & PT_BLOOD)
		{
			pts.fRadius	 = 600.0f;
		}
		else if (m_nType & PT_GIBSMOKE)
		{
			pts.fRadius	 = 1250.0f;
		}

		CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_PARTICLETRAILSEG_ID, &pts);

		// Let each Particle segment do its initial update...

		if (pFX) pFX->Update();

		m_fStartTime = fTime;
	}

	return LTTRUE;
}
示例#5
0
DBOOL CSmokeTrailFX::Update()
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	CSFXMgr* psfxMgr = pShell->GetSFXMgr();
	if (!psfxMgr || !m_pClientDE || !m_hServerObject) return DFALSE;

	DFLOAT fTime = m_pClientDE->GetTime();

	// Check to see if we should go away...

	if (m_bWantRemove)
	{
		return DFALSE;
	}


	// See if it is time to create a new trail segment...
	if ((m_fStartTime < 0) || (fTime > m_fStartTime + m_fSegmentTime))
	{
		STSCREATESTRUCT sts;

		sts.hServerObj = m_hServerObject;
		VEC_COPY(sts.vVel, m_vVel);
		VEC_COPY(sts.vColor1, m_vColor1);
		VEC_COPY(sts.vColor2, m_vColor2);
		sts.bSmall			= m_bSmall;
		sts.fLifeTime		= m_fLifeTime;
		sts.fFadeTime		= m_fFadeTime;
		sts.fOffsetTime		= m_fOffsetTime;
		sts.fRadius			= 1000.0f;
		sts.fGravity		= 15.0f;
		sts.nNumPerPuff		= m_nNumPerPuff;

		if(VEC_MAG(sts.vVel) < 1.0f)
		{
			sts.fGravity = 25.0f;
			sts.fOffsetTime = 0.1f;
			sts.fRadius = 500.0f;
			sts.nNumPerPuff = 1;
			sts.fLifeTime = 1.0f;
		}

 		CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_SMOKETRAILSEG_ID, &sts, DFALSE, this);

		// Let each smoke segment do its initial update...
		if (pFX) pFX->Update();

		m_fStartTime = fTime;
	}

	return DTRUE;
}
示例#6
0
void CSFXMgr::OnObjectRotate( HOBJECT hObj, bool bTeleport, LTRotation *pNewRot )
{
	if( !hObj || ! pNewRot )
		return;

	// If it's a CharacterFX we might want to modify the rotation...

	CSpecialFX *pFX = FindSpecialFX( SFX_CHARACTER_ID, hObj );
	if( pFX )
	{
		pFX->OnObjectRotate( pNewRot );
	}
}
示例#7
0
void CSFXMgr::OnTouchNotify(HOBJECT hMain, CollisionInfo *pInfo, float forceMag)
{
	if (!hMain) return;

	// See if this is the move-mgr's object...

	if (hMain == g_pPlayerMgr->GetMoveMgr()->GetObject())
	{
		g_pPlayerMgr->GetMoveMgr()->OnTouchNotify(pInfo, forceMag);
	}
	else
	{
		// Okay see if this is a special fx...

		CSpecialFX* pFX = FindSpecialFX(SFX_PROJECTILE_ID, hMain);

		if (pFX)
		{
			pFX->HandleTouch(pInfo);
		}
	}
}
示例#8
0
void CSFXMgr::UpdateDynamicSpecialFX()
{
	//track our performance
	CTimedSystemBlock TimingBlock(g_tsClientSFXUpdate);

	for (int j=0; j < DYN_ARRAY_SIZE; j++)
	{
		int nNumSFX  = m_dynSFXLists[j].GetSize();

		for (int i=0; i < nNumSFX; i++)
		{
			CSpecialFX* pSFX = m_dynSFXLists[j][i];
			if( pSFX )
			{
				if (!pSFX->Update())
				{
					m_dynSFXLists[j].Remove(pSFX);
				}
			}
		}
	}
}
CSpecialFX* CGibFX::CreateGibTrail(HLOCALOBJ hObj)
{
    if (!hObj || !m_pClientDE) return LTNULL;

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

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


	PTCREATESTRUCT pt;
	pt.hServerObj = hObj;
    pt.nType      = (uint8) (m_eModelType == eModelTypeHuman ? PT_BLOOD : PT_GIBSMOKE);

	CSpecialFX*	pSFX = debug_new(CParticleTrailFX);
    if (!pSFX) return LTNULL;

	pSFX->Init(&pt);
	pSFX->CreateObject(m_pClientDE);

	return pSFX;
}
示例#10
0
DBOOL CBloodTrailFX::Update()
{
	CBloodClientShell *pShell = (CBloodClientShell*)g_pClientDE->GetClientShell();
	CSFXMgr* psfxMgr = pShell->GetSFXMgr();
	if (!psfxMgr || !m_pClientDE || !m_hServerObject) return DFALSE;

	DFLOAT fTime = m_pClientDE->GetTime();

	// Check to see if we should go away...

	if (m_bWantRemove || (m_hServerObject == DNULL))
	{
		return DFALSE;
	}


	// See if it is time to create a new trail segment...

	if ((m_fStartTime < 0) || (fTime > m_fStartTime + m_fSegmentTime))
	{
		BTSCREATESTRUCT bts;

		bts.hServerObj = m_hObject;
		VEC_COPY(bts.vColor1, m_vColor);
		bts.fLifeTime		= m_fLifeTime;
		bts.fOffsetTime		= m_fOffsetTime;
		bts.fRadius			= 200.0f;
		bts.nNumPerPuff		= m_nNumPerPuff;

 		CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_BLOODTRAILSEG_ID, &bts, DFALSE, this);
		if (pFX) pFX->Update();
 
		m_fStartTime = fTime;
	}

	return DTRUE;
}
示例#11
0
void CWeaponFX::CreateLightBeamFX(SURFACE* pSurf)
{
	if (!pSurf) return;

    LTVector vEnterColor, vExitColor;
    if (g_pLTClient->GetPointShade(&m_vExitPos, &vExitColor) == LT_OK)
	{
		// Get the EnterColor value...

        LTVector vEnterPos = m_vExitPos - (m_vExitNormal * float(pSurf->nMaxShootThroughThickness + 1));

        if (g_pLTClient->GetPointShade(&vEnterPos, &vEnterColor) == LT_OK)
		{
			// Calculate the difference in light value...

            LTFLOAT fMaxEnter = Max(vEnterColor.x, vEnterColor.y);
			fMaxEnter = Max(fMaxEnter, vEnterColor.z);

            LTFLOAT fMaxExit = Max(vExitColor.x, vExitColor.y);
			fMaxExit = Max(fMaxExit, vExitColor.z);

			if (fabs((double)(fMaxExit - fMaxEnter)) >= g_cvarLightBeamColorDelta.GetFloat())
			{
                LTVector vStartPoint, vDir;
				if (fMaxEnter > fMaxExit)
				{
					vStartPoint = m_vExitPos;
					vDir = m_vDir;
				}
				else
				{
					vStartPoint = vEnterPos;
					vDir = -m_vDir;
				}

				PLFXCREATESTRUCT pls;

				pls.vStartPos			= vStartPoint;
				pls.vEndPos				= vStartPoint + (vDir * GetRandom(100.0, 150.0f));
                pls.vInnerColorStart    = LTVector(230, 230, 230);
				pls.vInnerColorEnd		= pls.vInnerColorStart;
                pls.vOuterColorStart    = LTVector(0, 0, 0);
                pls.vOuterColorEnd      = LTVector(0, 0, 0);
				pls.fAlphaStart			= 0.5f;
				pls.fAlphaEnd			= 0.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		= 1;

				CSpecialFX* pFX = g_pGameClientShell->GetSFXMgr()->CreateSFX(SFX_POLYLINE_ID, &pls);
				if (pFX) pFX->Update();
			}
		}
	}
}
示例#12
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 :)
}
示例#13
0
void CWeaponFX::CreateBloodSplatFX()
{
	CGameSettings* pSettings = g_pInterfaceMgr->GetSettings();
	if (!pSettings || !pSettings->Gore()) return;

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

	CSpecialFX* pFX = LTNULL;

	LTFLOAT fRange = g_vtBloodSplatsRange.GetFloat();

	// See if we should make some blood splats...

	ClientIntersectQuery iQuery;
	IntersectInfo iInfo;

	iQuery.m_From = m_vPos;

	LTVector vDir = m_vDir;

	// Create some blood splats...

	int nNumSplats = GetRandom((int)g_vtBloodSplatsMinNum.GetFloat(), (int)g_vtBloodSplatsMaxNum.GetFloat());

	LTVector vU, vR, vF;
    g_pLTClient->GetRotationVectors(&m_rDirRot, &vU, &vR, &vF);

	for (int i=0; i < nNumSplats; i++)
	{
		LTVector vDir = m_vDir;

		// Perturb direction after first splat...

		if (i > 0)
		{
			float fPerturb = g_vtBloodSplatsPerturb.GetFloat();

			float fRPerturb = (GetRandom(-fPerturb, fPerturb))/1000.0f;
			float fUPerturb = (GetRandom(-fPerturb, fPerturb))/1000.0f;

			vDir += (vR * fRPerturb);
			vDir += (vU * fUPerturb);
		}

		iQuery.m_To = vDir * fRange;
		iQuery.m_To += m_vPos;
		iQuery.m_Flags = IGNORE_NONSOLID | INTERSECT_HPOLY;

		if (g_pLTClient->IntersectSegment(&iQuery, &iInfo) && IsMainWorld(iInfo.m_hObject))
		{
			SurfaceType eType = GetSurfaceType(iInfo);
			if (eType == ST_SKY || eType == ST_INVISIBLE)
			{
				return; // Don't leave blood on the sky
			}


			LTBOOL bBigBlood = (LTBOOL)GetConsoleInt("BigBlood", 0);

			// Create a blood splat...

			BSCREATESTRUCT sc;

			g_pLTClient->AlignRotation(&(sc.rRot), &(iInfo.m_Plane.m_Normal), LTNULL);

			// Randomly rotate the blood splat

			g_pLTClient->RotateAroundAxis(&(sc.rRot), &(iInfo.m_Plane.m_Normal), GetRandom(0.0f, MATH_CIRCLE));

			LTVector vTemp = vDir * -2.0f;
			sc.vPos = iInfo.m_Point + vTemp;  // Off the wall a bit
			sc.vVel.Init(0.0f, 0.0f, 0.0f);

			sc.vInitialScale.Init(1.0f, 1.0f, 1.0f);
			sc.vInitialScale.x	= GetRandom(g_vtBloodSplatsMinScale.GetFloat(), g_vtBloodSplatsMaxScale.GetFloat());

			if (bBigBlood) sc.vInitialScale.x *= g_vtBigBloodSizeScale.GetFloat();

			sc.vInitialScale.y	= sc.vInitialScale.x;
			sc.vFinalScale		= sc.vInitialScale;

			sc.dwFlags			= FLAG_VISIBLE | FLAG_ROTATEABLESPRITE | FLAG_NOLIGHT;
			sc.fLifeTime		= GetRandom(g_vtBloodSplatsMinLifetime.GetFloat(), g_vtBloodSplatsMaxLifetime.GetFloat());

			if (bBigBlood) sc.fLifeTime *= g_vtBigBloodLifeScale.GetFloat();

			sc.fInitialAlpha	= 1.0f;
			sc.fFinalAlpha		= 0.0f;
			sc.nType			= OT_SPRITE;
			sc.bMultiply		= LTTRUE;

			char* pBloodFiles[] =
			{
				"Sfx\\Test\\Spr\\BloodL1.spr",
				"Sfx\\Test\\Spr\\BloodL2.spr",
				"Sfx\\Test\\Spr\\BloodL3.spr",
				"Sfx\\Test\\Spr\\BloodL4.spr"
			};

			sc.pFilename = pBloodFiles[GetRandom(0,3)];

			pFX = psfxMgr->CreateSFX(SFX_SCALE_ID, &sc);
			if (pFX) pFX->Update();
		}
		else if (i==0)
		{
			// Didn't hit anything straight back, do don't bother to
			// do anymore...

			return;
		}
	}
}
示例#14
0
CSpecialFX* CSFXMgr::CreateSFX(uint8 nId, SFXCREATESTRUCT *psfxCreateStruct,
							   ILTMessage_Read *pMsg, HOBJECT hServerObj)
{
    CSpecialFX* pSFX = NULL;

	switch (nId)
	{
		case SFX_WEAPON_ID :
		{
			pSFX = &s_WeaponFX;
		}
		break;

		case SFX_PLAYERLURE_ID :
		{
			pSFX = debug_new( PlayerLureFX );
		}
		break;

		case SFX_PLAYERSOUND_ID :
		{
			pSFX = g_SFXBank_PlayerSound.New();
		}
		break;

		case SFX_PROJECTILE_ID :
		{
			pSFX = g_SFXBank_Projectile.New();
		}
		break;

		case SFX_SEARCHLIGHT_ID :
		{
			pSFX = g_SFXBank_SearchLight.New();
		}
		break;

		case SFX_MARK_ID :
		{
			pSFX = g_SFXBank_Mark.New();
		}
		break;

		case SFX_SHELLCASING_ID :
		{
			pSFX = g_SFXBank_ShellCasing.New();
		}
		break;

		case SFX_CAMERA_ID :
		{
			pSFX = g_SFXBank_Camera.New();
			if (pSFX)
			{
				if (pSFX->Init(psfxCreateStruct))
				{
					if (g_pLTClient->IsConnected())
					{
						if (pSFX->CreateObject(g_pLTClient))
						{
							m_cameraSFXList.Add(pSFX);
						}
						else
						{
							DeleteSFX(pSFX);
                            pSFX = NULL;
						}
					}
					else
					{
						DeleteSFX(pSFX);
                        pSFX = NULL;
					}
				}
			}

			return pSFX;
		}
		break;

		case SFX_POLYGRID_ID :
		{
			pSFX = g_SFXBank_PolyGrid.New();
		}
		break;

		case SFX_RENDERTARGET_ID :
		{
			pSFX = g_SFXBank_RenderTarget.New();
		}
		break;

		case SFX_RENDERTARGETGROUP_ID :
		{
			pSFX = g_SFXBank_RenderTargetGroup.New();
		}
		break;

		case SFX_EXPLOSION_ID :
		{
			pSFX = g_SFXBank_Explosion.New();
		}
		break;

		case SFX_VOLUMEBRUSH_ID :
		{
			pSFX = g_SFXBank_VolumeBrush.New();
		}
		break;

		case SFX_PICKUPITEM_ID :
		{
			pSFX = g_SFXBank_PickupItem.New();
		}
		break;

		case SFX_AIMMAGNET_ID :
		{
			pSFX = g_SFXBank_AimMagnet.New();
		}
		break;

		case SFX_NAVMARKER_ID :
		{
			pSFX = g_SFXBank_NavMarker.New();
		}
		break;

		case SFX_LADDER_ID :
		{
			pSFX = g_SFXBank_Ladder.New();
		}
		break;

		case SFX_SPECIALMOVE_ID :
		{
			pSFX = g_SFXBank_SpecialMove.New();
		}
		break;

		case SFX_FINISHINGMOVE_ID :
		{
			pSFX = g_SFXBank_FinishingMove.New();
		}
		break;

		case SFX_CHARACTER_ID :
		{
			pSFX = g_SFXBank_Character.New();
		}
		break;

		case SFX_DEBUGLINE_ID:
		{
			pSFX = g_SFXBank_DebugLine.New();
		}
		break;

		case SFX_SNOW_ID:
		{
			pSFX = g_SFXBank_Snow.New();
		}
		break;
 
		case SFX_JUMPVOLUME_ID:
		{
			pSFX = g_SFXBank_JumpVolume.New();
		}
		break;

		case SFX_DYNAMIC_SECTOR_ID:
		{
			pSFX = g_SFXBank_DynamicSectorVolume.New();
		}
		break;

		case SFX_SCATTER_ID:
		{
			pSFX = g_SFXBank_Scatter.New();
		}
		break;

		case SFX_TRIGGER_ID:
		{
			pSFX = g_SFXBank_Trigger.New();
		}
		break;

		case SFX_FORENSICOBJECT_ID :
		{
			pSFX = g_SFXBank_ForensicObject.New();
		}
		break;

		case SFX_TURRET_ID:
		{
			pSFX = g_SFXBank_Turret.New( );
		}
		break;

		case SFX_TEAMCLIENTFX_ID:
		{
			pSFX = g_SFXBank_TeamClientFx.New( );
		}
		break;

		case SFX_CTFFLAGBASE_ID:
		{
			LT_MEM_TRACK_ALLOC(pSFX = new CTFFlagBaseSFX, LT_MEM_TYPE_GAMECODE);
		}
		break;

		case SFX_CTFFLAG_ID:
		{
			LT_MEM_TRACK_ALLOC(pSFX = new CTFFlagSFX, LT_MEM_TYPE_GAMECODE);
		}
		break;

		case SFX_CONTROLPOINT_ID:
		{
			LT_MEM_TRACK_ALLOC(pSFX = new ControlPointSFX, LT_MEM_TYPE_GAMECODE);
		}
		break;

		case SFX_SOUND_NONPOINT_ID :
		{
			pSFX = g_SFXBank_SoundNonPoint.New();
		}
		break;

		case SFX_VOLUMETRICLIGHT_ID :
		{
			pSFX = g_SFXBank_VolumetricLight.New();
		}
		break;

		case SFX_ENTRYTOOLLOCK_ID :
		{
			pSFX = g_SFXBank_EntryToolLock.New();
		}
		break;

		case SFX_SCREENEFFECT_ID :
		{
			pSFX = g_SFXBank_ScreenEffect.New();
		}
		break;

		case SFX_ACTIVATEOBJECT_ID:
		{
			pSFX = g_SFXBank_ActivateObject.New();
		}
		break;

		case SFX_PHYSICS_CONSTRAINT_ID:
		{
			pSFX = g_SFXBank_PhysicsConstraintFX.New( );
		}
		break;

		case SFX_PHYSICS_COLLISION_SYSTEM_ID:
		{
			pSFX = g_SFXBank_PhysicsCollisionSystemFX.New( );
		}
		break;

		default :
            return NULL;
		break;
	}


	// Initialize the sfx, and add it to the appropriate array...

    if (!pSFX) return NULL;


	// First initialize with the create struct...

	if (psfxCreateStruct)
	{
		if (!pSFX->Init(psfxCreateStruct))
		{
			DeleteSFX(pSFX);
            return NULL;
		}
	}
	else if (pMsg)  // Initialize using the hMessage
	{
		if (!pSFX->Init(hServerObj, pMsg))
		{
			DeleteSFX(pSFX);
            return NULL;
		}
	}
	else
	{
		DeleteSFX(pSFX);
        return NULL;
	}

	if (!pSFX->CreateObject(g_pLTClient))
	{
		DeleteSFX(pSFX);
        return NULL;
	}

	if( !AddDynamicSpecialFX(pSFX, nId))
	{
		DeleteSFX( pSFX );
		return NULL;
	}

	return pSFX;
}
示例#15
0
void CSFXMgr::OnSFXMessage(ILTMessage_Read *pMsg)
{
	if (!pMsg) return;

	uint32 nInitialMsgPos = pMsg->Tell( );

    uint8 nFXType   = pMsg->Readuint8();
	HOBJECT hObj	= pMsg->ReadObject();

	switch( nFXType )
	{
		// Special case for the camera
		case SFX_CAMERA_ID:
		{
			// Find the camera sfx...

			int nNumSFX = m_cameraSFXList.GetSize();

			for( int i = 0; i < nNumSFX; ++i )
			{
				if( m_cameraSFXList[i] && m_cameraSFXList[i]->GetServerObj() == hObj )
				{
					m_cameraSFXList[i]->OnServerMessage( pMsg );
				}
			}

			return;
		}
		break;

		// Special case for the texture FX
		case SFX_DISPLAYTIMER_ID:
		{
			g_pInterfaceMgr->HandleDisplayTimerMsg( *pMsg );
			return;
		}
		break;

	}


	if (0 <= nFXType && nFXType < DYN_ARRAY_SIZE && hObj)
	{
		CSpecialFX* pFX = FindSpecialFX(nFXType, hObj);

		if (pFX)
		{
			pFX->OnServerMessage(pMsg);
		}
		// If the object is waiting to be created, then append the message.
		else
{
			// Need to save the message from the beginning.
			uint32 nCurPos = pMsg->Tell( );
			pMsg->SeekTo( nInitialMsgPos );

			SpecialFXNotifyMessageHandler::Instance().AppendMessage( *pMsg, hObj );

			pMsg->SeekTo( nCurPos );
		}
	}
}
void CGibFX::HandleBounce(int nIndex)
{
	if (nIndex < 0 || nIndex >= m_nNumGibs) return;

	// Play a bounce sound if the gib isn't in liquid...

	if (!(m_Emitters[nIndex].m_dwPhysicsFlags & MO_LIQUID) && (m_hGib[nIndex]))
	{
		if (m_bPlayBounceSound && GetRandom(1, 4) != 1)
		{
			char* pSound = GetBounceSound();

			// Play appropriate sound...

			if (pSound)
			{
				g_pClientSoundMgr->PlaySoundFromPos(m_Emitters[nIndex].m_vPos,
					pSound, 1000.0f, SOUNDPRIORITY_MISC_LOW);
			}
		}
	}


	// See if we're resting...

	m_BounceCount[nIndex]--;
	if (m_BounceCount[nIndex] <= 0)
	{
		m_Emitters[nIndex].m_dwPhysicsFlags |= MO_RESTING;
		if (m_bSubGibs) HandleDoneBouncing(nIndex);
	}


	// Add a blood splat...

	if (m_bBloodSplats)
	{
		// Don't add blood splats on the sky...

        uint32 dwTextureFlags;
		m_pClientDE->GetPolyTextureFlags(m_info.m_hPoly, &dwTextureFlags);
		SurfaceType eType = (SurfaceType)dwTextureFlags;
		if (eType == ST_SKY) return;


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

		BSCREATESTRUCT sc;

        m_pClientDE->AlignRotation(&(sc.rRot), &(m_info.m_Plane.m_Normal), LTNULL    );

        LTVector vTemp;
		VEC_MULSCALAR(vTemp, m_info.m_Plane.m_Normal, 2.0f);
		VEC_ADD(sc.vPos, m_info.m_Point, vTemp);  // Off the wall/floor a bit
		VEC_SET(sc.vVel, 0.0f, 0.0f, 0.0f);
		VEC_SET(sc.vInitialScale, GetRandom(0.3f, 0.5f), GetRandom(0.3f, 0.5f), 1.0f);
		VEC_SET(sc.vFinalScale, GetRandom(0.8f, 1.0f), GetRandom(0.8f, 1.0f), 1.0f);

		sc.dwFlags			= FLAG_VISIBLE | FLAG_ROTATEABLESPRITE | FLAG_NOLIGHT;
		sc.fLifeTime		= m_fLifeTime + 10.0f;
		sc.fInitialAlpha	= 1.0f;
		sc.fFinalAlpha		= 0.0f;
		sc.nType			= OT_SPRITE;

		char* pBloodFiles[] =
		{
			"Sprites\\BloodSplat1.spr",
			"Sprites\\BloodSplat2.spr",
			"Sprites\\BloodSplat3.spr",
			"Sprites\\BloodSplat4.spr"
		};

		sc.pFilename = pBloodFiles[GetRandom(0,3)];


		CSpecialFX* pFX = psfxMgr->CreateSFX(SFX_SCALE_ID, &sc);
		if (pFX) pFX->Update();
	}
}