//===========================================================================//
// File:	NetSubsystems.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 "NetSubsystems.hpp"
#include "MWEntityManager.hpp"
#include "HeatManager.hpp"
#include "AMS.hpp"
#include "Adept\NetStatCollector.hpp"
#include "Mech.hpp"
#include "JumpJet.hpp"

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




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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	int current_bit = memory_stream->GetCurrentBitCount();

	Scalar heat_level = 0.0f;
	Scalar coolant_level = 0.0f;

	memory_stream->ReadBitsToScaledFloat(heat_level,0.0f, 1.0f,BitDepthManager::BitDepth(UpdateType,HeatEntryID));
	memory_stream->ReadBitsToScaledFloat(coolant_level,0.0f, 1.0f,BitDepthManager::BitDepth(UpdateType,CoolantEntryID));
	vehicle->m_heatManager->SetHeatPercentage(heat_level);
	vehicle->m_heatManager->SetCoolantPercentage(coolant_level);

	//SPEW(("jerryeds", "DECODE COOL : %f", coolant_level));

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


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MechInternalHeatUpdate::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 throw_away;
	memory_stream->ReadBits(&throw_away,BitDepthManager::BitDepth(UpdateType,HeatEntryID));
	memory_stream->ReadBits(&throw_away,BitDepthManager::BitDepth(UpdateType,CoolantEntryID));
	
	
	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,memory_stream->GetCurrentBitCount() - current_bit);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int MechInternalHeatUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{
	
	int current_bit = 0;

	current_bit += BitDepthManager::BitDepth(UpdateType,HeatEntryID);
	current_bit += BitDepthManager::BitDepth(UpdateType,CoolantEntryID);
	

	return current_bit;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

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

	int current_bit = memory_stream->GetCurrentBitCount();

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	Scalar heat_level;
	Scalar coolant_level;
	heat_level = vehicle->m_heatManager->GetHeatPercentage();
	coolant_level = vehicle->m_heatManager->GetCoolantPercentage();

	//SPEW(("jerryeds", "ENCODE COOL : %f", coolant_level));


	memory_stream->WriteScaledFloatToBits(heat_level,0.0f,1.0f,BitDepthManager::BitDepth(UpdateType,HeatEntryID));
	memory_stream->WriteScaledFloatToBits(coolant_level,0.0f,1.0f,BitDepthManager::BitDepth(UpdateType,CoolantEntryID));


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

}

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




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

	MWObject *vehicle = Cast_Object(MWObject*, entity);
	int current_bit = memory_stream->GetCurrentBitCount();


	ChainIteratorOf<Subsystem *> sub_iterator(&vehicle->subsystemsInVehicle);
	Subsystem *subsystem;

	
	while((subsystem = sub_iterator.ReadAndNext()) != NULL)
	{
	
		int alive = 0; // jcem: critical error - should clear before ReadBits(...)...
		memory_stream->ReadBits(&alive,1);
		if (!alive)
		{
			subsystem->executionState->RequestState(Subsystem::ExecutionStateEngine::DestroyedState);
		}
	}

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

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int SubsystemUpdate::SizeFunction(Entity *entity)
{
	Check_Object(entity);

	MWObject *vehicle = Cast_Object(MWObject*, entity);

	
	ChainIteratorOf<Subsystem *> sub_iterator(&vehicle->subsystemsInVehicle);
	Subsystem *subsystem;

	int size = 0;
	while((subsystem = sub_iterator.ReadAndNext()) != NULL)
	{
		++size;
	}


	
	return size;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int SubsystemUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{
	Check_Object(entity);

	MWObject *vehicle = Cast_Object(MWObject*, entity);

	ChainIteratorOf<Subsystem *> sub_iterator(&vehicle->subsystemsInVehicle);
	Subsystem *subsystem;

	int size = 0;
	while((subsystem = sub_iterator.ReadAndNext()) != NULL)
	{
		++size;
	}


	
	return size;
}


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

bool SubsystemUpdate::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)
	{
	
		Mech *mech = Cast_Object(Mech*, entity);

		if (mech->takenDamageThisFrame)
		{
			return true;

		}
	}
	

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void SubsystemUpdate::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();

	for (int i = 0; i < size; ++i)
	{
	
		int throw_away;
		memory_stream->ReadBits(&throw_away,1);
	
	}

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

	
}

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

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

	MWObject *vehicle = Cast_Object(MWObject*, entity);

	int current_bit = memory_stream->GetCurrentBitCount();

	
	ChainIteratorOf<Subsystem *> sub_iterator(&vehicle->subsystemsInVehicle);
	Subsystem *subsystem;

	
	while((subsystem = sub_iterator.ReadAndNext()) != NULL)
	{
		int alive = true;

		if (subsystem->executionState->GetState() == Subsystem::ExecutionStateEngine::DestroyedState)
			alive = false;

		memory_stream->WriteBits(&alive,1);

	}

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


}

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




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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	
	int cooling = 0;
	memory_stream->ReadBits(&cooling,1);

	vehicle->SetCooling(cooling);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}


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

	int throw_away;
	memory_stream->ReadBits(&throw_away,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

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


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

bool FlushUpdate::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;

		}
	}
	

	return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;

	int cooling = vehicle->m_heatManager->IsCooling();

	memory_stream->WriteBits(&cooling,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}





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




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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	int light_on = 0;
	memory_stream->ReadBits(&light_on,1);

	int local_state = vehicle->IsSearchLightOn();
	if (light_on != local_state)
	{
		if (light_on)
		{
			vehicle->TurnOnSearchLight();
		}
		else
		{
			vehicle->TurnOffSearchLight();
		}
	}

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}


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

	
	int throw_away;
	memory_stream->ReadBits(&throw_away,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int SearchLightUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{

	return 1;
}

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

bool SearchLightUpdate::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;

		}
	}
	

	return false;
}

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

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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	int light_on = vehicle->IsSearchLightOn();

	memory_stream->WriteBits(&light_on,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}



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




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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	int ams_ammo = 0;

	AMS *ams = vehicle->GetAMS();


	if (ams != NULL && ams->GetMaxAmmoCount() != 0 && ams->GetMaxAmmoCount() != -1)
	{
		memory_stream->ReadBitsToScaledInt(ams_ammo,0, ams->GetMaxAmmoCount()+1,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));
		ams->SetAmmo(ams_ammo);
	}
	else
	{
		int throw_away;
		memory_stream->ReadBits(&throw_away,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));
	}

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));

}


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

	
	int throw_away;
	memory_stream->ReadBits(&throw_away,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));


	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int InternalAMSAmmoUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{

	int current_bit = 0;

	current_bit += BitDepthManager::BitDepth(UpdateType,AmmoEntryID);
	

	return current_bit;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	int ams_ammo = 0;

	AMS *ams = vehicle->GetAMS();
	if (ams != NULL && ams->GetMaxAmmoCount() != 0 && ams->GetMaxAmmoCount() != -1)
	{
		ams_ammo = ams->GetAmmo();
		memory_stream->WriteScaledIntToBits(ams_ammo, 0, ams->GetMaxAmmoCount()+1,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));
	}
	else
	{
		int throw_away = 0;
		memory_stream->WriteBits(&throw_away,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));
	}

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,BitDepthManager::BitDepth(UpdateType,AmmoEntryID));

}



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




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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	int has_ammo = 0;
	memory_stream->ReadBits(&has_ammo,1);

	AMS *ams = vehicle->GetAMS();


	if (ams != NULL && ams->maxAmmoCount != -1)
	{
		if (has_ammo)
			ams->SetAmmo(ams->GetMaxAmmoCount());
		else
			ams->SetAmmo(0);
	}

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);


}


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

	
	int throw_away;
	memory_stream->ReadBits(&throw_away,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int ExternalAMSAmmoUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{
	

	return 1;
}

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

bool ExternalAMSAmmoUpdate::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;

		}
	}
	

	return false;
}

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

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

	MWObject *vehicle = Cast_Object(MWObject*, entity);;
	Check_Object(vehicle->m_heatManager);

	AMS *ams = vehicle->GetAMS();

	int has_ammo = 0;
	if (ams != NULL)
	{
		has_ammo = ams->DoesHaveAmmo();
	}

	memory_stream->WriteBits(&has_ammo,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

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

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


	int jump_on = 0;
	memory_stream->ReadBits(&jump_on,1);

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

	if (jump_on)
	{
		JumpJet *jet = mech->GetJumpJet();
		if (jet != NULL)
		{
// MSL 5.03 Merc Fix
			if (jet->GetReplicatorMode() == JumpJet::ReplicantMode)
			{
				jet->SetCurrentCharge(jet->GetMaxCharge());			
			}

			jet->RequestJumpJetsOn();
		}
	}
	else
	{
		JumpJet *jet = mech->GetJumpJet();
		if (jet != NULL)
		{
			jet->RequestJumpJetsOff();
		}
		
	}


	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}


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

	
	int throw_away;
	memory_stream->ReadBits(&throw_away,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int ExternalJumpJetUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{	

	return 1;
}


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

bool ExternalJumpJetUpdate::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;

		}
	}
	

	return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

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

	
	Mech *mech = Cast_Object(Mech*, entity);
	
	int jump_on = 0;
	
	JumpJet *jet = mech->GetJumpJet();
	if (jet != NULL)
	{
		if (jet->executionState->GetState() == JumpJet::ExecutionStateEngine::JumpingState)
		{
			jump_on = 1;
		}

	}

	memory_stream->WriteBits(&jump_on,1);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

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

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

	



	Scalar max_charge = 1.0f;
	Scalar current_charge;

	Mech *mech = Cast_Object(Mech*, entity);
	JumpJet *jet = mech->GetJumpJet();

	if (jet != NULL)
	{
		max_charge = jet->GetMaxCharge();
	}

	memory_stream->ReadBitsToScaledFloat(current_charge, 0.0f, max_charge, 4);


	if (jet != NULL)
	{
		// if the server charge is greater than the client charge only
		// increase the client if the client isn't jumping!  
		// The client can only get more fuel when he isn't jumping!
		if (current_charge > jet->CurrentCharge() && jet->executionState->GetState() != JumpJet::ExecutionStateEngine::JumpingState)
		{
			jet->SetCurrentCharge(current_charge);
		}

		//SPEWALWAYS(("jerryeds", "DECODE JUMP - %f", current_charge));

	}


	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

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

	
	int throw_away;
	
	memory_stream->ReadBits(&throw_away,4);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int InternalJumpJetUpdate::MaxSize(Entity *entity, int debug_level, int bandwidth)
{

	return 4;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

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

	Mech *mech = Cast_Object(Mech*, entity);
	
	Scalar max_charge = 1.0f;
	Scalar current_charge = 0.0f;
	
	JumpJet *jet = mech->GetJumpJet();

	if (jet != NULL)
	{
		current_charge = jet->CurrentCharge();
		max_charge = jet->GetMaxCharge();

		//SPEW(("jerryeds", "ENCODE JUMP - %f", current_charge));
	}

	memory_stream->WriteScaledFloatToBits(current_charge, 0.0f, max_charge, 4);

	Network::GetInstance()->netStatCollector[Network::MechInternalBitSizeStat].AddToStatistic(connection,1);

}

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