//===========================================================================//
// File:	NetMovement.cpp											
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 01/06/2000  JSE  Inital coding
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Microsoft Corp.										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//


#include "MW4Headers.hpp"

#include "NetMovement.hpp"
#include "MWEntityManager.hpp"
#include "VehicleInterface.hpp"
#include "MWPlayer.hpp"
#include "Torso.hpp"
#include <Adept\Map.hpp>
#include "Adept\NetStatCollector.hpp"
#include "Sensor.hpp"


//##########################################################################
//###########################   MechPositionUpdate
//##########################################################################


void MechWarrior4::NetMovementSecurityCheckStart()
{
	_asm
	{
		nop
	}	
}




void MechPositionUpdate::Decode(Entity *entity, MemoryStream *memory_stream, Time till, Scalar packet_latency, int connection, int debug_level, int bandwidth, Scalar rate)
{
	Check_Object(memory_stream);
	Check_Object(entity);


	int current_bit = memory_stream->GetCurrentBitCount();

	Mech *mech = Cast_Object(Mech*, entity);

	
	const Mech::GameModel *model = mech->GetGameModel();
	Check_Object(model);


	Torso* torso = mech->GetTorso();
	Check_Object(torso);
	const Torso::GameModel *torso_model;
	torso_model = torso->GetGameModel();
	Check_Object(torso_model);


	YawPitchRoll mech_rotation_local_to_world(YawPitchRoll::Identity);
	Point3D mech_translation_local_to_world(Point3D::Identity);

	Scalar min_z, max_z, min_x, max_x;
	Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x);

	int master_mech_on = 0; // jcem: critical error - should clear before ReadBits(...)...
	memory_stream->ReadBits( &master_mech_on, 1);

	int local_mech_on = (mech->executionState->GetState() != Mech::ExecutionStateEngine::NeverExecuteState)?1:0;

	

	if (master_mech_on && !local_mech_on)
	{
		mech->TurnOn();
	}

	if (!master_mech_on && local_mech_on)
	{
		mech->TurnOff();
	}




	Scalar speed_demand;
	Scalar yaw_deamand;

	memory_stream->ReadBitsToScaledFloat(yaw_deamand, -1.01f, 1.01f, BitDepthManager::BitDepth(UpdateType,RotationDemandUpdateEntryID));
	memory_stream->ReadBitsToScaledFloat(speed_demand, -1.01f, 1.01f, BitDepthManager::BitDepth(UpdateType,SpeedDemandUpdateEntryID));


	if (Stuff::Close_Enough(yaw_deamand ,0.0f,0.05f))
	{
		yaw_deamand = 0.0f;
	}
	if (Stuff::Close_Enough(speed_demand ,0.0f,0.05f))
	{
		speed_demand = 0.0f;
	}
	
	mech->yawDemand = yaw_deamand;
	mech->speedDemand = speed_demand;


#if 0
	memory_stream->ReadBitsToScaledFloat(torso->pitchDemand, -1.0, 1.0, BitDepthManager::BitDepth(UpdateType,TorsoPichDemandUpdateEntryID));
	memory_stream->ReadBitsToScaledFloat(torso->yawDemand, -1.0, 1.0, BitDepthManager::BitDepth(UpdateType,TorsoYawDemandUpdateEntryID));
	
	if (Stuff::Close_Enough(torso->pitchDemand ,0.0f,0.05f))
	{
		torso->pitchDemand = 0.0f;
	}
	if (Stuff::Close_Enough(torso->yawDemand ,0.0f,0.05f))
	{
		torso->yawDemand = 0.0f;
	}
#endif
	



	int mech_state = 0; // jcem: critical error - should clear before ReadBits(...)...
	memory_stream->ReadBits( &mech_state, 2);

	switch (mech_state)
	{
		case DrivingState:

			{
				if (master_mech_on)
				{
					if (mech->executionState->GetState() != Mech::ExecutionStateEngine::DrivingMotionState)
					{
						mech->executionState->RequestState(Mech::ExecutionStateEngine::DrivingMotionState);

					}

					if (!mech->animStateEngine->IsTransitioning())
					{
						switch (mech->animStateEngine->GetState())
						{
						case MechAnimationStateEngine::FallForwardState:
						case MechAnimationStateEngine::FallBackwardState:
						case MechAnimationStateEngine::FallLeftState:
						case MechAnimationStateEngine::FallRightState:
							mech->animStateEngine->RequestState(MechAnimationStateEngine::StandState, Mech::NoBlend);
							break;
						}
					}
				}
				
				Point3D current_speed = Point3D::Identity;
				mech->queFallState = Mech::NoFallMode;
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.y, -2005.0f, 1005.0f, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_rotation_local_to_world.yaw.angle, -Stuff::Pi, Stuff::Pi, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(current_speed.z, model->maxReverseSpeed, model->maxSpeed*1.25f, BitDepthManager::BitDepth(UpdateType,CurrentSpeedUpdateEntryID));
			
				bool shutdown = 0;
				bool crouch = 0;
				memory_stream->ReadBit(shutdown);
				memory_stream->ReadBit(crouch);

				mech->ShutDownRequest(shutdown);
				if (mech->IsCrouched() != crouch)
					mech->CrouchRequest();

				mech->SetNetworkCorretionPosition(mech_translation_local_to_world, mech_rotation_local_to_world, current_speed, speed_demand, packet_latency, rate);
				mech->currentSpeedMPS = current_speed.z;
				

				//SPEW(("jerryeds", "<%f:%f:%f>", mech_translation_local_to_world.x, mech_translation_local_to_world.y, mech_translation_local_to_world.z));

			}
			break;

		case JumpingState:
			{

				if (master_mech_on && mech->executionState->GetState() != Mech::ExecutionStateEngine::FlyingMotionState)
				{
					mech->executionState->RequestState(Mech::ExecutionStateEngine::FlyingMotionState);

				}
		
				
				mech->queFallState = Mech::NoFallMode;
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.y, -2005.0f, 1005.0f, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_rotation_local_to_world.yaw.angle, -Stuff::Pi, Stuff::Pi, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
				
				memory_stream->ReadBitsToScaledFloat(mech->localSpaceVelocity.linearMotion.x, -300.0f, 300.0f, BitDepthManager::BitDepth(UpdateType,CurrentXVelocityEntryID));
				memory_stream->ReadBitsToScaledFloat(mech->localSpaceVelocity.linearMotion.y, -300.0f, 300.0f, BitDepthManager::BitDepth(UpdateType,CurrentYVelocityEntryID));
				memory_stream->ReadBitsToScaledFloat(mech->localSpaceVelocity.linearMotion.z, -300.0f, 300.0f, BitDepthManager::BitDepth(UpdateType,CurrentZVelocityEntryID));


				mech->worldSpaceVelocity.linearMotion.Multiply(
					mech->localSpaceVelocity.linearMotion,
					mech->GetLocalToWorld()
				);

				Point3D speed(mech->localSpaceVelocity.linearMotion.x, mech->localSpaceVelocity.linearMotion.y, mech->localSpaceVelocity.linearMotion.z);
				mech->SetNetworkCorretionPosition(mech_translation_local_to_world, mech_rotation_local_to_world, speed, mech->localSpaceVelocity.linearMotion.z, packet_latency, rate);
				
			}
			break;
	
		case FallingState:
			{
				Point3D current_speed = Point3D::Identity;
                mech->queFallState = 0; // may not be error but..., jcem: critical error - should clear before ReadBits(...)...
				memory_stream->ReadBits(&mech->queFallState, 3);


				if (master_mech_on && mech->executionState->GetState() != Mech::ExecutionStateEngine::FallingMotionState && mech->blockFallTimer > 2.0f)
				{

					switch(mech->queFallState)
					{
					case Mech::FallBackMode:
						mech->animStateEngine->RequestState(MechAnimationStateEngine::FallBackwardState);
						break;

					case Mech::FallRightMode:
						mech->animStateEngine->RequestState(MechAnimationStateEngine::FallRightState);
						break;

					case Mech::FallLeftMode:
						mech->animStateEngine->RequestState(MechAnimationStateEngine::FallLeftState);
						break;

					case Mech::FallForwardMode:
						mech->animStateEngine->RequestState(MechAnimationStateEngine::FallForwardState);
						break;
					}

					mech->StartFall();
				}
				
				mech->fallDirection = mech->queFallState;
				mech->queFallState = Mech::NoFallMode;

				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.y, -2005.0f, 1005.0f, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_translation_local_to_world.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(mech_rotation_local_to_world.yaw.angle, -Stuff::Pi, Stuff::Pi, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
				memory_stream->ReadBitsToScaledFloat(current_speed.z, model->maxReverseSpeed, model->maxSpeed*1.25f, BitDepthManager::BitDepth(UpdateType,CurrentSpeedUpdateEntryID));
				
				mech->SetNetworkCorretionPosition(mech_translation_local_to_world, mech_rotation_local_to_world, current_speed, 0.0f, packet_latency,rate);
				mech->currentSpeedMPS = current_speed.z;
			}
			break;
	}

		

	
	



	Scalar pitch_value;
	Scalar yaw_value;


	Sensor *sensor;




	bool sensor_on = true;

	memory_stream->ReadBit(sensor_on);


	sensor = mech->GetSensor();
	if(sensor)
	{
		if (sensor_on)
		{
			sensor->SetSensorMode(Sensor::ActiveMode, mech->DoesHaveBeagle());
		}
		else
		{
			sensor->SetSensorMode(Sensor::PassiveMode, mech->DoesHaveBeagle());
		}
	}

	memory_stream->ReadBitsToScaledFloat(pitch_value, -torso_model->pitchRadius, torso_model->pitchRadius, BitDepthManager::BitDepth(UpdateType,CurrentTorsoPitchUpdateEntryID));
	memory_stream->ReadBitsToScaledFloat(yaw_value, -torso_model->twistRadius, torso_model->twistRadius, BitDepthManager::BitDepth(UpdateType,CurrentTorsoYawUpdateEntryID));

	torso->oldYawValue = torso->yawValue;
	torso->oldPitchValue = torso->pitchValue;
	torso->pitchValueCorrection = pitch_value;
	torso->yawValueCorrection = yaw_value;
	torso->correctionCurTime = 0.0f;
	torso->correctionTime = rate;

// MSL 5.04 Back View Added
	int look_direction = 0; // jcem: critical error - should clear before ReadBits(...)...
	memory_stream->ReadBits( &look_direction, 2);

	if (look_direction == Torso::LookLeftDirection)
	{		
		torso->LookLeft();
	}
	else if (look_direction == Torso::LookRightDirection)
	{
		torso->LookRight();
	}
	else if (look_direction == Torso::LookBackDirection)
	{
		torso->LookBack();
	}
	else if (look_direction == Torso::SurrenderDirection)
	{
		torso->LookSurrender();
	}
	else
	{
		torso->LookForward();
	}




	Network::GetInstance()->netStatCollector[Network::IncomingMechMovementBitSizeStat].AddToStatistic(connection,memory_stream->GetCurrentBitCount() - current_bit);


}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void MechPositionUpdate::Skip(MemoryStream *memory_stream, int size, Time till, int connection, int debug_level, int bandwidth)
{
	Check_Object(memory_stream);
	

	int current_bit = memory_stream->GetCurrentBitCount();


	int throwaway;

	memory_stream->ReadBits( &throwaway, 1);

	memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,RotationDemandUpdateEntryID));
	memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,SpeedDemandUpdateEntryID));

#if 0
	memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,TorsoPichDemandUpdateEntryID));
	memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,TorsoYawDemandUpdateEntryID));
#endif

	int mech_state = 0; // jcem: critical error - should clear before ReadBits(...)...
	memory_stream->ReadBits( &mech_state, 2);

	switch (mech_state)
	{

	case DrivingState:
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentSpeedUpdateEntryID));
		memory_stream->ReadBits(&throwaway, 1);
		memory_stream->ReadBits(&throwaway, 1);

		break;

	case JumpingState:
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
	
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentXVelocityEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentYVelocityEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentZVelocityEntryID));

		break;

	case FallingState:
		memory_stream->ReadBits(&throwaway, 3);
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
		memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentSpeedUpdateEntryID));
		
		break;

	}
	
	bool throwaway_b;
	memory_stream->ReadBit(throwaway_b);
		
	memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentTorsoPitchUpdateEntryID));
	memory_stream->ReadBits(&throwaway, BitDepthManager::BitDepth(UpdateType,CurrentTorsoYawUpdateEntryID));
	
	memory_stream->ReadBits(&throwaway, 2);



	Network::GetInstance()->netStatCollector[Network::IncomingMechMovementBitSizeStat].AddToStatistic(connection,memory_stream->GetCurrentBitCount() - current_bit);


}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int MechPositionUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{
	
	int current_bit = 0;

	current_bit += BitDepthManager::BitDepth(UpdateType,RotationDemandUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,SpeedDemandUpdateEntryID);

#if 0
	current_bit += BitDepthManager::BitDepth(UpdateType,TorsoPichDemandUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,TorsoYawDemandUpdateEntryID);
#endif

	current_bit += 4;
	current_bit += BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,CurrentSpeedUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,CurrentXVelocityEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,CurrentYVelocityEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,CurrentZVelocityEntryID);

	current_bit += 1;
	current_bit += BitDepthManager::BitDepth(UpdateType,CurrentTorsoPitchUpdateEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,CurrentTorsoYawUpdateEntryID);
	current_bit += 3;
	current_bit += 2;
	
	return current_bit;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechPositionUpdate::Encode(Entity *entity, DynamicMemoryStream *memory_stream, int connection, int debug_level, int bandwidth)
{
	Check_Object(memory_stream);
	Check_Object(entity);

	int current_bit = memory_stream->GetCurrentBitCount();

	Mech *mech = Cast_Object(Mech*, entity);

	const Mech::GameModel *model = mech->GetGameModel();
	Check_Object(model);

	
	Torso* torso = mech->GetTorso();
	Check_Object(torso);
	const Torso::GameModel *torso_model;
	torso_model = torso->GetGameModel();
	Check_Object(torso_model);


	YawPitchRoll mech_rotation_local_to_world;
	Point3D mech_translation_local_to_world;
	
	mech->GetNetworkPosition(mech_translation_local_to_world, mech_rotation_local_to_world);


	Scalar min_z, max_z, min_x, max_x;
	Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x);

	
	int local_mech_on = (mech->executionState->GetState() != Mech::ExecutionStateEngine::NeverExecuteState)?1:0;




	memory_stream->WriteBits( &local_mech_on, 1);


	memory_stream->WriteScaledFloatToBits(mech->yawDemand, -1.01f, 1.01f, BitDepthManager::BitDepth(UpdateType,RotationDemandUpdateEntryID));
	memory_stream->WriteScaledFloatToBits(mech->speedDemand, -1.01f, 1.01f, BitDepthManager::BitDepth(UpdateType,SpeedDemandUpdateEntryID));

#if 0
	memory_stream->WriteScaledFloatToBits(torso->pitchDemand, -1.0, 1.0, BitDepthManager::BitDepth(UpdateType,TorsoPichDemandUpdateEntryID));
	memory_stream->WriteScaledFloatToBits(torso->yawDemand, -1.0, 1.0, BitDepthManager::BitDepth(UpdateType,TorsoYawDemandUpdateEntryID));
#endif

	int mech_state = DrivingState;

	switch(mech->executionState->GetState())
	{
	case Mech::ExecutionStateEngine::DrivingMotionState:
		mech_state = DrivingState;
		break;
	case Mech::ExecutionStateEngine::FlyingMotionState:
		mech_state = JumpingState;
		break;
	case Mech::ExecutionStateEngine::FallingMotionState:
		mech_state = FallingState;
		break;

	}





	memory_stream->WriteBits( &mech_state, 2);

	switch (mech_state)
	{

	case DrivingState:
		{
			memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
			memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.y, -2005.0f, 1005.0f, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
			memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
			memory_stream->WriteScaledFloatToBits(mech_rotation_local_to_world.yaw, -Pi, Pi, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
			memory_stream->WriteScaledFloatToBits(mech->currentSpeedMPS, model->maxReverseSpeed, model->maxSpeed*1.25f, BitDepthManager::BitDepth(UpdateType,CurrentSpeedUpdateEntryID));
			
			bool shutdown = mech->IsShutdown();
			bool crouch = mech->IsCrouched();

			memory_stream->WriteBit(shutdown);
			memory_stream->WriteBit(crouch);

		}
		break;
	case JumpingState:
		memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
		memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.y, -2005.0f, 1005.0f, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
		memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
		memory_stream->WriteScaledFloatToBits(mech_rotation_local_to_world.yaw, -Pi, Pi, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
		
		memory_stream->WriteScaledFloatToBits(mech->localSpaceVelocity.linearMotion.x, -300.0f, 300.0f, BitDepthManager::BitDepth(UpdateType,CurrentXVelocityEntryID));
		memory_stream->WriteScaledFloatToBits(mech->localSpaceVelocity.linearMotion.y, -300.0f, 300.0f, BitDepthManager::BitDepth(UpdateType,CurrentYVelocityEntryID));
		memory_stream->WriteScaledFloatToBits(mech->localSpaceVelocity.linearMotion.z, -300.0f, 300.0f, BitDepthManager::BitDepth(UpdateType,CurrentZVelocityEntryID));
		break;

	case FallingState:
		memory_stream->WriteBits(&mech->fallDirection, 3);
		memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,XPositionUpdateEntryID));
		memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.y, -2005.0f, 1005.0f, BitDepthManager::BitDepth(UpdateType,YAboveTerrainUpdateEntryID));
		memory_stream->WriteScaledFloatToBits(mech_translation_local_to_world.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,ZPositionUpdateUpdateEntryID));
		memory_stream->WriteScaledFloatToBits(mech_rotation_local_to_world.yaw, -Pi, Pi, BitDepthManager::BitDepth(UpdateType,CurrentRotationUpdateEntryID));
		memory_stream->WriteScaledFloatToBits(mech->currentSpeedMPS, model->maxReverseSpeed, model->maxSpeed*1.25f, BitDepthManager::BitDepth(UpdateType,CurrentSpeedUpdateEntryID));
		
		break;

	}

	Sensor *sensor;
	bool sensor_on = true;

	sensor = mech->GetSensor();
	if(sensor)
	{
		
		switch (sensor->GetSensorMode ())
		{
			case Sensor::ActiveMode:
				sensor_on = true;
				break;
			case Sensor::PassiveMode:
				sensor_on = false;
				break;
			

		}
	}

	memory_stream->WriteBit(sensor_on);


	memory_stream->WriteScaledFloatToBits(torso->pitchValue, -torso_model->pitchRadius, torso_model->pitchRadius, BitDepthManager::BitDepth(UpdateType,CurrentTorsoPitchUpdateEntryID));
	memory_stream->WriteScaledFloatToBits(torso->yawValue, -torso_model->twistRadius, torso_model->twistRadius, BitDepthManager::BitDepth(UpdateType,CurrentTorsoYawUpdateEntryID));

// MSL 5.04 Back View Added
//	int look_direction = Torso::LookRightDirection;
	int look_direction = Torso::LookForwardDirection;
	
// MSL 5.04 Back View Added	
	switch (torso->lookDirection)
	{
	case Torso::LookLeftDirection:
		look_direction = torso->LookLeftDirection;
		break;
	case Torso::LookRightDirection:
		look_direction = torso->LookRightDirection;
		break;
	case Torso::LookBackDirection:
		look_direction = torso->LookBackDirection;
		break;
	case Torso::SurrenderDirection:
		look_direction = torso->SurrenderDirection;
		break;
	case Torso::LookForwardDirection:
		look_direction = torso->LookForwardDirection;
		break;
//	default:
//		look_direction = Torso::LookForwardDirection;
//		break;

	}


	memory_stream->WriteBits(&look_direction, 2);

	
	Network::GetInstance()->netStatCollector[Network::OutgoingMechMovementBitSizeStat].AddToStatistic(connection,memory_stream->GetCurrentBitCount() - current_bit);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

bool MechPositionUpdate::MaintainActiveFlagFunction(Entity *entity,Point3D cull_location)
{

	Point3D entity_location;
	entity_location = entity->GetLocalToWorld();

	Point3D distance;
	distance.Subtract(cull_location, entity_location);

	// if the mech is within 1200 meters and is on than it is active
	if (distance.GetLengthSquared() < 1440000.0f)
	{
	
		if (entity->executionState->GetState() != Entity::ExecutionStateEngine::NeverExecuteState)
		{
			return true;

		}
	}
	

	//SPEWALWAYS(("jerryeds","NOT ACTIVE???"));
	return false;
	
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void MechWarrior4::NetMovementSecurityCheckStop()
{
	_asm
	{
		nop
	}	
}


//##########################################################################
//###########################   MechAnimationUpdate
//##########################################################################

void MechAnimationUpdate::Decode(Entity *entity, MemoryStream *memory_stream, Time till, Scalar packet_latency, int connection, int debug_level, int bandwidth, Scalar rate)
{
	Check_Object(memory_stream);
	Check_Object(entity);
	


}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechAnimationUpdate::Skip(MemoryStream *memory_stream, int size, Time till, int connection, int debug_level, int bandwidth)
{
	Check_Object(memory_stream);
	//Check_Object(entity);
	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int MechAnimationUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{
	
	return 0;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechAnimationUpdate::Encode(Entity *entity, DynamicMemoryStream *memory_stream, int connection, int debug_level, int bandwidth)
{
	Check_Object(memory_stream);
	Check_Object(entity);

}


//##########################################################################
//###########################   MechMovementUpdate
//##########################################################################

void MechMovemntUpdate::Decode(Entity *entity, MemoryStream *memory_stream, Time till, Scalar packet_latency, int connection, int debug_level, int bandwidth, Scalar rate)
{

	
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechMovemntUpdate::Skip(MemoryStream *memory_stream, int size, Time till, int connection, int debug_level, int bandwidth)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int MechMovemntUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{
	
	return 0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechMovemntUpdate::Encode(Entity *entity, DynamicMemoryStream *memory_stream, int connection, int debug_level, int bandwidth)
{

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

bool MechMovemntUpdate::MaintainActiveFlagFunction(Entity *entity,Point3D cull_location)
{

	
	

	return false;
	
}

//##########################################################################
//###########################   MechFirstPersonMovementUpdate
//##########################################################################

