void CClientMeleeCollisionController::HandleBlocked(HOBJECT hTarget, const LTVector& vPos, const LTVector& vDir)
{
	// Get the proper weapon record...
	CClientWeapon* pClientWeapon = g_pClientWeaponMgr->GetCurrentClientWeapon();
	HWEAPON hWeapon = pClientWeapon ? pClientWeapon->GetWeaponRecord() : NULL;	//!!ARL: Use Attacker's weapon instead?  (will need to be sent from server - probably along with block info)
	HWEAPONDATA hWeaponData = g_pWeaponDB->GetWeaponData(hWeapon, !USE_AI_DATA);

	// Spawn a block effect for it...
	const char* pszBlockFX = g_pWeaponDB->GetString(hWeaponData, "BlockFX");
	CLIENTFX_CREATESTRUCT fxcs(pszBlockFX, 0, LTRigidTransform(vPos, LTRotation(vDir, LTVector(0,1,0))));
	g_pGameClientShell->GetSimulationTimeClientFXMgr().CreateClientFX(NULL, fxcs, true);

	// Let the server objects know they've blocked / been blocked.
	CAutoMessage cMsg;
	cMsg.Writeuint8(MID_OBJECT_MESSAGE);
	cMsg.WriteObject(m_hObject);
	cMsg.Writeuint32(MID_MELEEBLOCK);
	cMsg.WriteObject(hTarget);
	g_pLTClient->SendToServer(cMsg.Read(), MESSAGE_GUARANTEED);

	// Disable attacker's collision (i.e. stop attacking).
	DisableCollisions();

	// For local player attackers, send a BlockRecoil stimulus so a proper animation can be played.
	if (m_hObject == g_pPlayerMgr->GetMoveMgr()->GetObject())
	{
		CPlayerBodyMgr::Instance().HandleAnimationStimulus("CS_RecoilFromBlock");
	}
}
void CDestructibleModel::DoExplosion(char* pTargetName)
{
	CWeapons weapons;
	weapons.Init(m_hObject);
	weapons.ObtainWeapon(m_nExplosionWeaponId);
	weapons.ChangeWeapon(m_nExplosionWeaponId);

	CWeapon* pWeapon = weapons.GetCurWeapon();
	if (!pWeapon) return;

	weapons.SetAmmo(pWeapon->GetAmmoId());

	pWeapon->SetDamageFactor(m_fDamageFactor);

	LTRotation rRot;
	g_pLTServer->GetObjectRotation(m_hObject, &rRot);

	LTVector vF, vPos;
	g_pLTServer->GetObjectPos(m_hObject, &vPos);
	vF = rRot.Forward();

	// Just blow up in place if we're not supposed to fire along
	// forward vector and we don't have a target...

	if (!m_bFireAlongForward)
	{
		pWeapon->SetLifetime(0.0f);
		VEC_SET(vF, 0.0f, -1.0f, 0.0f);  // Fire down
	}

	// See if we have a target...If so, point at it.

	if (pTargetName)
	{
		ObjArray <HOBJECT, MAX_OBJECT_ARRAY_SIZE> objArray;
		g_pLTServer->FindNamedObjects(pTargetName, objArray);

		if (objArray.NumObjects())
		{
			LTVector vObjPos;
			g_pLTServer->GetObjectPos(objArray.GetObject(0), &vObjPos);
			vF = vObjPos - vPos;
			vF.Normalize();

			rRot = LTRotation(vF, LTVector(0.0f, 1.0f, 0.0f));
			g_pLTServer->SetObjectRotation(m_hObject, &rRot);
		}
	}

	WeaponFireInfo weaponFireInfo;
	weaponFireInfo.hFiredFrom	= m_hObject;
	weaponFireInfo.vPath		= vF;
	weaponFireInfo.vFirePos	= vPos;
	weaponFireInfo.vFlashPos	= vPos;

	pWeapon->Fire(weaponFireInfo);
}
Exemple #3
0
bool WorldModel::AttachServerMark( CServerMark& mark, CLIENTWEAPONFX & theStruct)
{
	LTransform globalTransform, parentTransform, localTransform;
    ILTTransform *pTransformLT;
    LTVector vParentPos, vOffset;
    LTRotation rParentRot, rRot;
    LTRotation rOffset;

	pTransformLT = g_pLTServer->GetTransformLT();

	// Attach the mark to the parent object...

	// Figure out what the rotation we want is.
    rOffset.Init();
	rRot = LTRotation(theStruct.vSurfaceNormal, LTVector(0.0f, 1.0f, 0.0f));


	// MD
	// Ok, now we have the transform in global space but attachments are specified in
	// local space (so they can move as the object moves and rotates).

	// Set the global LTransform.
	pTransformLT->Set(globalTransform, theStruct.vPos, rRot);

	// Get the object's transform.
	g_pLTServer->GetObjectPos( m_hObject, &vParentPos);
	g_pLTServer->GetObjectRotation( m_hObject, &rParentRot);
	parentTransform.m_Pos = vParentPos;
	parentTransform.m_Rot = rParentRot;
	
	parentTransform.m_Scale.Init(1,1,1);
	globalTransform.m_Scale.Init(1,1,1);

	// Get the offset.
	pTransformLT->Difference(localTransform, globalTransform, parentTransform);
	vOffset = localTransform.m_Pos;
	rOffset = localTransform.m_Rot;


	HATTACHMENT hAttachment = NULL;
    LTRESULT dRes = g_pLTServer->CreateAttachment( m_hObject, mark.m_hObject, LTNULL,
											     &vOffset, &rOffset, &hAttachment);
    if (dRes != LT_OK)
	{
		return false;
	}

	// Add to the attachment list.
	LTObjRefNotifier ref( *this );
	ref = mark.m_hObject;
	m_AttachmentList.push_back( ref );

	return true;
}
Exemple #4
0
//this will take a list of properties and convert it to internal values
bool CBaseFXProps::LoadProperty(ILTInStream* pStream, const char* pszName, const char* pszStringTable, const uint8* pCurveData)
{
	if( LTStrIEquals( pszName, FXPROP_UPDATEPOS ))
	{
		m_eFollowType = (EFXFollowType)CFxProp_Enum::Load(pStream);
	}
	else if( LTStrIEquals( pszName, FXPROP_ATTACHNAME ))
	{
		m_pszAttach = CFxProp_String::Load(pStream, pszStringTable);
	}
	else if( LTStrIEquals( pszName, FXPROP_OFFSET ))
	{
		m_vfcOffset.Load(pStream, pCurveData);
	}
	else if( LTStrIEquals( pszName, FXPROP_MENULAYER ))
	{
		m_nMenuLayer = CFxProp_Int::Load(pStream);
	}
	else if( LTStrIEquals( pszName, FXPROP_ROTATION ))
	{
		m_vfcRotation.Load(pStream, pCurveData);
	}
	else if (LTStrIEquals(pszName, FXPROP_INITIALROTATION))
	{
		LTVector vInitialAngles = CFxProp_Vector::Load(pStream);
		m_rInitialRotation = LTRotation(VEC_EXPAND(vInitialAngles * MATH_PI / 180.0f));
	}
	else if( LTStrIEquals( pszName, FXPROP_SMOOTHSHUTDOWN ))
	{
		m_bSmoothShutdown = CFxProp_EnumBool::Load(pStream);
	}
	else if( LTStrIEquals( pszName, FXPROP_DETAILLEVEL ))
	{
		m_nDetailLevel = CFxProp_Enum::Load(pStream);
		LTASSERT((m_nDetailLevel < FX_NUM_DETAIL_SETTINGS), "Found an invalid detail setting");
	}
	else if( LTStrIEquals( pszName, FXPROP_ISGORE ))
	{
		m_eGoreSetting = (EFXGoreSetting)CFxProp_Enum::Load(pStream);
	}
	else if( LTStrIEquals( pszName, FXPROP_SLOWMOTION ))
	{
		m_eSlowMotion = (EFXSlowMotionSetting)CFxProp_Enum::Load(pStream);
	}
	else
	{
		return false;
	}

	return true;
}
Exemple #5
0
/* Construct quaternion from Euler angles (in radians). */
LTRotation Eul_ToQuat(EulerAngles ea)
{
    float a[3], ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
    float roll;
    int i,j,k,h,n,s,f;
    EulGetOrd((int)ea.w,i,j,k,h,n,s,f);
    if (f==EulFrmR) {
        float t = ea.x;
        ea.x = ea.z;
        ea.z = t;
    }
    if (n==EulParOdd) ea.y = -ea.y;
    ti = ea.x*0.5f;
    tj = ea.y*0.5f;
    th = ea.z*0.5f;
    ci = (float)cos(ti);
    cj = (float)cos(tj);
    ch = (float)cos(th);
    si = (float)sin(ti);
    sj = (float)sin(tj);
    sh = (float)sin(th);
    cc = ci*ch;
    cs = ci*sh;
    sc = si*ch;
    ss = si*sh;
    if (s==EulRepYes)
    {
        a[i] = cj*(cs + sc);	/* Could speed up with */
        a[j] = sj*(cc + ss);	/* trig identities. */
        a[k] = sj*(cs - sc);
        roll = cj*(cc - ss);
    }
    else
    {
        a[i] = cj*sc - sj*cs;
        a[j] = cj*ss + sj*cc;
        a[k] = cj*cs - sj*sc;
        roll = cj*cc + sj*ss;
    }
    if(n==EulParOdd)
        a[j] = -a[j];

    return LTRotation(a[EulX], a[EulY], a[EulZ], roll);
}
Exemple #6
0
void CLeanMgr::CalculateNewPosRot( LTVector &vOutPos, LTRotation &rOutRot, float fAngle )
{
	float fPitch	= g_pPlayerMgr->GetPitch();
	float fYaw		= g_pPlayerMgr->GetYaw();
	float fRoll		= g_pPlayerMgr->GetRoll();

	// Use the current camera angles and just add the new roll for the camera rotation...

	rOutRot = LTRotation( fPitch, fYaw, fRoll + fAngle );

	// Don't factor in the pitch so the position isn't affected by it...

	LTMatrix	mRotation;
	LTRotation	rRotation( 0.0f, fYaw, fRoll + fAngle );
	
	rRotation.ConvertToMatrix( mRotation );

	vOutPos = (mRotation * m_vRotationPtOffset) + m_vRotationPt;

	// Make sure we are actually in the world before we try to clip...

	ClientIntersectQuery iQuery;
	ClientIntersectInfo  iInfo;

	iQuery.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID | INTERSECT_HPOLY;
	iQuery.m_From = m_vRotationPt + m_vRotationPtOffset;
	iQuery.m_To = vOutPos;

	if( g_pLTClient->IntersectSegment( &iQuery, &iInfo ))
	{
		vOutPos = iInfo.m_Point + iInfo.m_Plane.m_Normal;
	}

	// Keep us far away from walls to avoid clipping...
	
	float fCamClipDist = g_vtCameraClipDistance.GetFloat();
	g_vtCameraClipDistance.SetFloat( g_vtLeanCamClipDist.GetFloat() );

	g_pPlayerMgr->GetPlayerCamera()->CalcNonClipPos( vOutPos, rOutRot );

	g_vtCameraClipDistance.SetFloat( fCamClipDist );
}
Exemple #7
0
LTRotation CLTMessage_Read::PeekYRotation(const CPacket_Read &cPacket)
{
	int8 nAngle = cPacket.Peekint8();
	return LTRotation(0.0f, (float)(nAngle) * (MATH_PI / 127.0f), 0.0f);
}
Exemple #8
0
LTRotation CLTMessage_Read::ReadYRotation(CPacket_Read &cPacket)
{
	int8 nAngle = cPacket.Readint8();
	return LTRotation(0.0f, (float)(nAngle) * (MATH_PI / 127.0f), 0.0f);
}
Exemple #9
0
void CLightningFX::EmitBolts( float tmFrameTime )
{
	// Make sure enough time between emissions has passed...
	m_tmElapsedEmission += tmFrameTime;

	if( m_fDelay < m_tmElapsedEmission )
	{
		LTransform		lTrans;
		LTVector		vAttractorPos;
		ILTModel		*pModelLT = m_pLTClient->GetModelLT();

		uint32	nActiveBolts = GetRandom( (int)GetProps()->m_nMinNumBolts, (int)GetProps()->m_nMaxNumBolts );
		uint32	nBolt;

		bool	bCanUseAttractors = (m_lstAttractors.size() > 0);
		bool	bCanUseRadius = (GetProps()->m_fOmniDirectionalRadius >= 1.0f);

		CLightningBolt *pBolt = LTNULL;
		LightningBolts::iterator iter;

		for( nBolt = 0, iter = m_lstBolts.begin(); iter != m_lstBolts.end(), nBolt < nActiveBolts; ++iter, ++nBolt )
		{
			pBolt = *iter;
			
			pBolt->m_fWidth = GetRandom( GetProps()->m_fMinBoltWidth, GetProps()->m_fMaxBoltWidth );
			pBolt->m_fLifetime = GetRandom( GetProps()->m_fMinLifetime, GetProps()->m_fMaxLifetime );
			pBolt->m_tmElapsed = 0.0f;
			pBolt->m_bActive = true;
			
			// Grab the position of the object to compensate for offset
		
			if( m_hTarget )
			{
				m_pLTClient->GetObjectPos( m_hTarget, &vAttractorPos );
			}
			else
			{
				vAttractorPos = m_vTargetPos;
			}

			// Decide if we should use an attractor or radius for the end pos...
			
			if( bCanUseAttractors && (!bCanUseRadius || GetRandom(0,1)) )
			{
				uint8	nIndex = GetRandom( 0, (int)(m_lstAttractors.size()) - 1 );
				CAttractor cAttractor = m_lstAttractors[nIndex];

				if( cAttractor.GetTransform( lTrans, true ) == LT_OK )
				{
					vAttractorPos = lTrans.m_Pos;
				}
			}	
			else if( bCanUseRadius )
			{
				LTVector vRandomPos;
				vRandomPos.x = GetRandom( -1.0f, 1.0f );
				vRandomPos.y = GetRandom( -1.0f, 1.0f );
				vRandomPos.z = GetRandom( -1.0f, 1.0f );
				
				vRandomPos.Normalize();
				vRandomPos *= GetRandom( -GetProps()->m_fOmniDirectionalRadius, GetProps()->m_fOmniDirectionalRadius );

				vAttractorPos = m_vPos + vRandomPos;

				IntersectQuery	iQuery;
				IntersectInfo	iInfo;

				iQuery.m_From	= m_vPos;
				iQuery.m_To		= vAttractorPos;

				if( m_pLTClient->IntersectSegment( &iQuery, &iInfo ))
				{
					vAttractorPos = iInfo.m_Point;
				}
			}

			
			LTVector vNew = m_vPos;
			LTVector vDir = vAttractorPos - vNew;
						
			float fStep = vDir.Length() / (float)pBolt->m_nNumSegments;
			float fPerturb = GetRandom( GetProps()->m_fMinPerturb, GetProps()->m_fMaxPerturb );
			
			vDir.Normalize();
			LTRotation rRot = LTRotation( vDir, LTVector( 0.0f, 1.0f, 0.0f ));
				
			CLinkListNode<PT_TRAIL_SECTION> *pNode = pBolt->m_collPathPts.GetHead();
			while( pNode )
			{
				pNode->m_Data.m_vPos = vNew;
				pNode->m_Data.m_tmElapsed = 0.0f;
				pNode->m_Data.m_vBisector.Init();
												
				// Add in some perturb going in the direction of the attractor pos for the next section...
				
				vNew +=	(rRot.Forward() * fStep );
				vNew += (rRot.Up() * GetRandom( -fPerturb, fPerturb ));
				vNew += (rRot.Right() * GetRandom( -fPerturb, fPerturb ));

				// Make sure the last section goes to the end pos...

				if( !pNode->m_pNext )
					pNode->m_Data.m_vPos = vAttractorPos;

				pNode = pNode->m_pNext;
			}
		}

		// Decide when the next emission will be...

		m_tmElapsedEmission = 0.0f;
		m_fDelay = GetRandom( GetProps()->m_fMinDelay, GetProps()->m_fMaxDelay );
	}
}
Exemple #10
0
bool CLTBModelFX::Init(ILTClient *pClientDE, FX_BASEDATA *pBaseData, const CBaseFXProps *pProps)
{
	// Perform base class initialisation

	if (!CBaseFX::Init(pClientDE, pBaseData, pProps)) 
		return false;

	// Use the "target" Normal instead, if one was specified...

	LTVector vNorm = GetProps()->m_vNorm;

	if( pBaseData->m_vTargetNorm.LengthSquared() > MATH_EPSILON )
	{
		vNorm = pBaseData->m_vTargetNorm;
		vNorm.Normalize();
	}

	// Develop the Right and Up vectors based off the Forward...

	LTVector vR, vU;
	if( (1.0f == vNorm.y) || (-1.0f == vNorm.y) )
	{
		vR = LTVector( 1.0f, 0.0f, 0.0f ).Cross( vNorm );
	}
	else
	{
		vR = LTVector( 0.0f, 1.0f, 0.0f ).Cross( vNorm );
	}

	vU = vNorm.Cross( vR );
	m_rNormalRot = LTRotation( vNorm, vU );


	ObjectCreateStruct ocs;

	// Combine the direction we would like to face with our parents rotation...

	if( m_hParent )
	{
		m_pLTClient->GetObjectRotation( m_hParent, &ocs.m_Rotation );
	}
	else
	{
		ocs.m_Rotation = m_rCreateRot;
	}

	ocs.m_Rotation = ocs.m_Rotation * m_rNormalRot;	

	ocs.m_ObjectType		= OT_MODEL;
	ocs.m_Flags				|= pBaseData->m_dwObjectFlags |	(GetProps()->m_bShadow ? FLAG_SHADOW : 0 );
	ocs.m_Flags2			|= pBaseData->m_dwObjectFlags2;
	
	// Calculate the position with the offset in 'local' coordinate space...

	LTMatrix mMat;
	ocs.m_Rotation.ConvertToMatrix( mMat );

	m_vPos = ocs.m_Pos = m_vCreatePos + (mMat * GetProps()->m_vOffset);

	
	SAFE_STRCPY( ocs.m_Filename, GetProps()->m_szModelName );
	
	SAFE_STRCPY( ocs.m_SkinNames[0], GetProps()->m_szSkinName[0] );
	SAFE_STRCPY( ocs.m_SkinNames[1], GetProps()->m_szSkinName[1] );
	SAFE_STRCPY( ocs.m_SkinNames[2], GetProps()->m_szSkinName[2] );
	SAFE_STRCPY( ocs.m_SkinNames[3], GetProps()->m_szSkinName[3] );
	SAFE_STRCPY( ocs.m_SkinNames[4], GetProps()->m_szSkinName[4] );
	
	SAFE_STRCPY( ocs.m_RenderStyleNames[0], GetProps()->m_szRenderStyle[0] );
	SAFE_STRCPY( ocs.m_RenderStyleNames[1], GetProps()->m_szRenderStyle[1] );
	SAFE_STRCPY( ocs.m_RenderStyleNames[2], GetProps()->m_szRenderStyle[2] );
	SAFE_STRCPY( ocs.m_RenderStyleNames[3], GetProps()->m_szRenderStyle[3] );

	m_hObject = m_pLTClient->CreateObject(&ocs);
	if( !m_hObject ) 
		return LTFALSE;

	ILTModel		*pLTModel = m_pLTClient->GetModelLT();
	ANIMTRACKERID	nTracker;
	
	pLTModel->GetMainTracker( m_hObject, nTracker );

	//setup the animation if the user specified one
	if( strlen(GetProps()->m_szAnimName) > 0)
	{
		//ok, we need to set this
		HMODELANIM hAnim = m_pLTClient->GetAnimIndex(m_hObject, GetProps()->m_szAnimName);

		if(hAnim != INVALID_MODEL_ANIM)
		{
			//ok, lets set this animation
			pLTModel->SetCurAnim(m_hObject, nTracker, hAnim);
			pLTModel->ResetAnim(m_hObject, nTracker);
		}
	}
	//disable looping on this animation (so we can actually stop!)
	pLTModel->SetLooping(m_hObject, nTracker, false);

	// Setup the initial data needed to override the models animation length...
	if( GetProps()->m_bOverrideAniLength )
	{
		uint32 nAnimLength;

		pLTModel->GetCurAnimLength( m_hObject, nTracker, nAnimLength );
		pLTModel->SetCurAnimTime( m_hObject, nTracker, 0 );

		float fAniLength = (GetProps()->m_fAniLength < MATH_EPSILON) ? GetProps()->m_tmLifespan : GetProps()->m_fAniLength;
		
		if( fAniLength >= MATH_EPSILON || fAniLength <= -MATH_EPSILON )
			m_fAniRate = (nAnimLength * 0.001f) / fAniLength;

		pLTModel->SetAnimRate( m_hObject, nTracker, m_fAniRate );
	}

	// Success !!

	return LTTRUE;
}
Exemple #11
0
void CWeatherFX::CreateSplashSprites()
{
	if (m_eSurfaceType == ST_UNKNOWN) return;

	// Setup the splash sprite...

	BSCREATESTRUCT sc;

	CString str;
    LTFLOAT fLifetime = 0.0;
    uint32 dwFlags   = FLAG_NOLIGHT;
    char szFilename[128] = "";

	if (m_eSurfaceType == ST_LIQUID)
	{
		sc.rRot = LTRotation(LTVector(0.0f, 1.0f, 0.0f), LTVector(1.0f, 0.0f, 0.0f));

		fLifetime = 1.0f;
		dwFlags |= FLAG_ROTATEABLESPRITE;

		g_pClientButeMgr->GetWeatherAttributeString(WEATHER_BUTE_RAINRING,szFilename,sizeof(szFilename));
		if (!szFilename[0]) return;

	}
	else  // Not a liquid
	{
		fLifetime = 0.05f;
		dwFlags |= FLAG_SPRITEBIAS;

		g_pClientButeMgr->GetWeatherAttributeString(WEATHER_BUTE_RAINSPLASH,szFilename,sizeof(szFilename));
		if (!szFilename[0]) return;

	}

	sc.vPos = m_vPos;

	sc.dwFlags			= dwFlags;
	sc.fLifeTime		= fLifetime;
	sc.fInitialAlpha	= 1.0f;
	sc.fFinalAlpha		= 0.0f;
	sc.pFilename		= szFilename;
	sc.nType			= OT_SPRITE;

    LTFLOAT fStartScale, fEndScale;

	for (int i=0; i < NUM_SPLASH_SPRITES; i++)
	{
		if (m_eSurfaceType == ST_LIQUID)
		{
			fStartScale = GetRandom(0.05f, 0.1f);
			fEndScale   = GetRandom(0.2f, 0.3f);
		}
		else
		{
			fStartScale = GetRandom(0.1f, 0.30f);
			fEndScale   = GetRandom(0.2f, 0.35f);
		}

		sc.vInitialScale.Init(fStartScale, fStartScale, 1.0f);
		sc.vFinalScale.Init(fEndScale, fEndScale, 1.0f);

		if (!m_Splash[i].Init(&sc) || !m_Splash[i].CreateObject(m_pClientDE))
		{
			break;
		}
	}
}
Exemple #12
0
//performs a ray intersection. This will return false if nothing is hit, or true if something
//is. If something is hit, it will fill out the intersection property and the alignment
//vector according to the properties that the user has setup. If an object is hit, it will
//fill out the hit object, and specify the output transform relative to the hit object's space
bool CCreateRayFX::DetermineIntersection(	const LTVector& vObjPos, const LTVector& vObjForward, 
											HOBJECT& hOutObj, LTRigidTransform& tOutTrans)
{
	//default our output parameters to reasonable values
	hOutObj = NULL;
	tOutTrans.Init();

	//perform a ray intersection from our position along our Y axis and see if we hit anything.
	//If we do, create the effect there facing along the specified vector, randomly twisted

	//find the starting and ending points
	LTVector vStart = vObjPos + vObjForward * GetProps()->m_fMinDist;
	LTVector vEnd   = vObjPos + vObjForward * GetProps()->m_fMaxDist;

	//we now need to perform an intersection using these endpoints and see if we hit anything
	IntersectQuery	iQuery;
	IntersectInfo	iInfo;

	iQuery.m_Flags		= INTERSECT_HPOLY | IGNORE_NONSOLID;
	iQuery.m_FilterFn	= NULL;
	iQuery.m_pUserData	= NULL;
	iQuery.m_From		= vStart;
	iQuery.m_To			= vEnd;

	if( !g_pLTClient->IntersectSegment( iQuery, &iInfo ) )
	{
		//we didn't intersect anything, don't create an effect
		return false;
	}

	//determine if we hit the sky
	if(IsSkyPoly(iInfo.m_hPoly))
	{
		//never create an effect on the sky
		return false;
	}

	//we now need to determine the normal of intersection
	LTVector vHitNormal = iInfo.m_Plane.Normal();

	//we hit something, so we can now at least determine the point of intersection
	tOutTrans.m_vPos = iInfo.m_Point + vHitNormal * GetProps()->m_fOffset;

	//the primary vector we wish to align to
	LTVector vAlignment;

	//determine what our dominant axis should be
	switch (GetProps()->m_eAlignment)
	{
	default:
	case CCreateRayProps::eAlign_ToSource:
		vAlignment = -vObjForward;
		break;
	case CCreateRayProps::eAlign_Normal:
		vAlignment = vHitNormal;
		break;
	case CCreateRayProps::eAlign_Outgoing:
		vAlignment = vObjForward - (2.0f * vObjForward.Dot(vHitNormal)) * vHitNormal;
		vAlignment.Normalize();
		break;
	case CCreateRayProps::eAlign_ToViewer:
		{
			LTVector vCameraPos;
			g_pLTClient->GetObjectPos(m_pFxMgr->GetCamera(), &vCameraPos);
			vAlignment = vCameraPos - tOutTrans.m_vPos;
			vAlignment.Normalize();
		}
		break;
	}

	//and generate a randomly twisted orientation around our dominant axis
	tOutTrans.m_rRot = LTRotation(vAlignment, LTVector(0.0f, 1.0f, 0.0f));
	tOutTrans.m_rRot.Rotate(vAlignment, GetRandom(0.0f, MATH_CIRCLE));

	//now if we hit an object, make sure to store that object, and convert the transform into
	//the object's space
	if(iInfo.m_hObject && (g_pLTClient->Physics()->IsWorldObject(iInfo.m_hObject) == LT_NO))
	{
		//store this as our hit object
		hOutObj = iInfo.m_hObject;

		//and convert the transform into that object's space
		LTRigidTransform tObjTrans;
		g_pLTClient->GetObjectTransform(hOutObj, &tObjTrans);
		tOutTrans = tOutTrans.GetInverse() * tOutTrans;
	}

	//success
	return true;
}
Exemple #13
0
bool DoomsDayDevice::AddDoomsDayPiece( DoomsDayPiece *pDDPiece, CPlayerObj *pPlayer )
{
	if( !pDDPiece || !pPlayer )
		return false;
	
	// Don't allow dead players to add pieces to a device...

	if( pPlayer->IsDead() )
		return false;

	// Check the list of pieces to see if this one has already been added...

	DoomsDayPieceList::iterator iter = m_lstPiecesOnDevice.begin();
	while( iter != m_lstPiecesOnDevice.end() )
	{
		if( (*iter)->GetDoomsDayPieceType() == pDDPiece->GetDoomsDayPieceType() )
			return false;

		++iter;
	}

	// Reset the filenames to the 'replaced' PropType...
	
	char szPropType[256] = {0};
	sprintf( szPropType, "%s_replace", pDDPiece->GetPropTypeName() );

	PROPTYPE *pPropType = g_pPropTypeMgr->GetPropType( szPropType );
	if( !pPropType )
		return false;
	
	
	ObjectCreateStruct ocs;

	LTStrCpy( ocs.m_Filename, pPropType->sFilename.c_str(), ARRAY_LEN( ocs.m_Filename ));

	pPropType->blrPropRenderStyleReader.CopyList( 0, ocs.m_RenderStyleNames[0], MAX_CS_FILENAME_LEN + 1 );
	pPropType->blrPropSkinReader.CopyList( 0, ocs.m_SkinNames[0], MAX_CS_FILENAME_LEN + 1 );

	if( g_pCommonLT->SetObjectFilenames( pDDPiece->m_hObject, &ocs ) != LT_OK )
		return false;
	

	// Attach the piece to the base...

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

	LTRotation rRot;
	g_pLTServer->GetObjectRotation( m_hObject, &rRot );
	g_pLTServer->SetObjectRotation( pDDPiece->m_hObject, &rRot );

	LTStrCpy( szPropType, pDDPiece->GetPropTypeName(), ARRAY_LEN( szPropType ));
	
	char *pszDoomsday = strtok( szPropType, "_" );
	char *pszSocket = strtok( NULL, "\0" );

	HATTACHMENT hAttachment;
	g_pLTServer->CreateAttachment( m_hObject, pDDPiece->m_hObject, pszSocket, &LTVector(0,0,0), &LTRotation(), &hAttachment );
	
	// Hide the target object...

	g_pCommonLT->SetObjectFlags( m_lsthTargets[pDDPiece->GetDoomsDayPieceType()], OFT_Flags, 0, FLAG_VISIBLE );

	// Add it to the list of pieces...

	m_lstPiecesOnDevice.push_back( pDDPiece );

	// Give the player points for adding the piece.
	ServerGameOptions& sgo = g_pGameServerShell->GetServerGameOptions( );
	uint32 nBonus = pDDPiece->IsHeavy( ) ? sgo.GetDoomsday( ).m_nHeavyPiecePlacedScore : sgo.GetDoomsday( ).m_nLightPiecePlacedScore;
	pPlayer->GetPlayerScore()->AddBonus( nBonus );

	if( m_lstPiecesOnDevice.size() == kDoomsDay_MAXTYPES )
	{
		// All the pieces are now on the base...
		
		Fire( *pPlayer );
	}

	return true;
}
Exemple #14
0
void DoomsDayDevice::InitialUpdate( )
{
	// Create the "target" objects...
	
	char szSpawn[256];
		
	LTVector vPos;
	g_pLTServer->GetObjectPos( m_hObject, &vPos );

	LTRotation rRot;
	g_pLTServer->GetObjectRotation( m_hObject, &rRot );

	// The PropTypes to use as targets are the normal PropTypes with _target appended...
	
	char szType[64] = {0};

	for( uint32 i = 0; i < kDoomsDay_MAXTYPES; ++i )
	{
		sprintf( szType, c_aDDPieceTypes[i].m_pszPropType );
		sprintf( szSpawn, "PropType Type %s_target", szType );

		BaseClass* pObj = SpawnObject( szSpawn, vPos, rRot );
		
		if( pObj && pObj->m_hObject )
		{
			m_lsthTargets.push_back( pObj->m_hObject );

			g_pCommonLT->SetObjectFlags( m_lsthTargets[i], OFT_Flags2, FLAG2_FORCETRANSLUCENT, FLAG2_FORCETRANSLUCENT );

			// Attach the target to the base...

			char *pszDoomsday = strtok( szType, "_" );
			char *pszSocket = strtok( NULL, "\0" );

			HATTACHMENT hAttachment;
			g_pLTServer->CreateAttachment( m_hObject, pObj->m_hObject, pszSocket, &LTVector(0,0,0), &LTRotation(), &hAttachment );
	
		}
	}

	BeginIdle( );
}
Exemple #15
0
bool WorldModel::CreateServerMark(CLIENTWEAPONFX & theStruct)
{
	// See if we should create a mark, or simply move one of the GameBase's
	// marks.

	// If the GameBase has the max number of marks or this mark is very close
	// to a pre-existing mark, just move that mark to the new position.

    HOBJECT hMoveObj = LTNULL;
    HOBJECT hFarObj  = LTNULL;

    uint32 nNumMarks = m_MarkList.size( );

    LTFLOAT  fClosestMarkDist  = REGION_DIAMETER;
    LTFLOAT  fFarthestMarkDist = 0.0f;
    uint8   nNumInRegion      = 0;
    LTVector vPos;

	for( ObjRefNotifierList::iterator iter = m_MarkList.begin( ); iter != m_MarkList.end( ); iter++ )
	{
		HOBJECT hObj = *iter;
		if( !hObj )
			continue;

		HATTACHMENT hAttachment = NULL;
        if (LT_OK == g_pLTServer->FindAttachment( m_hObject, hObj, &hAttachment))
		{
			LTransform transform;
            g_pCommonLT->GetAttachmentTransform(hAttachment, transform, LTTRUE);

			vPos = transform.m_Pos;
		}

        LTFLOAT fDist = VEC_DISTSQR(vPos, theStruct.vPos);
		if (fDist < REGION_DIAMETER)
		{
			if (fDist < fClosestMarkDist)
			{
				fClosestMarkDist = fDist;
				hMoveObj = hObj;
			}

			if (++nNumInRegion > MAX_MARKS_IN_REGION)
			{
				// Just move this mark to the correct pos...
				hMoveObj = hMoveObj ? hMoveObj : hObj;
				break;
			}
		}

		if (fDist > fFarthestMarkDist)
		{
			fFarthestMarkDist = fDist;
			hFarObj = hObj;
		}
	}

	// If we've got the max number of marks on this object, just move
	// the closest one to the new position...

	if (nNumMarks >= MAX_MARKS_PER_OBJECT)
	{
		if( !hMoveObj )
		{
			if( hFarObj )
			{
				hMoveObj = hFarObj;
			}
			else
			{
				HOBJECT hFirstMark = *m_MarkList.begin( );
				hMoveObj = hFirstMark;
			}
		}
	}
	else
	{
        hMoveObj = LTNULL; // Need to create one...
	}

	// Re-setup the object to move it...

	if (hMoveObj && IsKindOf(hMoveObj, "CServerMark"))
	{
        CServerMark* pMoveMark = (CServerMark*) g_pLTServer->HandleToObject(hMoveObj);
		if (!pMoveMark)
			return false;

		// Since this mark is already attached to us, remove the attachment
		DetachObject( pMoveMark->m_hObject );

		if( !AttachServerMark( *pMoveMark, (CLIENTWEAPONFX)theStruct))
		{
			g_pLTServer->RemoveObject( pMoveMark->m_hObject );
			RemoveMarkFromList( pMoveMark->m_hObject );
			pMoveMark = NULL;
			return false;
		}

		return true;
	}


	// Okay, no luck, need to create a new mark...

	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

    LTFLOAT fScaleAdjust = 1.0f;
	if (!GetImpactSprite((SurfaceType)theStruct.nSurfaceType, fScaleAdjust,
		theStruct.nAmmoId, createStruct.m_Filename, ARRAY_LEN(createStruct.m_Filename)))
	{
		return false;
	}

	createStruct.m_ObjectType = OT_SPRITE;
	createStruct.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATEABLESPRITE;
	createStruct.m_Pos = theStruct.vPos;

	createStruct.m_Rotation = LTRotation(theStruct.vSurfaceNormal, LTVector(0.0f, 1.0f, 0.0f));

	AMMO const *pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId);
	if( !pAmmo ) 
		return false;

    static HCLASS hClass = g_pLTServer->GetClass("CServerMark");
    CServerMark* pMark = (CServerMark*) g_pLTServer->CreateObject(hClass, &createStruct);
	if (!pMark)
		return false;


	// Randomly adjust the mark's scale to add a bit o spice...

	if (pAmmo->pImpactFX)
	{
        LTFLOAT fScale = fScaleAdjust * pAmmo->pImpactFX->fMarkScale;

        LTVector vScale(fScale, fScale, fScale);
        g_pLTServer->ScaleObject(pMark->m_hObject, &vScale);
	}

	if( !AttachServerMark( *pMark, (CLIENTWEAPONFX)theStruct))
	{
		g_pLTServer->RemoveObject( pMark->m_hObject );
		pMark = NULL;
		return false;
	}

	AddMarkToList( pMark->m_hObject );

	return true;
}
Exemple #16
0
bool CFallingStuffFX::Update(float tmFrameTime)
{
    // Base class update first

    m_vLastPos = m_vPos;

    if (!CBaseFX::Update(tmFrameTime))
        return false;

    //increment our emission time by the elapsed frame time
    m_tmElapsedEmission += tmFrameTime;

    if (!IsShuttingDown() && !IsSuspended() && (m_tmElapsedEmission > GetProps()->m_tmFallingStuffFXEmission))
    {
        ObjectCreateStruct ocs;
        INIT_OBJECTCREATESTRUCT(ocs);

        LTVector vScale;
        vScale.Init(m_scale, m_scale, m_scale);

        LTVector vInterp;
        LTVector vInterpCur  = m_vPos;

        // Calculate interpolant for particle system

        if (GetProps()->m_nFallingStuffFXEmission)
        {
            vInterp = m_vPos - m_vLastPos;
            vInterp /= (float)GetProps()->m_nFallingStuffFXEmission;
        }

        for (uint32 i = 0; i < GetProps()->m_nFallingStuffFXEmission; i ++)
        {
            ocs.m_ObjectType		= OT_SPRITE;
            ocs.m_Flags				= FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATABLESPRITE;

            // Compute the initial position

            float xRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f);
            float zRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f);

            ocs.m_Pos = m_vPos + (m_vRight * xRand) + (m_vUp * zRand);

            ocs.m_Scale				= vScale;
            strcpy(ocs.m_Filename, GetProps()->m_sSpriteName);

            // Move the start point

            vInterpCur += vInterp;

            HLOCALOBJ hNewSprite = m_pLTClient->CreateObject(&ocs);

            if (hNewSprite)
            {
                // Create a new sprite

                FALLING_THING *pNewSprite = debug_new( FALLING_THING );

                if (GetProps()->m_nImpactCreate)
                {
                    if (g_dwSplash > (uint32)GetProps()->m_nImpactCreate)
                    {
                        pNewSprite->m_bSplash = true;
                        g_dwSplash = 0;
                    }
                    else
                    {
                        pNewSprite->m_bSplash = false;
                    }
                }
                else
                {
                    pNewSprite->m_bSplash = false;
                }

                g_dwSplash ++;

                if (pNewSprite)
                {
                    LTVector v;

                    // Compute the initial velocity

                    v = m_vPlaneDir * GetProps()->m_fVel;

                    pNewSprite->m_hObject	= hNewSprite;
                    pNewSprite->m_vVel		= v;
                    pNewSprite->m_tmElapsed	= 0.0f;
                    pNewSprite->m_vPos		= ocs.m_Pos;
                    pNewSprite->m_vLastPos	= ocs.m_Pos;

                    m_collSprites.AddTail(pNewSprite);
                }
            }
        }

        m_tmElapsedEmission = 0.0f;

        // And store the last position

        m_vLastPos = m_vPos;
    }

    LTMatrix mSpin;

    if (GetProps()->m_bUseSpin)
    {
        // Setup rotation

        LTMatrix vRight;
        LTMatrix vUp;
        LTMatrix vForward;
        LTMatrix vTmp;

        Mat_SetupRot(&vRight, &m_vRight, m_xRot);
        Mat_SetupRot(&vUp, &m_vUp, m_yRot);
        Mat_SetupRot(&vForward, &m_vPlaneDir, m_zRot);

        MatMul(&vTmp, &vRight, &vUp);
        MatMul(&mSpin, &vTmp, &vForward);

        m_xRot += GetProps()->m_vRotAdd.x * tmFrameTime;
        m_yRot += GetProps()->m_vRotAdd.y * tmFrameTime;
        m_zRot += GetProps()->m_vRotAdd.z * tmFrameTime;
    }

    // Get the camera rotation

    LTRotation orient;
    m_pLTClient->GetObjectRotation(m_hCamera, &orient);

    LTRotation dRot(orient);

    LTVector vF = orient.Forward();

    float rot = (float)atan2(vF.x, vF.z);

    // Update the sprites....

    CLinkListNode<FALLING_THING *> *pNode = m_collSprites.GetHead();
    CLinkListNode<FALLING_THING *> *pDelNode;

    while (pNode)
    {
        pDelNode = NULL;

        FALLING_THING *pSprite = pNode->m_Data;

        //adjust our elapsed time
        pSprite->m_tmElapsed += tmFrameTime;

        // Check for expiration

        if (pSprite->m_tmElapsed > GetProps()->m_tmSpriteLifespan)
        {
            // Destroy this object

            m_pLTClient->RemoveObject(pSprite->m_hObject);

            pDelNode = pNode;
        }
        else
        {
            // Update !!

            pSprite->m_vLastPos = pSprite->m_vPos;

            pSprite->m_vPos += (pSprite->m_vVel * tmFrameTime);

            // Rotate if neccessary

            TVector3<float> vPos = pSprite->m_vPos;

            if (GetProps()->m_bUseSpin)
            {
                MatVMul_InPlace(&mSpin, &vPos);
            }

            // Add in wind

            vPos += (GetProps()->m_vWind * GetProps()->m_fWindAmount) * tmFrameTime;

            // Setup the new sprite position

            LTVector vPos2 = vPos;
            m_pLTClient->SetObjectPos(pSprite->m_hObject, &vPos2);


            // Setup the colour

            float r, g, b, a;

            m_pLTClient->GetObjectColor(pSprite->m_hObject, &r, &g, &b, &a);
            CalcColour(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &r, &g, &b, &a);
            m_pLTClient->SetObjectColor(pSprite->m_hObject, r, g, b, a);

            // Setup the scale

            float scale = 0.1f;

            CalcScale(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &scale);

            LTVector vScale;
            vScale.Init(scale, scale * GetProps()->m_fStretchMul, scale);
            m_pLTClient->SetObjectScale(pSprite->m_hObject, &vScale);

            // Setup the rotation

            dRot = LTRotation(0, 0, 0, 1);
            LTRotation orient(dRot);

            orient.Rotate( orient.Up(), rot );

            m_pLTClient->SetObjectRotation(pSprite->m_hObject, &orient);

            // Check to see if we need to start a splash sprite

            if (pSprite->m_bSplash)
            {
                ClientIntersectQuery ciq;
                ClientIntersectInfo  cii;

                ciq.m_From		= pSprite->m_vLastPos;
                ciq.m_To		= pSprite->m_vPos;

                if ((GetProps()->m_sImpactSpriteName[0]) && (m_pLTClient->IntersectSegment(&ciq, &cii)))
                {
                    // Create a splash sprite

                    SPLASH *pSplash = debug_new( SPLASH );

                    ObjectCreateStruct ocs;
                    INIT_OBJECTCREATESTRUCT(ocs);

                    LTVector vScale;
                    vScale.Init(0.0f, 0.0f, 0.0f);

                    ocs.m_ObjectType = OT_SPRITE;
                    ocs.m_Flags		 = FLAG_VISIBLE | FLAG_ROTATABLESPRITE | FLAG_NOLIGHT;
                    ocs.m_Pos		 = cii.m_Point + (cii.m_Plane.m_Normal * 2.0f);
                    ocs.m_Scale		 = vScale;

                    LTRotation dOrient( cii.m_Plane.m_Normal, LTVector(0.0f, 1.0f, 0.0f) );

                    strcpy(ocs.m_Filename, GetProps()->m_sImpactSpriteName);

                    pSplash->m_hObject = m_pLTClient->CreateObject(&ocs);
                    pSplash->m_scale = 0.0f;

                    LTRotation orient(dRot);
                    m_pLTClient->SetObjectRotation(pSplash->m_hObject, &orient);

                    pSplash->m_tmElapsed = 0.0f;

                    m_collSplashes.AddTail(pSplash);

                    // Destroy this object

                    m_pLTClient->RemoveObject(pSprite->m_hObject);

                    // Delete the sprite

                    pDelNode = pNode;
                }
            }
        }

        pNode = pNode->m_pNext;

        if (pDelNode) m_collSprites.Remove(pDelNode);
    }

    // Update our splashes

    CLinkListNode<SPLASH *> *pSplashNode = m_collSplashes.GetHead();

    while (pSplashNode)
    {
        CLinkListNode<SPLASH *> *pDelNode = NULL;

        SPLASH *pSplash = pSplashNode->m_Data;

        //update the elapsed time on the splash
        pSplash->m_tmElapsed += tmFrameTime;

        // Calculate the new scale

        float scale = GetProps()->m_fImpactScale1 + ((GetProps()->m_fImpactScale2 - GetProps()->m_fImpactScale1) * (pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan));

        LTVector vScale(scale, scale, scale);
        m_pLTClient->SetObjectScale(pSplash->m_hObject, &vScale);

        float r, g, b, a;

        m_pLTClient->GetObjectColor(pSplash->m_hObject, &r, &g, &b, &a);

        a = (float)(int)(pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan);
        if (a < 0.0f) a = 0.0f;
        if (a > 1.0f) a = 1.0f;

        m_pLTClient->SetObjectColor(pSplash->m_hObject, r, g, b, a);

        if (pSplash->m_tmElapsed > GetProps()->m_tmImpactLifespan)
        {
            m_pLTClient->RemoveObject(pSplash->m_hObject);
            pDelNode = pSplashNode;
        }

        pSplashNode = pSplashNode->m_pNext;

        if (pDelNode) m_collSplashes.Remove(pDelNode);
    }

    // Success !!

    return true;
}