Ejemplo n.º 1
0
void Fire::InitialUpdate(int nInfo)
{
	if (nInfo == INITIALUPDATE_SAVEGAME) return;

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

    g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, m_bOn ? USRFLG_VISIBLE : 0, FLAGMASK_ALL);

	// Tell the clients about the Fire...

	CAutoMessage cMsg;
	cMsg.Writeuint8(SFX_FIRE_ID);
	cMsg.Writefloat(m_fRadius);
    cMsg.Writefloat(m_fSoundRadius);
    cMsg.Writefloat(m_fLightRadius);
    cMsg.Writefloat(m_fLightPhase);
    cMsg.Writefloat(m_fLightFreq);
    cMsg.WriteLTVector(m_vLightOffset);
    cMsg.WriteLTVector(m_vLightColor);
    cMsg.Writeuint8(m_bSmoke);
    cMsg.Writeuint8(m_bLight);
    cMsg.Writeuint8(m_bSparks);
    cMsg.Writeuint8(m_bSound);
    cMsg.Writeuint8(m_bBlackSmoke);
    cMsg.Writeuint8(m_bSmokeOnly);
	g_pLTServer->SetObjectSFXMessage(m_hObject, cMsg.Read());
}
Ejemplo n.º 2
0
void LightGroup::UpdateClients()
{
	// Calculate our current color
	LTVector vColor = (m_bOn) ? m_vColor : LTVector(0.0f, 0.0f, 0.0f);

	{
		// Set up the update message
		CAutoMessage cMsg;
		cMsg.Writeuint8(MID_SFX_MESSAGE);
		cMsg.Writeuint8(SFX_LIGHTGROUP_ID);
		cMsg.WriteObject(m_hObject);
		cMsg.Writeuint32(m_nID);
		cMsg.WriteLTVector(vColor);

		// Send the message to all connected clients
		g_pLTServer->SendToClient(cMsg.Read(), LTNULL, MESSAGE_GUARANTEED);
	}
	
	{
		CAutoMessage cMsg;
		cMsg.Writeuint8(SFX_LIGHTGROUP_ID);

		cMsg.Writeuint32(m_nID);
		cMsg.WriteLTVector(vColor);

		// Make sure new clients will get the message
		g_pLTServer->SetObjectSFXMessage(m_hObject, cMsg.Read());
	}

	m_bClientNeedsUpdate = false;
}
Ejemplo n.º 3
0
void CLeanMgr::BeginLean( eLeanDirection kDir )
{
	m_kLeanDir = kDir;

	m_fMaxLeanAngle = DEG2RAD( g_vtLeanAngle.GetFloat() );
	m_fLeanFromAngle = m_fLastLeanAngle;

	m_fStartTime = 0.0f;
	m_fEndTime = g_vtLeanOutTime.GetFloat();

	if( m_bLeanedOut )
	{
		// Send a message to the server to remove the original stimulus.

		CAutoMessage cMsg;
		cMsg.Writeuint8( MID_PLAYER_CLIENTMSG );
		cMsg.Writeuint8( CP_PLAYER_LEAN );
		cMsg.Writeuint8( PL_CENTER );
		cMsg.WriteLTVector( LTVector( 0, 0, 0) );
		g_pLTClient->SendToServer( cMsg.Read(), MESSAGE_GUARANTEED );
	}

	// If we are just begining to lean then we are not leaned out...

	m_bLeanedOut = false;
}
Ejemplo n.º 4
0
bool ServerPhysicsCollisionMgr::HandleRigidBodyCollision( CollisionData& collisionData )
{
	if( !PhysicsCollisionMgr::HandleRigidBodyCollision( collisionData ))
		return false;

	// Check if this event needs to get sent to the client.
	if( collisionData.bSendToClient )
	{
		CAutoMessage cMsg;
		cMsg.Writeuint8( MID_PHYSICSCOLLISION );
		// We send the rigidbody values down to the client, even though
		// they can't be dereferenced.  They will be used to
		// uniquely identify this collision event on the client.
		cMsg.Writeuint32(( uint32 )collisionData.hBodyA );
		cMsg.Writeuint32(( uint32 )collisionData.hBodyB );
		// Send the objects down if we had rigid bodies.  We
		// can't get the objects without the rigid bodies, so
		// only sending them when we have non-null rigid bodies saves bandwidth.
		if( collisionData.hBodyA != INVALID_PHYSICS_RIGID_BODY )
			cMsg.WriteObject( collisionData.hObjectA );
		if( collisionData.hBodyB != INVALID_PHYSICS_RIGID_BODY )
			cMsg.WriteObject( collisionData.hObjectB );
		// We can write out 8bits of index here because we already
		// have a 255 limit on collisionproperties, since they must fit in the userflags.
		cMsg.Writeuint8(( uint8 )g_pLTDatabase->GetRecordIndex( collisionData.hCollisionPropertyA ));
		cMsg.Writeuint8(( uint8 )g_pLTDatabase->GetRecordIndex( collisionData.hCollisionPropertyB ));
		// Super fine resolution of the impulse isn't necessary
		// since the data tables are defined with integers.
		cMsg.Writefloat(collisionData.fImpulse);
		cMsg.WriteLTVector( collisionData.vCollisionPt );
		cMsg.WriteLTVector( collisionData.vCollisionNormal );
		// We're sending unguaranteed, since it's not essential the client is informed,
		// since it's just sounds and clientfx.
		g_pLTServer->SendToClient( cMsg.Read(), NULL, 0 );
	}

	return true;
}
Ejemplo n.º 5
0
void CDestructibleModel::CreateDestroyedFX(const DamageStruct& DamageInfo)
{
	// If no destroyed fx is specifed, return...
	if ( LTStrEmpty( m_pszDestroyedFXName ) || !LTStrICmp(m_pszDestroyedFXName, FX_NONE)) return;

	// Use the position/rotation of the object for the fx...
	LTRigidTransform tObjTrans;
	g_pLTServer->GetObjectTransform(m_hObject, &tObjTrans);

	CAutoMessage cMsg;
	cMsg.Writeuint8(SFX_CLIENTFXGROUPINSTANT);
	cMsg.WriteString(m_pszDestroyedFXName);
	cMsg.Writebool( false ); // loop
	cMsg.Writebool( false ); // smooth shutdown
	cMsg.Writebool( false ); // No special parent
	cMsg.WriteLTVector(tObjTrans.m_vPos);
	cMsg.WriteCompLTRotation(tObjTrans.m_rRot);
	cMsg.Writebool( false ); // No target info

	g_pLTServer->SendSFXMessage(cMsg.Read(), 0);
}
Ejemplo n.º 6
0
void CLeanMgr::EndLean( eLeanDirection kDir )
{

	if( m_bLeanedOut )
	{
		// Send a message to the server to remove the original stimulus.

		CAutoMessage cMsg;
		cMsg.Writeuint8( MID_PLAYER_CLIENTMSG );
		cMsg.Writeuint8( CP_PLAYER_LEAN );
		cMsg.Writeuint8( PL_CENTER );
		cMsg.WriteLTVector( LTVector( 0, 0, 0) );
		g_pLTClient->SendToServer( cMsg.Read(), MESSAGE_GUARANTEED );
	}
	
	// If we are ending a lean we are not leaned out...

	m_bLeanedOut = false;
	

	bool	bLeft = !!(m_dwControlFlags & BC_CFLG_LEAN_LEFT);
	bool	bRight = !!(m_dwControlFlags & BC_CFLG_LEAN_RIGHT);
	
	if( bLeft || bRight )
	{
		// Readjust the lean...

		m_kLeanDir			= bLeft ? kLean_Left : kLean_Right;
		m_fLeanFromAngle	= m_fLastLeanAngle;
		m_fStartTime		= 0.0f;
		
		float fMovePercent = 1.0f - (float(m_kLeanDir) * (m_fLastLeanAngle / m_fMaxLeanAngle));
		m_fEndTime = g_vtLeanOutTime.GetFloat() * fMovePercent; 
	}
	else
	{
		BeginCenter();
	}
}
void CClientMeleeCollisionController::HandleCollision(HOBJECT hTarget, HMODELNODE hNodeHit, EPhysicsGroup eHitPhysics, const LTVector& vPos, const LTVector& vDir)
{
	// Check if the attack has been blocked via rigidbody...
	if (eHitPhysics == PhysicsUtilities::ePhysicsGroup_UserBlockMelee)
	{
		HandleBlocked(hTarget, vPos, vDir);
		return;
	}

	// Check if the attack has been blocked via forced blocking (what the AI does)...
	CCharacterFX* pTargetFX = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(hTarget);
	if (pTargetFX && pTargetFX->IsBlocking())
	{
		HandleBlocked(hTarget, vPos, vDir);
		return;
	}

	// Handle normal damage...
	CAutoMessage cMsg;
	cMsg.Writeuint8(MID_OBJECT_MESSAGE);
	cMsg.WriteObject(m_hObject);
	cMsg.Writeuint32(MID_MELEEATTACK);
	cMsg.WriteObject(hTarget);
	cMsg.Writeuint32(hNodeHit);
	cMsg.WriteLTVector(vPos);
	cMsg.WriteLTVector(vDir);
	cMsg.Writeint32(g_pGameClientShell->GetServerRealTimeMS());
	g_pLTClient->SendToServer(cMsg.Read(), MESSAGE_GUARANTEED);

	//!!ARL: Maybe DisableCollisions for hTarget if they are blocking?
	// (to avoid the weirdness of taking damage but still blocking the attack)

	// For local player targets, send an AttackRecoil stimulus so a proper animation can be played.
	if (hTarget == g_pPlayerMgr->GetMoveMgr()->GetObject())
	{
		CPlayerBodyMgr::Instance().HandleAnimationStimulus("CS_RecoilFromAttack");
	}
}
Ejemplo n.º 8
0
void CreateClientWeaponFX(CLIENTWEAPONFX & theStruct)
{
    if (!g_pLTServer) return;

	// make sure the impact FX in valid
	ASSERT( ( 0 <= theStruct.eImpactType ) || ( IMPACT_TYPE_COUNT > theStruct.eImpactType ) );

	// If this is a moveable object, set the flags of fx to ignore
	// marks and smoke...

	if (IsMoveable(theStruct.hObj))
	{
		theStruct.wIgnoreFX |= WFX_MARK;

		// Create a server-side mark if applicable...

		if (CanMarkObject(theStruct.hObj))
		{
			AMMO const *pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId);
			if (pAmmo)
			{
				if (pAmmo->pImpactFX)
				{
					if (WFX_MARK & pAmmo->pImpactFX->nFlags)
					{
                        CreateServerMark((CLIENTWEAPONFX)theStruct);
					}
				}

				// Create an exit mark if applicable...

				if (pAmmo->pFireFX)
				{
					if (WFX_EXITMARK & pAmmo->pFireFX->nFlags)
					{
						CreateServerExitMark((const CLIENTWEAPONFX)theStruct);
					}
				}
			}
		}
	}

	// Do impact dings if applicable...

	if (!(IsMultiplayerGame() && IsCharacter(theStruct.hObj)))
	{
		theStruct.wIgnoreFX |= WFX_IMPACTDING;
	}


	// [KLS 2/28/02] - If the object hit is a character, re-evaluate the surface type.
	// We do this here because the process of applying damage to the character may have
	// changed the character's surface type (e.g., from Armor to Flesh).

	if (IsCharacter(theStruct.hObj))
	{
		theStruct.nSurfaceType = GetSurfaceType(theStruct.hObj);
	}


	// Tell all the clients who can see this fx about the fx...

	CAutoMessage cMsg;
	cMsg.Writeuint8(SFX_WEAPON_ID);
	cMsg.WriteObject(theStruct.hObj);
	cMsg.WriteObject(theStruct.hFiredFrom);
    cMsg.Writeuint8(theStruct.nWeaponId);
    cMsg.Writeuint8(theStruct.nAmmoId);
    cMsg.Writeuint8(theStruct.nSurfaceType);
    cMsg.Writeuint16(theStruct.wIgnoreFX);
    cMsg.Writeuint8(theStruct.nShooterId);
    cMsg.WriteLTVector(theStruct.vFirePos);
    cMsg.WriteLTVector(theStruct.vPos);
    cMsg.WriteLTVector(theStruct.vSurfaceNormal);
    cMsg.Writeuint8(theStruct.eImpactType);
	g_pLTServer->SendSFXMessage(cMsg.Read(), theStruct.vPos, 0);
}
Ejemplo n.º 9
0
void CLeanMgr::UpdateLean( )
{
	if( !IsLeaning() ) return;


	// Don't start leaning untill we are done moving...

	if( !m_bDoneMoving && (g_pMoveMgr->GetMovementPercent() > MATH_EPSILON) )
	{
		BeginLean( m_kLeanDir );
	}
	else
	{
		m_bDoneMoving = true;
	}

	LTVector vCamPos;
	g_pLTClient->GetObjectPos( g_pPlayerMgr->GetCamera(), &vCamPos );
	
	// Develop the rotation values...

	m_vRotationPt.Init( vCamPos.x, vCamPos.y - g_vtLeanRadius.GetFloat(), vCamPos.z );
	m_vRotationPtOffset.Init( 0.0f, g_vtLeanRadius.GetFloat(), 0.0f );
	

	float fLeanFromAngle	= m_fLeanFromAngle;

	// Did we try to center but went back to leaning before we finished...

	if( m_bFailedToCenter )
	{
		m_bFailedToCenter = false;

		// Recalculate the time...

		if( m_fMaxLeanAngle > 0.0f )
		{
			float fMovePercent = 1.0f - (float(m_kLeanDir) * (m_fLastLeanAngle / m_fMaxLeanAngle));
			m_fEndTime = g_vtLeanOutTime.GetFloat() * fMovePercent; 
		}

		m_fStartTime	= 0.0f;
		fLeanFromAngle	= m_fLastLeanAngle;
	}

	// Find the angle based on the percentage of lean we should be at...

	m_fStartTime += g_pLTClient->GetFrameTime();

	float	fT = (m_fStartTime / m_fEndTime);
	bool	bDone = CalcAngle( m_fLeanAngle, fLeanFromAngle, m_fMaxLeanAngle, m_kLeanDir, m_fEndTime, fT );

	// Save our last lean angle...

	m_fLastLeanAngle = m_fLeanAngle;

	LTRotation	rRot;
	LTVector	vPos;
	CalculateNewPosRot( vPos, rRot, m_fLeanAngle );

	// [KLS 3/22/03] Only adjust the camera in first person...

	if (g_pPlayerMgr->IsFirstPerson())
	{
		g_pLTClient->SetObjectPosAndRotation( g_pPlayerMgr->GetCamera(), &vPos, &rRot );
	}

	if( bDone )
	{
		if( !m_bLeanedOut )
		{
			// We are completely leaned out.

			m_bLeanedOut = true;

			// Send a message to the server to register a stimulus.

			CAutoMessage cMsg;
			cMsg.Writeuint8( MID_PLAYER_CLIENTMSG );
			cMsg.Writeuint8( CP_PLAYER_LEAN );
			cMsg.Writeuint8( m_kLeanDir == kLean_Left ? PL_LEFT : PL_RIGHT );
			cMsg.WriteLTVector( vPos );
			g_pLTClient->SendToServer( cMsg.Read(), MESSAGE_GUARANTEED );
		}

		m_bFailedToLean = false;
		return;
	}

	m_bFailedToLean = true;
}
Ejemplo n.º 10
0
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CDebugLineFX::Update
//
//	PURPOSE:	Checks for new lines, clients, or a clear line and sends
//				the data down to any clients.
//
// ----------------------------------------------------------------------- //
void DebugLineSystem::Update()
{
	if( !m_hObject ) return;

	while( ( !m_lstDebugLines.empty() ) || m_bClearOldLines )
	{
		// Set up the message.
		CAutoMessage cMsg;

		cMsg.Writeuint8( MID_SFX_MESSAGE );

		// Record the ID and server object, used to route the message.
		cMsg.Writeuint8( SFX_DEBUGLINE_ID );
		cMsg.WriteObject( m_hObject );

		// Record the number of entries.
		int cLines = m_lstDebugLines.size();
		if( cLines < s_MaxLinesPerMessage )
		{
			cMsg.Writeuint16( cLines );
		}
		else
		{
			cMsg.Writeuint16( s_MaxLinesPerMessage );
		}

		// Tell whether we want to clear old lines or not, 
		cMsg.Writebool( m_bClearOldLines );
		cMsg.Writebool( m_bRelative );

		// Record each entry.

		int iLine=0;
		DEBUG_LINE_LIST::iterator itLine;
		for( itLine = m_lstDebugLines.begin(); itLine != m_lstDebugLines.end(); ++itLine )
		{
			cMsg.WriteType( *itLine );
			++iLine;
			if( iLine >= s_MaxLinesPerMessage )
			{
				break;
			}
		}
		m_lstDebugLines.erase( m_lstDebugLines.begin(), itLine );

		cMsg.WriteString( m_DebugString.c_str() );
		cMsg.WriteLTVector( m_vDebugStringPos );

		// Send the message!
		g_pLTServer->SendToClient(cMsg.Read(), NULL, MESSAGE_GUARANTEED);
		
		// If we have cleared out our lines and have no more to send,
		// why should we exist?
		if( m_bClearOldLines && ( cLines == 0 ) )
		{
			char szObjectName[256];
			g_pLTServer->GetObjectName(m_hObject, szObjectName, LTARRAYSIZE(szObjectName));
			LineSystem::SystemMap::iterator iter = LineSystem::g_systems.find( szObjectName );
			if( iter != LineSystem::g_systems.end() )
			{
				LineSystem::g_systems.erase(iter);
			}

			g_pLTServer->RemoveObject(m_hObject);
		}

		// Reset m_bClearOldLines so that we don't re-enter this block.
		m_bClearOldLines = false;
	}
}
Ejemplo n.º 11
0
WeaponState CClientWeaponDisc::Update( bool bFire,
                                       FireType eFireType /*=FT_NORMAL_FIRE*/ )
{
/// DEBUG CODE
    if ( g_bDisplayClientWeaponTarget )
    {
        // find the point we're aiming at
        LTVector vTargetPoint;
        CalculatePointGuidedTarget( &vTargetPoint );
        static CLIENTFX_LINK s_pTargetPoint;
        if ( s_pTargetPoint.m_pInstance )
        {
            // back it off just a little
            LTVector vBackOff;
            CalculateControlDirection( &vBackOff );
            vBackOff *= -5.0f;
            vTargetPoint += vBackOff;
            s_pTargetPoint.m_pInstance->SetPos( vTargetPoint, vTargetPoint );
        }
        else
        {
            // create the target point
            CLIENTFX_CREATESTRUCT fxInit( "DISC_target", FXFLAG_LOOP , vTargetPoint );

            g_pClientFXMgr->CreateClientFX( &s_pTargetPoint, fxInit, LTTRUE );
            if ( s_pTargetPoint.m_pInstance )
            {
                s_pTargetPoint.m_pInstance->m_bPlayerView = LTFALSE;
            }
        }
    }
/// DEBUG CODE

    //
    // See if we are disabled...If so don't allow any weapon stuff...
    if ( m_bDisabled )
    {
        return W_IDLE;
    }

    if ( m_bDiscNeedsUpdates )
    {
        CAutoMessage cMsg;
        LTRESULT ltResult;

        cMsg.Writeuint8( MID_PROJECTILE );

        // write the projectile message subtype
        cMsg.Writeuint8( MPROJ_UPDATE_CONTROL_LINE );

        // pass a control vector, which is a vector pointing
        // straight out in front of the player
        LTVector vControlDirection;
        CalculateControlDirection( &vControlDirection );

        // get the control position (in this case, the camera position)
        // get the camera
        HOBJECT hCamera = g_pPlayerMgr->GetCamera();
        ASSERT( 0 != hCamera );
        LTVector vControlPosition;
        ltResult = g_pLTClient->GetObjectPos( hCamera, &vControlPosition );
        ASSERT( LT_OK == ltResult );

        // write the control vector
        cMsg.WriteLTVector( vControlDirection );

        // write the control position
        cMsg.WriteLTVector( vControlPosition );

        // send the message
        ltResult = g_pLTClient->SendToServer(
                       cMsg.Read(),
                       MESSAGE_GUARANTEED
                   );
        ASSERT( LT_OK == ltResult );
    }

    return CClientWeapon::Update( bFire, eFireType );
}
Ejemplo n.º 12
0
void CTransitionAggregate::Load( ILTMessage_Read *pMsg, uint32 dwLoadFlags )
{
	if( !pMsg ) return;
	
	LOAD_HOBJECT( m_hObject );

	// The rest is dependent on the load type...

	if( dwLoadFlags != LOAD_TRANSITION ) return;
	
	HOBJECT hTransArea = g_pTransMgr->GetTransitionArea();
	if( !hTransArea ) return;
	
	TransitionArea *pTransArea = (TransitionArea*)g_pLTServer->HandleToObject( hTransArea );
	if( !pTransArea ) return;

	LTransform tfLocal;
	LTransform tfObjectWorld;
	LTVector vVelRel;
	LTransform const& tfTransAreaWorld = pTransArea->GetWorldTransform( );
	LTMatrix mRotation;
	tfTransAreaWorld.m_Rot.ConvertToMatrix( mRotation );

	LOAD_VECTOR( tfLocal.m_Pos );
	LOAD_ROTATION( tfLocal.m_Rot );
	LOAD_VECTOR( vVelRel );
	
	// Calc pos and rot based on offsets and current TransArea...

	tfObjectWorld.m_Pos = tfTransAreaWorld.m_Pos + ( mRotation * tfLocal.m_Pos );
	tfObjectWorld.m_Rot = tfTransAreaWorld.m_Rot * tfLocal.m_Rot;
	LTVector vVel = mRotation * vVelRel;

	if( IsPlayer( m_hObject ))
	{
		// Since the PlayerObj is controlled by the client we need to notify the
		// client of the rotation.  We are only worried about the Yaw since Roll doesn't 
		// matter and Pitch can be preserved on the client.


		CPlayerObj *pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject( m_hObject );
		if( !pPlayer ) return;

		
		LTFLOAT		fYaw;
		LTVector	vF = tfObjectWorld.m_Rot.Forward();

		// We don't care about Roll...

		vF.y = 0.0f; 
		vF.Normalize();

		// Yaw = arctan( vF.x / vF.z );
		// atan2 is well defined even for vF.z == 0

		fYaw = (LTFLOAT)atan2( vF.x, vF.z );
		
		// Inform the client of the correct camera/player orientation...

		LTVector vVec( 0.0f, fYaw, 0.0f );
		
		CAutoMessage cMsg;
		cMsg.Writeuint8( MID_PLAYER_ORIENTATION );
		cMsg.Writeuint8( MID_ORIENTATION_YAW );
		cMsg.WriteLTVector( vVec );
		g_pLTServer->SendToClient(cMsg.Read(), pPlayer->GetClient(), MESSAGE_GUARANTEED);
		
	}

	g_pLTServer->SetObjectPos( m_hObject, &tfObjectWorld.m_Pos );
	g_pLTServer->SetObjectRotation( m_hObject, &tfObjectWorld.m_Rot );
	g_pPhysicsLT->SetVelocity( m_hObject, &vVel );
}