//===========================================================================//
// File:	NetWeapon.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 "NetWeapon.hpp"
#include "MWEntityManager.hpp"
#include "SubsystemClassData.hpp"

#include "Weapon.hpp"
#include "MissileWeapon.hpp"
// MSL 5.03 RTX
//#include "rtxweaponsub.hpp"
#include "Mech.hpp"
#include <Adept\Map.hpp>

#include <Adept\CollisionVolume.hpp>

Stuff::MemoryBlock*
	WeaponUpdate::AllocatedMemory = NULL;

void WeaponUpdate::InitializeClass()
{
	Verify(!AllocatedMemory);
	AllocatedMemory =
		new Stuff::MemoryBlock(
			sizeof(WeaponUpdate),
			10,
			2,
			"WeaponUpdates"
		);
	Register_Object(AllocatedMemory);
}

void WeaponUpdate::TerminateClass()
{
	Unregister_Object(AllocatedMemory);
	delete AllocatedMemory;
	AllocatedMemory = NULL;
}



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


//##########################################################################
//###########################   FirstPersonWeaponCommand
//##########################################################################

#define DEFAULT_RANGE	15.f
#define VEHICLE_RANGE	5.f
#define MECH_RANGE		5.f

void WeaponCommand::SpecialDecode(int connection, int type, WeaponUpdate &weapon_command, MemoryStream *memory_stream)
{

//	SPEW(("jerryeds", "REC-FIRE"));

	weapon_command.obsolete = false;
	memory_stream->ReadBits(&weapon_command.weaponFired, 32);
	memory_stream->ReadBits(&weapon_command.lockTime, 32);

	switch(type)
	{
		case MWEntityManager::FirstPersonWeaponToMechCommandMessageID:
			{
				// originator connection id is derived from packet header
				// target id is the full entity id
				// offset is default

		
				if (((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection] != NULL)
				{

					Check_Object(((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection]);

					weapon_command.originator.Add(((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection]);

					BYTE connection_id;
					WORD local_id;

					memory_stream->ReadBits(&connection_id, 8);
					memory_stream->ReadBits(&local_id, 16);

					ReplicatorID repid(connection_id, local_id);

					Connection	*connection = Network::GetInstance()->GetConnection(connection_id);
					if (connection != NULL)
					{
						Check_Object(connection);
						
						Entity *target = (Entity *) connection->FindReplicator(repid);
						if (target != NULL)
						{
							Check_Object(target);
							weapon_command.target.Add(target);

							Entity* parent_target = target;
							int class_id = parent_target->GetClassID();
							if (class_id == MWMoverClassID)
							{
								MWMover* mover = Cast_Object(MWMover*, parent_target);
								parent_target = mover->GetParentVehicle();
							}

							Scalar sphere_radiusMaxX = 0.f;
							Scalar sphere_radiusMaxY = 0.f;
							Scalar sphere_radiusMaxZ = 0.f;
							Scalar sphere_radiusMinX = 0.f;
							Scalar sphere_radiusMinY = 0.f;
							Scalar sphere_radiusMinZ = 0.f;
							class_id = parent_target->GetClassID();
							switch (class_id)
							{
							case MechClassID:
								{
									sphere_radiusMaxX = MECH_RANGE;
									sphere_radiusMaxY = MECH_RANGE;
									sphere_radiusMaxZ = MECH_RANGE;
									sphere_radiusMinX = -MECH_RANGE;
									sphere_radiusMinY = -MECH_RANGE;
									sphere_radiusMinZ = -MECH_RANGE;
								}
								break;
							case BuildingClassID:
							case TurretClassID:
							case BridgeClassID:
							case MFBClassID:
							case FieldBaseClassID:
							case DropshipClassID:
								{
									CollisionVolume *solid = parent_target->GetSolidVolume();
									if (solid)
									{
										Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
										sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
										sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
										sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
										sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
										sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
										sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
									}
									else
									{
										sphere_radiusMaxX = DEFAULT_RANGE;
										sphere_radiusMaxY = DEFAULT_RANGE;
										sphere_radiusMaxZ = DEFAULT_RANGE;
										sphere_radiusMinX = -DEFAULT_RANGE;
										sphere_radiusMinY = -DEFAULT_RANGE;
										sphere_radiusMinZ = -DEFAULT_RANGE;
									}
								}
								break;
							case VehicleClassID:
								{
									sphere_radiusMaxX = VEHICLE_RANGE;
									sphere_radiusMaxY = VEHICLE_RANGE;
									sphere_radiusMaxZ = VEHICLE_RANGE;
									sphere_radiusMinX = -VEHICLE_RANGE;
									sphere_radiusMinY = -VEHICLE_RANGE;
									sphere_radiusMinZ = -VEHICLE_RANGE;
								}
								break;
							default:
								{
									sphere_radiusMaxX = DEFAULT_RANGE;
									sphere_radiusMaxY = DEFAULT_RANGE;
									sphere_radiusMaxZ = DEFAULT_RANGE;
									sphere_radiusMinX = -DEFAULT_RANGE;
									sphere_radiusMinY = -DEFAULT_RANGE;
									sphere_radiusMinZ = -DEFAULT_RANGE;
								}
								break;
							}				

							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));
			
//							SPEWALWAYS(("jackyc", "First Person To Mech Read - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));		

						}
						else
						{
							weapon_command.obsolete = true;
						}
					}
					else
					{
						weapon_command.obsolete = true;
					}
				}
				else
				{
					weapon_command.obsolete = true;
				}

			}
			break;

		case MWEntityManager::ThirdPersonWeaponToMechCommandMessageID:
			// originator id is in the packet
			// target id is the full entity id
			// offset is default
			{

				BYTE originator_id;
				memory_stream->ReadBits(&originator_id, 8);

				Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[originator_id];
			
				if(originator != NULL)
				{
				
					weapon_command.originator.Add(originator);
					Check_Object(originator);

					BYTE connection_id;
					WORD local_id;

					memory_stream->ReadBits(&connection_id, 8);
					memory_stream->ReadBits(&local_id, 16);

					ReplicatorID repid(connection_id, local_id);

					Connection	*connection = Network::GetInstance()->GetConnection(connection_id);

					if (connection != NULL)
					{
						Check_Object(connection);
						Entity *target = (Entity *) connection->FindReplicator(repid);

						
						if (target != NULL)
						{
							weapon_command.target.Add(target);
							Check_Object(target);
							
							Entity* parent_target = target;
							int class_id = parent_target->GetClassID();
							if (class_id == MWMoverClassID)
							{
								MWMover* mover = Cast_Object(MWMover*, parent_target);
								parent_target = mover->GetParentVehicle();
							}

							Scalar sphere_radiusMaxX = 0.f;
							Scalar sphere_radiusMaxY = 0.f;
							Scalar sphere_radiusMaxZ = 0.f;
							Scalar sphere_radiusMinX = 0.f;
							Scalar sphere_radiusMinY = 0.f;
							Scalar sphere_radiusMinZ = 0.f;
							class_id = parent_target->GetClassID();
							switch (class_id)
							{
							case MechClassID:
								{
									sphere_radiusMaxX = MECH_RANGE;
									sphere_radiusMaxY = MECH_RANGE;
									sphere_radiusMaxZ = MECH_RANGE;
									sphere_radiusMinX = -MECH_RANGE;
									sphere_radiusMinY = -MECH_RANGE;
									sphere_radiusMinZ = -MECH_RANGE;
								}
								break;
							case BuildingClassID:
							case TurretClassID:
							case BridgeClassID:
							case MFBClassID:
							case FieldBaseClassID:
							case DropshipClassID:
								{
									CollisionVolume *solid = parent_target->GetSolidVolume();
									if (solid)
									{
										Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
										sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
										sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
										sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
										sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
										sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
										sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
									}
									else
									{
										sphere_radiusMaxX = DEFAULT_RANGE;
										sphere_radiusMaxY = DEFAULT_RANGE;
										sphere_radiusMaxZ = DEFAULT_RANGE;
										sphere_radiusMinX = -DEFAULT_RANGE;
										sphere_radiusMinY = -DEFAULT_RANGE;
										sphere_radiusMinZ = -DEFAULT_RANGE;
									}
								}
								break;
							case VehicleClassID:
								{
									sphere_radiusMaxX = VEHICLE_RANGE;
									sphere_radiusMaxY = VEHICLE_RANGE;
									sphere_radiusMaxZ = VEHICLE_RANGE;
									sphere_radiusMinX = -VEHICLE_RANGE;
									sphere_radiusMinY = -VEHICLE_RANGE;
									sphere_radiusMinZ = -VEHICLE_RANGE;
								}
								break;
							default:
								{
									sphere_radiusMaxX = DEFAULT_RANGE;
									sphere_radiusMaxY = DEFAULT_RANGE;
									sphere_radiusMaxZ = DEFAULT_RANGE;
									sphere_radiusMinX = -DEFAULT_RANGE;
									sphere_radiusMinY = -DEFAULT_RANGE;
									sphere_radiusMinZ = -DEFAULT_RANGE;
								}
								break;
							}				

							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));		
					
//							SPEWALWAYS(("jackyc", "Third Person To Mech Read - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));			

							//SPEW(("jerryeds", "CLIENT SAW : %d: HIT : %d:%d - %f:%f:%f", originator_id, connection_id, local_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

							//SPEW(("jerryeds", "CLIENT SAW: %s : <%f:%f:%f>", (const char *)weapon_command.target->instanceName, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

						
						}
						else
						{
							weapon_command.obsolete = true;
						}
					}
					else
					{
						weapon_command.obsolete = true;
					}
				}
				else
				{
					weapon_command.obsolete = true;
				}
			}
			break;

		case MWEntityManager::AIWeaponCommandToMechtMessageID:
			// originator connection id is server and local is in packet
			// target id is the full entity id
			// offset is default

			{

				
				WORD local_id;
				memory_stream->ReadBits(&local_id, 16);

				ReplicatorID repid(Connection::Server->GetID(), local_id);
				Entity *originator = (Entity *) Connection::Server->FindReplicator(repid);

				
				if(originator != NULL)
				{
					Check_Object(originator);
					weapon_command.originator.Add(originator);

					BYTE connection_id;

					memory_stream->ReadBits(&connection_id, 8);
					memory_stream->ReadBits(&local_id, 16);

					ReplicatorID repid(connection_id, local_id);

					Connection	*connection = Network::GetInstance()->GetConnection(connection_id);
					if (connection != NULL)
					{
						Check_Object(connection);
						Entity *target = (Entity *) connection->FindReplicator(repid);

						
						if (target != NULL)
						{

							Check_Object(target);
							weapon_command.target.Add(target);

							Entity* parent_target = target;
							int class_id = parent_target->GetClassID();
							if (class_id == MWMoverClassID)
							{
								MWMover* mover = Cast_Object(MWMover*, parent_target);
								parent_target = mover->GetParentVehicle();
							}

							Scalar sphere_radiusMaxX = 0.f;
							Scalar sphere_radiusMaxY = 0.f;
							Scalar sphere_radiusMaxZ = 0.f;
							Scalar sphere_radiusMinX = 0.f;
							Scalar sphere_radiusMinY = 0.f;
							Scalar sphere_radiusMinZ = 0.f;
							class_id = parent_target->GetClassID();
							switch (class_id)
							{
							case MechClassID:
								{
									sphere_radiusMaxX = MECH_RANGE;
									sphere_radiusMaxY = MECH_RANGE;
									sphere_radiusMaxZ = MECH_RANGE;
									sphere_radiusMinX = -MECH_RANGE;
									sphere_radiusMinY = -MECH_RANGE;
									sphere_radiusMinZ = -MECH_RANGE;
								}
								break;
							case BuildingClassID:
							case TurretClassID:
							case BridgeClassID:
							case MFBClassID:
							case FieldBaseClassID:
							case DropshipClassID:
								{
									CollisionVolume *solid = parent_target->GetSolidVolume();
									if (solid)
									{
										Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
										sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
										sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
										sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
										sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
										sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
										sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
									}
									else
									{
										sphere_radiusMaxX = DEFAULT_RANGE;
										sphere_radiusMaxY = DEFAULT_RANGE;
										sphere_radiusMaxZ = DEFAULT_RANGE;
										sphere_radiusMinX = -DEFAULT_RANGE;
										sphere_radiusMinY = -DEFAULT_RANGE;
										sphere_radiusMinZ = -DEFAULT_RANGE;
									}
								}
								break;
							case VehicleClassID:
								{
									sphere_radiusMaxX = VEHICLE_RANGE;
									sphere_radiusMaxY = VEHICLE_RANGE;
									sphere_radiusMaxZ = VEHICLE_RANGE;
									sphere_radiusMinX = -VEHICLE_RANGE;
									sphere_radiusMinY = -VEHICLE_RANGE;
									sphere_radiusMinZ = -VEHICLE_RANGE;
								}
								break;
							default:
								{
									sphere_radiusMaxX = DEFAULT_RANGE;
									sphere_radiusMaxY = DEFAULT_RANGE;
									sphere_radiusMaxZ = DEFAULT_RANGE;
									sphere_radiusMinX = -DEFAULT_RANGE;
									sphere_radiusMinY = -DEFAULT_RANGE;
									sphere_radiusMinZ = -DEFAULT_RANGE;
								}
								break;
							}				

							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
							memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));			
						}
						else
						{
							weapon_command.obsolete = true;
						}
					}
					else
					{
						weapon_command.obsolete = true;
					}
				}
				else
				{
					weapon_command.obsolete = true;
				}
			}
			break;


		case MWEntityManager::FirstPersonWeaponToGroundCommandMessageID:
			// originator connection id is derived from packet header
			// target id is the ground
			// offset is larger
			{
				Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection];

				if (originator != NULL)
				{

					weapon_command.originator.Add(originator);
					Check_Object(originator);

					Check_Object(Map::GetInstance());
					weapon_command.target.Add( Map::GetInstance() );

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

					memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID));
					memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID));

					// find the y component

					Check_Object(MWEntityManager::GetInstance());
					weapon_command.targetOffset.y = ((MWEntityManager*)MWEntityManager::GetInstance())->FindGroundHeight(weapon_command.targetOffset.x, weapon_command.targetOffset.z);



					//SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));


				}
				else
				{
					weapon_command.obsolete = true;
				}
			

			}
			break;

		case MWEntityManager::ThirdPersonWeaponToGroundCommandMessageID:
			// originator id is in the packet
			// target id is the ground
			// offset is larger
			{
				BYTE connection_id;
				memory_stream->ReadBits(&connection_id, 8);

				Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection_id];

				if (originator != NULL)
				{

					weapon_command.originator.Add(originator);
					Check_Object(originator);

					Check_Object(Map::GetInstance());
					weapon_command.target.Add( Map::GetInstance() );

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

					memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID));
					memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID));

					// find the y component

					Check_Object(MWEntityManager::GetInstance());
					weapon_command.targetOffset.y = ((MWEntityManager*)MWEntityManager::GetInstance())->FindGroundHeight(weapon_command.targetOffset.x, weapon_command.targetOffset.z);

					//SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));


				}
				else
				{
					weapon_command.obsolete = true;
				}
			}
			break;

		case MWEntityManager::AIWeaponCommandToGroundtMessageID:
			// originator connection id is server and local is in packet
			// target id is the ground
			// offset is larger
			{
				WORD local_id;
				memory_stream->ReadBits(&local_id, 16);

				ReplicatorID repid(Connection::Server->GetID(), local_id);
				Entity *originator = (Entity *) Connection::Server->FindReplicator(repid);

				if (originator != NULL)
				{
				
					Check_Object(originator);
					weapon_command.originator.Add(originator);

					Check_Object(Map::GetInstance());
					weapon_command.target.Add(Map::GetInstance());

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

					memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID));
					memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID));

					// find the y component

					Check_Object(MWEntityManager::GetInstance());
					weapon_command.targetOffset.y = ((MWEntityManager*)MWEntityManager::GetInstance())->FindGroundHeight(weapon_command.targetOffset.x, weapon_command.targetOffset.z);

				}
				else
				{
					weapon_command.obsolete = true;
				}
			
			}
			break;
			

		case MWEntityManager::FirstPersonWeaponToServerObjectCommandMessageID:
			// originator connection id is derived from packet header
			// target local id is in the packet - connection is server
			// offset is default
			{
				Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection];

				if (originator != NULL)
				{

					weapon_command.originator.Add(originator);

					WORD local_id;
					memory_stream->ReadBits(&local_id, 16);

					ReplicatorID repid(Connection::Server->GetID(), local_id);
					Entity *target = (Entity *) Connection::Server->FindReplicator(repid);

					if (target != NULL)
					{
				
						weapon_command.target.Add(target);

						Entity* parent_target = target;
						int class_id = parent_target->GetClassID();
						if (class_id == MWMoverClassID)
						{
							MWMover* mover = Cast_Object(MWMover*, parent_target);
							parent_target = mover->GetParentVehicle();
						}
						
						Scalar sphere_radiusMaxX = 0.f;
						Scalar sphere_radiusMaxY = 0.f;
						Scalar sphere_radiusMaxZ = 0.f;
						Scalar sphere_radiusMinX = 0.f;
						Scalar sphere_radiusMinY = 0.f;
						Scalar sphere_radiusMinZ = 0.f;
						class_id = parent_target->GetClassID();
						switch (class_id)
						{
						case MechClassID:
							{
								sphere_radiusMaxX = MECH_RANGE;
								sphere_radiusMaxY = MECH_RANGE;
								sphere_radiusMaxZ = MECH_RANGE;
								sphere_radiusMinX = -MECH_RANGE;
								sphere_radiusMinY = -MECH_RANGE;
								sphere_radiusMinZ = -MECH_RANGE;
							}
							break;
						case BuildingClassID:
						case TurretClassID:
						case BridgeClassID:
						case MFBClassID:
						case FieldBaseClassID:
						case DropshipClassID:
							{
								CollisionVolume *solid = parent_target->GetSolidVolume();
								if (solid)
								{
									Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
									sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
									sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
									sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
									sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
									sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
									sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
								}
								else
								{
									sphere_radiusMaxX = DEFAULT_RANGE;
									sphere_radiusMaxY = DEFAULT_RANGE;
									sphere_radiusMaxZ = DEFAULT_RANGE;
									sphere_radiusMinX = -DEFAULT_RANGE;
									sphere_radiusMinY = -DEFAULT_RANGE;
									sphere_radiusMinZ = -DEFAULT_RANGE;
								}
							}
							break;
						case VehicleClassID:
							{
								sphere_radiusMaxX = VEHICLE_RANGE;
								sphere_radiusMaxY = VEHICLE_RANGE;
								sphere_radiusMaxZ = VEHICLE_RANGE;
								sphere_radiusMinX = -VEHICLE_RANGE;
								sphere_radiusMinY = -VEHICLE_RANGE;
								sphere_radiusMinZ = -VEHICLE_RANGE;
							}
							break;
						default:
							{
								sphere_radiusMaxX = DEFAULT_RANGE;
								sphere_radiusMaxY = DEFAULT_RANGE;
								sphere_radiusMaxZ = DEFAULT_RANGE;
								sphere_radiusMinX = -DEFAULT_RANGE;
								sphere_radiusMinY = -DEFAULT_RANGE;
								sphere_radiusMinZ = -DEFAULT_RANGE;
							}
							break;
						}				
						
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));
											
//						SPEWALWAYS(("jackyc", "First Person To Server Receive - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

					}
					else
					{
						weapon_command.obsolete = true;
					}
				}
				else
				{
					weapon_command.obsolete = true;
				}

			}
			break;

		case MWEntityManager::ThirdPersonWeaponToServerObjectCommandMessageID:
			// originator id is in the packet
			// target local id is in the packet - connection is server
			// offset is default
			{
				BYTE connection_id;
				memory_stream->ReadBits(&connection_id, 8);

				Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection_id];


				if (originator != NULL)
				{

					weapon_command.originator.Add(originator);

					WORD local_id;
					memory_stream->ReadBits(&local_id, 16);

					ReplicatorID repid(Connection::Server->GetID(), local_id);
					Entity *target = (Entity *) Connection::Server->FindReplicator(repid);


					if (target != NULL)
					{
						weapon_command.target.Add(target);
				
						Entity* parent_target = target;
						int class_id = parent_target->GetClassID();
						if (class_id == MWMoverClassID)
						{
							MWMover* mover = Cast_Object(MWMover*, parent_target);
							parent_target = mover->GetParentVehicle();
						}
						
						Scalar sphere_radiusMaxX = 0.f;
						Scalar sphere_radiusMaxY = 0.f;
						Scalar sphere_radiusMaxZ = 0.f;
						Scalar sphere_radiusMinX = 0.f;
						Scalar sphere_radiusMinY = 0.f;
						Scalar sphere_radiusMinZ = 0.f;
						class_id = parent_target->GetClassID();
						switch (class_id)
						{
						case MechClassID:
							{
								sphere_radiusMaxX = MECH_RANGE;
								sphere_radiusMaxY = MECH_RANGE;
								sphere_radiusMaxZ = MECH_RANGE;
								sphere_radiusMinX = -MECH_RANGE;
								sphere_radiusMinY = -MECH_RANGE;
								sphere_radiusMinZ = -MECH_RANGE;
							}
							break;
						case BuildingClassID:
						case TurretClassID:
						case BridgeClassID:
						case MFBClassID:
						case FieldBaseClassID:
						case DropshipClassID:
							{
								CollisionVolume *solid = parent_target->GetSolidVolume();
								if (solid)
								{
									Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
									sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
									sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
									sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
									sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
									sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
									sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
								}
								else
								{
									sphere_radiusMaxX = DEFAULT_RANGE;
									sphere_radiusMaxY = DEFAULT_RANGE;
									sphere_radiusMaxZ = DEFAULT_RANGE;
									sphere_radiusMinX = -DEFAULT_RANGE;
									sphere_radiusMinY = -DEFAULT_RANGE;
									sphere_radiusMinZ = -DEFAULT_RANGE;
								}
							}
							break;
						case VehicleClassID:
							{
								sphere_radiusMaxX = VEHICLE_RANGE;
								sphere_radiusMaxY = VEHICLE_RANGE;
								sphere_radiusMaxZ = VEHICLE_RANGE;
								sphere_radiusMinX = -VEHICLE_RANGE;
								sphere_radiusMinY = -VEHICLE_RANGE;
								sphere_radiusMinZ = -VEHICLE_RANGE;
							}
							break;
						default:
							{
								sphere_radiusMaxX = DEFAULT_RANGE;
								sphere_radiusMaxY = DEFAULT_RANGE;
								sphere_radiusMaxZ = DEFAULT_RANGE;
								sphere_radiusMinX = -DEFAULT_RANGE;
								sphere_radiusMinY = -DEFAULT_RANGE;
								sphere_radiusMinZ = -DEFAULT_RANGE;
							}
							break;
						}				
						
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));
																					
//						SPEWALWAYS(("jackyc", "Third Person To Server Receive - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

					}
					else
					{
						weapon_command.obsolete = true;
					}
				}
				else
				{
					weapon_command.obsolete = true;
				}
			}
			break;

		case MWEntityManager::AIWeaponCommandToServerObjectMessageID:
			// originator connection id is server and local is in packet
			// target local id is in the packet - connection is server
			// offset is default
			{
				WORD local_id;
				memory_stream->ReadBits(&local_id, 16);

				ReplicatorID repid(Connection::Server->GetID(), local_id);
				Entity *originator = (Entity *) Connection::Server->FindReplicator(repid);


				if (originator != NULL)
				{

					weapon_command.originator.Add(originator);

					WORD local_id;
					memory_stream->ReadBits(&local_id, 16);

					ReplicatorID repid(Connection::Server->GetID(), local_id);
					Entity *target = (Entity *) Connection::Server->FindReplicator(repid);

					if (target != NULL)
					{
				
						weapon_command.target.Add(target);

						Entity* parent_target = target;
						int class_id = parent_target->GetClassID();
						if (class_id == MWMoverClassID)
						{
							MWMover* mover = Cast_Object(MWMover*, parent_target);
							parent_target = mover->GetParentVehicle();
						}
						
						Scalar sphere_radiusMaxX = 0.f;
						Scalar sphere_radiusMaxY = 0.f;
						Scalar sphere_radiusMaxZ = 0.f;
						Scalar sphere_radiusMinX = 0.f;
						Scalar sphere_radiusMinY = 0.f;
						Scalar sphere_radiusMinZ = 0.f;
						class_id = parent_target->GetClassID();
						switch (class_id)
						{
						case MechClassID:
							{
								sphere_radiusMaxX = MECH_RANGE;
								sphere_radiusMaxY = MECH_RANGE;
								sphere_radiusMaxZ = MECH_RANGE;
								sphere_radiusMinX = -MECH_RANGE;
								sphere_radiusMinY = -MECH_RANGE;
								sphere_radiusMinZ = -MECH_RANGE;
							}
							break;
						case BuildingClassID:
						case TurretClassID:
						case BridgeClassID:
						case MFBClassID:
						case FieldBaseClassID:
						case DropshipClassID:
							{
								CollisionVolume *solid = parent_target->GetSolidVolume();
								if (solid)
								{
									Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
									sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
									sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
									sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
									sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
									sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
									sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
								}
								else
								{
									sphere_radiusMaxX = DEFAULT_RANGE;
									sphere_radiusMaxY = DEFAULT_RANGE;
									sphere_radiusMaxZ = DEFAULT_RANGE;
									sphere_radiusMinX = -DEFAULT_RANGE;
									sphere_radiusMinY = -DEFAULT_RANGE;
									sphere_radiusMinZ = -DEFAULT_RANGE;
								}
							}
							break;
						case VehicleClassID:
							{
								sphere_radiusMaxX = VEHICLE_RANGE;
								sphere_radiusMaxY = VEHICLE_RANGE;
								sphere_radiusMaxZ = VEHICLE_RANGE;
								sphere_radiusMinX = -VEHICLE_RANGE;
								sphere_radiusMinY = -VEHICLE_RANGE;
								sphere_radiusMinZ = -VEHICLE_RANGE;
							}
							break;
						default:
							{
								sphere_radiusMaxX = DEFAULT_RANGE;
								sphere_radiusMaxY = DEFAULT_RANGE;
								sphere_radiusMaxZ = DEFAULT_RANGE;
								sphere_radiusMinX = -DEFAULT_RANGE;
								sphere_radiusMinY = -DEFAULT_RANGE;
								sphere_radiusMinZ = -DEFAULT_RANGE;
							}
							break;
						}				
						
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
						memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));																
					}
					else
					{
						weapon_command.obsolete = true;
					}
				}
				else
				{
					weapon_command.obsolete = true;
				}
			}
			break;

		case MWEntityManager::FirstPersonWeaponNoTargetCommandMessageID:
			// originator connection id is derived from packet header
			// no target no offset just shoot
			{
				if (MWEntityManager::GetInstance()->playerVehicle[connection] != NULL)
					weapon_command.originator.Add(MWEntityManager::GetInstance()->playerVehicle[connection]);
				weapon_command.target.Remove();
				weapon_command.targetOffset = Point3D::Identity;


				Check_Object(weapon_command.originator.GetCurrent());

				Check_Object(Map::GetInstance());
				weapon_command.target.Add( Map::GetInstance() );

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

				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID));
				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID));
				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID));
				

				if (weapon_command.originator.GetCurrent() == NULL)
				{
					weapon_command.obsolete = true;
				}
			}
			break;

		case MWEntityManager::ThirdPersonWeaponNoTargetCommandMessageID:
			// originator id is in the packet
			// no target no offset just shoot
			{
				BYTE connection_id;
				memory_stream->ReadBits(&connection_id, 8);

				if (MWEntityManager::GetInstance()->playerVehicle[connection_id] != NULL)
					weapon_command.originator.Add(MWEntityManager::GetInstance()->playerVehicle[connection_id]);
				weapon_command.target.Remove();
				weapon_command.targetOffset = Point3D::Identity;

				Check_Object(weapon_command.originator.GetCurrent());

				Check_Object(Map::GetInstance());
				weapon_command.target.Add( Map::GetInstance() );

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

				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID));
				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID));
				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID));
				
//				SPEWALWAYS(("jackyc", "Third Person No Target Receive - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

				if (weapon_command.originator.GetCurrent() == NULL)
				{
					weapon_command.obsolete = true;
				}

			}
			break;

		case MWEntityManager::AIWeaponCommandToNoTargetMessageID:
			// originator connection id is server and local is in packet
			// no target no offset just shoot
			{
				WORD local_id;
				memory_stream->ReadBits(&local_id, 16);

				ReplicatorID repid(Connection::Server->GetID(), local_id);
				Entity *originator = (Entity *) Connection::Server->FindReplicator(repid);
				if (originator != NULL)
					weapon_command.originator.Add(originator);

				weapon_command.target.Remove();
				weapon_command.targetOffset = Point3D::Identity;

				Check_Object(weapon_command.originator.GetCurrent());

				Check_Object(Map::GetInstance());
				weapon_command.target.Add(Map::GetInstance());

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

				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID));
				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID));
				memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID));

				if (weapon_command.originator.GetCurrent() == NULL)
				{
					weapon_command.obsolete = true;
				}

			}
			break;
	}


	if (!weapon_command.obsolete)
	{
		Vehicle *vehicle = Cast_Object(Vehicle *, weapon_command.originator.GetCurrent());


		if (weapon_command.target.GetCurrent() != NULL)
		{
			Stuff::ChainIteratorOf<Weapon*> iterator(&vehicle->weaponChain);
			Weapon *weapon;
			
			while ((weapon = iterator.ReadAndNext()) != NULL)
			{
				int id = weapon->GetWeaponID();
				if (weapon_command.weaponFired & (0x1 << id))
				{
					if (weapon->IsDerivedFrom(MissileWeapon::DefaultData))
					{
						MissileWeapon *missile_weapon;
						missile_weapon = Cast_Object(MissileWeapon *, weapon);

						if (missile_weapon->IsAMSValid(weapon_command.target.GetCurrent()))
						{
							//write the target number...
                            weapon_command.AntiWeaponCount[id] = 0; // may not error, but ... jcem: critical error - should clear before ReadBits(...)...
							memory_stream->ReadBits(&weapon_command.AntiWeaponCount[id], 3);
						}
						else
						{
							weapon_command.AntiWeaponCount[id] = 0;
						}
					}
				}
			}
		}
	}


}





//##########################################################################
//###########################   FirstPersonWeaponCommand
//##########################################################################

void WeaponCommand::SpecialEncode(int connection, int type, WeaponUpdate &weapon_command, DynamicMemoryStream *memory_stream)
{

//	SPEW(("jerryeds", "SEND-FIRE"));

	memory_stream->WriteBits(&weapon_command.weaponFired, 32);
	memory_stream->WriteBits(&weapon_command.lockTime, 32);

	switch(type)
	{
		case MWEntityManager::FirstPersonWeaponToMechCommandMessageID:
			{
				// originator connection id is derived from packet header
				// target id is the full entity id
				// offset is default

				Check_Object(weapon_command.target.GetCurrent());

				BYTE connection_id = weapon_command.target.GetCurrent()->GetReplicatorID().connectionID;
				WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID;

				memory_stream->WriteBits(&connection_id, 8);
				memory_stream->WriteBits(&local_id, 16);

//				SPEWALWAYS(("jackyc", "First Person To Mech Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));		

				Entity* parent_target = weapon_command.target.GetCurrent();
				int class_id = parent_target->GetClassID();
				if (class_id == MWMoverClassID)
				{
					MWMover* mover = Cast_Object(MWMover*, parent_target);
					parent_target = mover->GetParentVehicle();
				}

				Scalar sphere_radiusMaxX = 0.f;
				Scalar sphere_radiusMaxY = 0.f;
				Scalar sphere_radiusMaxZ = 0.f;
				Scalar sphere_radiusMinX = 0.f;
				Scalar sphere_radiusMinY = 0.f;
				Scalar sphere_radiusMinZ = 0.f;
				class_id = parent_target->GetClassID();
				switch (class_id)
				{
				case MechClassID:
					{
						sphere_radiusMaxX = MECH_RANGE;
						sphere_radiusMaxY = MECH_RANGE;
						sphere_radiusMaxZ = MECH_RANGE;
						sphere_radiusMinX = -MECH_RANGE;
						sphere_radiusMinY = -MECH_RANGE;
						sphere_radiusMinZ = -MECH_RANGE;
					}
					break;
				case BuildingClassID:
				case TurretClassID:
				case BridgeClassID:
				case MFBClassID:
				case FieldBaseClassID:
				case DropshipClassID:
					{
						CollisionVolume *solid = parent_target->GetSolidVolume();
						if (solid)
						{
							Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
							sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
							sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
						}
						else
						{
							sphere_radiusMaxX = DEFAULT_RANGE;
							sphere_radiusMaxY = DEFAULT_RANGE;
							sphere_radiusMaxZ = DEFAULT_RANGE;
							sphere_radiusMinX = -DEFAULT_RANGE;
							sphere_radiusMinY = -DEFAULT_RANGE;
							sphere_radiusMinZ = -DEFAULT_RANGE;
						}
					}
					break;
				case VehicleClassID:
					{
						sphere_radiusMaxX = VEHICLE_RANGE;
						sphere_radiusMaxY = VEHICLE_RANGE;
						sphere_radiusMaxZ = VEHICLE_RANGE;
						sphere_radiusMinX = -VEHICLE_RANGE;
						sphere_radiusMinY = -VEHICLE_RANGE;
						sphere_radiusMinZ = -VEHICLE_RANGE;
					}
					break;
				default:
					{
						sphere_radiusMaxX = DEFAULT_RANGE;
						sphere_radiusMaxY = DEFAULT_RANGE;
						sphere_radiusMaxZ = DEFAULT_RANGE;
						sphere_radiusMinX = -DEFAULT_RANGE;
						sphere_radiusMinY = -DEFAULT_RANGE;
						sphere_radiusMinZ = -DEFAULT_RANGE;
					}
					break;
				}		
				
				Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX);
				Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY);
				Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ);
				
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));

				//SPEW(("jerryeds", "CLIENT HIT: %s : <%f:%f:%f>", (const char *)weapon_command.target->instanceName, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

//				SPEWALWAYS(("jackyc", "First Person To Mech Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));		

			}
			break;

		case MWEntityManager::ThirdPersonWeaponToMechCommandMessageID:
			// originator id is in the packet
			// target id is the full entity id
			// offset is default
			{

				BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID;
				memory_stream->WriteBits(&connection_id, 8);

				Check_Object(weapon_command.target.GetCurrent());

				connection_id = weapon_command.target.GetCurrent()->GetReplicatorID().connectionID;
				WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID;

				memory_stream->WriteBits(&connection_id, 8);
				memory_stream->WriteBits(&local_id, 16);

//				SPEWALWAYS(("jackyc", "Third Person To Mech Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));		

				Entity* parent_target = weapon_command.target.GetCurrent();
				int class_id = parent_target->GetClassID();
				if (class_id == MWMoverClassID)
				{
					MWMover* mover = Cast_Object(MWMover*, parent_target);
					parent_target = mover->GetParentVehicle();
				}

				Scalar sphere_radiusMaxX = 0.f;
				Scalar sphere_radiusMaxY = 0.f;
				Scalar sphere_radiusMaxZ = 0.f;
				Scalar sphere_radiusMinX = 0.f;
				Scalar sphere_radiusMinY = 0.f;
				Scalar sphere_radiusMinZ = 0.f;
				class_id = parent_target->GetClassID();
				switch (class_id)
				{
				case MechClassID:
					{
						sphere_radiusMaxX = MECH_RANGE;
						sphere_radiusMaxY = MECH_RANGE;
						sphere_radiusMaxZ = MECH_RANGE;
						sphere_radiusMinX = -MECH_RANGE;
						sphere_radiusMinY = -MECH_RANGE;
						sphere_radiusMinZ = -MECH_RANGE;
					}
					break;
				case BuildingClassID:
				case TurretClassID:
				case BridgeClassID:
				case MFBClassID:
				case FieldBaseClassID:
				case DropshipClassID:
					{
						CollisionVolume *solid = parent_target->GetSolidVolume();
						if (solid)
						{
							Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
							sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
							sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
						}
						else
						{
							sphere_radiusMaxX = DEFAULT_RANGE;
							sphere_radiusMaxY = DEFAULT_RANGE;
							sphere_radiusMaxZ = DEFAULT_RANGE;
							sphere_radiusMinX = -DEFAULT_RANGE;
							sphere_radiusMinY = -DEFAULT_RANGE;
							sphere_radiusMinZ = -DEFAULT_RANGE;
						}
					}
					break;
				case VehicleClassID:
					{
						sphere_radiusMaxX = VEHICLE_RANGE;
						sphere_radiusMaxY = VEHICLE_RANGE;
						sphere_radiusMaxZ = VEHICLE_RANGE;
						sphere_radiusMinX = -VEHICLE_RANGE;
						sphere_radiusMinY = -VEHICLE_RANGE;
						sphere_radiusMinZ = -VEHICLE_RANGE;
					}
					break;
				default:
					{
						sphere_radiusMaxX = DEFAULT_RANGE;
						sphere_radiusMaxY = DEFAULT_RANGE;
						sphere_radiusMaxZ = DEFAULT_RANGE;
						sphere_radiusMinX = -DEFAULT_RANGE;
						sphere_radiusMinY = -DEFAULT_RANGE;
						sphere_radiusMinZ = -DEFAULT_RANGE;
					}
					break;
				}		
				
				Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX);
				Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY);
				Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ);
				
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));
				
//				SPEWALWAYS(("jackyc", "Third Person To Mech Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

				//SPEW(("jerryeds","SERVER HIT : %d:%d - %f:%f:%f" , connection_id, local_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

				//SPEW(("jerryeds", "SERVER HIT: %s : <%f:%f:%f>", (const char *)weapon_command.target->instanceName, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

			}
			break;

		case MWEntityManager::AIWeaponCommandToMechtMessageID:
			// originator connection id is server and local is in packet
			// target id is the full entity id
			// offset is default

			{

				BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID;
				WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID;

				memory_stream->WriteBits(&local_id, 16);

				Check_Object(weapon_command.target.GetCurrent());

				connection_id = weapon_command.target.GetCurrent()->GetReplicatorID().connectionID;
				local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID;

				memory_stream->WriteBits(&connection_id, 8);
				memory_stream->WriteBits(&local_id, 16);

				Entity* parent_target = weapon_command.target.GetCurrent();
				int class_id = parent_target->GetClassID();
				if (class_id == MWMoverClassID)
				{
					MWMover* mover = Cast_Object(MWMover*, parent_target);
					parent_target = mover->GetParentVehicle();
				}

				Scalar sphere_radiusMaxX = 0.f;
				Scalar sphere_radiusMaxY = 0.f;
				Scalar sphere_radiusMaxZ = 0.f;
				Scalar sphere_radiusMinX = 0.f;
				Scalar sphere_radiusMinY = 0.f;
				Scalar sphere_radiusMinZ = 0.f;
				class_id = parent_target->GetClassID();
				switch (class_id)
				{
				case MechClassID:
					{
						sphere_radiusMaxX = MECH_RANGE;
						sphere_radiusMaxY = MECH_RANGE;
						sphere_radiusMaxZ = MECH_RANGE;
						sphere_radiusMinX = -MECH_RANGE;
						sphere_radiusMinY = -MECH_RANGE;
						sphere_radiusMinZ = -MECH_RANGE;
					}
					break;
				case BuildingClassID:
				case TurretClassID:
				case BridgeClassID:
				case MFBClassID:
				case FieldBaseClassID:
				case DropshipClassID:
					{
						CollisionVolume *solid = parent_target->GetSolidVolume();
						if (solid)
						{
							Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
							sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
							sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
						}
						else
						{
							sphere_radiusMaxX = DEFAULT_RANGE;
							sphere_radiusMaxY = DEFAULT_RANGE;
							sphere_radiusMaxZ = DEFAULT_RANGE;
							sphere_radiusMinX = -DEFAULT_RANGE;
							sphere_radiusMinY = -DEFAULT_RANGE;
							sphere_radiusMinZ = -DEFAULT_RANGE;
						}
					}
					break;
				case VehicleClassID:
					{
						sphere_radiusMaxX = VEHICLE_RANGE;
						sphere_radiusMaxY = VEHICLE_RANGE;
						sphere_radiusMaxZ = VEHICLE_RANGE;
						sphere_radiusMinX = -VEHICLE_RANGE;
						sphere_radiusMinY = -VEHICLE_RANGE;
						sphere_radiusMinZ = -VEHICLE_RANGE;
					}
					break;
				default:
					{
						sphere_radiusMaxX = DEFAULT_RANGE;
						sphere_radiusMaxY = DEFAULT_RANGE;
						sphere_radiusMaxZ = DEFAULT_RANGE;
						sphere_radiusMinX = -DEFAULT_RANGE;
						sphere_radiusMinY = -DEFAULT_RANGE;
						sphere_radiusMinZ = -DEFAULT_RANGE;
					}
					break;
				}		
				
				Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX);
				Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY);
				Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ);
				
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));
			}
			break;


		case MWEntityManager::FirstPersonWeaponToGroundCommandMessageID:
			// originator connection id is derived from packet header
			// target id is the ground
			// offset is larger
			{

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

				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID));

				//SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));


			}
			break;

		case MWEntityManager::ThirdPersonWeaponToGroundCommandMessageID:
			// originator id is in the packet
			// target id is the ground
			// offset is larger
			{
				BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID;
				memory_stream->WriteBits(&connection_id, 8);

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

				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID));

				//SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

//				SPEWALWAYS(("jackyc", "Third Person To Ground Write - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));
		
			}
			break;

		case MWEntityManager::AIWeaponCommandToGroundtMessageID:
			// originator connection id is server and local is in packet
			// target id is the ground
			// offset is larger
			{
				WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID;

				memory_stream->WriteBits(&local_id, 16);

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

				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID));
			
			}
			break;
			

		case MWEntityManager::FirstPersonWeaponToServerObjectCommandMessageID:
			// originator connection id is derived from packet header
			// target local id is in the packet - connection is server
			// offset is default
			{
				WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID;
				memory_stream->WriteBits(&local_id, 16);

//				SPEWALWAYS(("jackyc", "First Person To Server Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

				Entity* parent_target = weapon_command.target.GetCurrent();
				int class_id = parent_target->GetClassID();
				if (class_id == MWMoverClassID)
				{
					MWMover* mover = Cast_Object(MWMover*, parent_target);
					parent_target = mover->GetParentVehicle();
				}

				Scalar sphere_radiusMaxX = 0.f;
				Scalar sphere_radiusMaxY = 0.f;
				Scalar sphere_radiusMaxZ = 0.f;
				Scalar sphere_radiusMinX = 0.f;
				Scalar sphere_radiusMinY = 0.f;
				Scalar sphere_radiusMinZ = 0.f;
				class_id = parent_target->GetClassID();
				switch (class_id)
				{
				case MechClassID:
					{
						sphere_radiusMaxX = MECH_RANGE;
						sphere_radiusMaxY = MECH_RANGE;
						sphere_radiusMaxZ = MECH_RANGE;
						sphere_radiusMinX = -MECH_RANGE;
						sphere_radiusMinY = -MECH_RANGE;
						sphere_radiusMinZ = -MECH_RANGE;
					}
					break;
				case BuildingClassID:
				case TurretClassID:
				case BridgeClassID:
				case MFBClassID:
				case FieldBaseClassID:
				case DropshipClassID:
					{
						CollisionVolume *solid = parent_target->GetSolidVolume();
						if (solid)
						{
							Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
							sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
							sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
						}
						else
						{
							sphere_radiusMaxX = DEFAULT_RANGE;
							sphere_radiusMaxY = DEFAULT_RANGE;
							sphere_radiusMaxZ = DEFAULT_RANGE;
							sphere_radiusMinX = -DEFAULT_RANGE;
							sphere_radiusMinY = -DEFAULT_RANGE;
							sphere_radiusMinZ = -DEFAULT_RANGE;
						}
					}
					break;
				case VehicleClassID:
					{
						sphere_radiusMaxX = VEHICLE_RANGE;
						sphere_radiusMaxY = VEHICLE_RANGE;
						sphere_radiusMaxZ = VEHICLE_RANGE;
						sphere_radiusMinX = -VEHICLE_RANGE;
						sphere_radiusMinY = -VEHICLE_RANGE;
						sphere_radiusMinZ = -VEHICLE_RANGE;
					}
					break;
				default:
					{
						sphere_radiusMaxX = DEFAULT_RANGE;
						sphere_radiusMaxY = DEFAULT_RANGE;
						sphere_radiusMaxZ = DEFAULT_RANGE;
						sphere_radiusMinX = -DEFAULT_RANGE;
						sphere_radiusMinY = -DEFAULT_RANGE;
						sphere_radiusMinZ = -DEFAULT_RANGE;
					}
					break;
				}		
				
				Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX);
				Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY);
				Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ);
				
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));
				
//				SPEWALWAYS(("jackyc", "First Person To Server Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

			}
			break;

		case MWEntityManager::ThirdPersonWeaponToServerObjectCommandMessageID:
			// originator id is in the packet
			// target local id is in the packet - connection is server
			// offset is default
			{
				BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID;
				memory_stream->WriteBits(&connection_id, 8);

				WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID;
				memory_stream->WriteBits(&local_id, 16);

//				SPEWALWAYS(("jackyc", "Third Person To Server Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

				Entity* parent_target = weapon_command.target.GetCurrent();
				int class_id = parent_target->GetClassID();
				if (class_id == MWMoverClassID)
				{
					MWMover* mover = Cast_Object(MWMover*, parent_target);
					parent_target = mover->GetParentVehicle();
				}

				Scalar sphere_radiusMaxX = 0.f;
				Scalar sphere_radiusMaxY = 0.f;
				Scalar sphere_radiusMaxZ = 0.f;
				Scalar sphere_radiusMinX = 0.f;
				Scalar sphere_radiusMinY = 0.f;
				Scalar sphere_radiusMinZ = 0.f;
				class_id = parent_target->GetClassID();
				switch (class_id)
				{
				case MechClassID:
					{
						sphere_radiusMaxX = MECH_RANGE;
						sphere_radiusMaxY = MECH_RANGE;
						sphere_radiusMaxZ = MECH_RANGE;
						sphere_radiusMinX = -MECH_RANGE;
						sphere_radiusMinY = -MECH_RANGE;
						sphere_radiusMinZ = -MECH_RANGE;
					}
					break;
				case BuildingClassID:
				case TurretClassID:
				case BridgeClassID:
				case MFBClassID:
				case FieldBaseClassID:
				case DropshipClassID:
					{
						CollisionVolume *solid = parent_target->GetSolidVolume();
						if (solid)
						{
							Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
							sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
							sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
						}
						else
						{
							sphere_radiusMaxX = DEFAULT_RANGE;
							sphere_radiusMaxY = DEFAULT_RANGE;
							sphere_radiusMaxZ = DEFAULT_RANGE;
							sphere_radiusMinX = -DEFAULT_RANGE;
							sphere_radiusMinY = -DEFAULT_RANGE;
							sphere_radiusMinZ = -DEFAULT_RANGE;
						}
					}
					break;
				case VehicleClassID:
					{
						sphere_radiusMaxX = VEHICLE_RANGE;
						sphere_radiusMaxY = VEHICLE_RANGE;
						sphere_radiusMaxZ = VEHICLE_RANGE;
						sphere_radiusMinX = -VEHICLE_RANGE;
						sphere_radiusMinY = -VEHICLE_RANGE;
						sphere_radiusMinZ = -VEHICLE_RANGE;
					}
					break;
				default:
					{
						sphere_radiusMaxX = DEFAULT_RANGE;
						sphere_radiusMaxY = DEFAULT_RANGE;
						sphere_radiusMaxZ = DEFAULT_RANGE;
						sphere_radiusMinX = -DEFAULT_RANGE;
						sphere_radiusMinY = -DEFAULT_RANGE;
						sphere_radiusMinZ = -DEFAULT_RANGE;
					}
					break;
				}		
				
				Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX);
				Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY);
				Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ);
				
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));
				
//				SPEWALWAYS(("jackyc", "Third Person To Server Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));

			}
			break;

		case MWEntityManager::AIWeaponCommandToServerObjectMessageID:
			// originator connection id is server and local is in packet
			// target local id is in the packet - connection is server
			// offset is default
			{
				WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID;
				memory_stream->WriteBits(&local_id, 16);

				local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID;
				memory_stream->WriteBits(&local_id, 16);

				Entity* parent_target = weapon_command.target.GetCurrent();
				int class_id = parent_target->GetClassID();
				if (class_id == MWMoverClassID)
				{
					MWMover* mover = Cast_Object(MWMover*, parent_target);
					parent_target = mover->GetParentVehicle();
				}

				Scalar sphere_radiusMaxX = 0.f;
				Scalar sphere_radiusMaxY = 0.f;
				Scalar sphere_radiusMaxZ = 0.f;
				Scalar sphere_radiusMinX = 0.f;
				Scalar sphere_radiusMinY = 0.f;
				Scalar sphere_radiusMinZ = 0.f;
				class_id = parent_target->GetClassID();
				switch (class_id)
				{
				case MechClassID:
					{
						sphere_radiusMaxX = MECH_RANGE;
						sphere_radiusMaxY = MECH_RANGE;
						sphere_radiusMaxZ = MECH_RANGE;
						sphere_radiusMinX = -MECH_RANGE;
						sphere_radiusMinY = -MECH_RANGE;
						sphere_radiusMinZ = -MECH_RANGE;
					}
					break;
				case BuildingClassID:
				case TurretClassID:
				case BridgeClassID:
				case MFBClassID:
				case FieldBaseClassID:
				case DropshipClassID:
					{
						CollisionVolume *solid = parent_target->GetSolidVolume();
						if (solid)
						{
							Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent);
							sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z;
							sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x;
							sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y;
							sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z;
						}
						else
						{
							sphere_radiusMaxX = DEFAULT_RANGE;
							sphere_radiusMaxY = DEFAULT_RANGE;
							sphere_radiusMaxZ = DEFAULT_RANGE;
							sphere_radiusMinX = -DEFAULT_RANGE;
							sphere_radiusMinY = -DEFAULT_RANGE;
							sphere_radiusMinZ = -DEFAULT_RANGE;
						}
					}
					break;
				case VehicleClassID:
					{
						sphere_radiusMaxX = VEHICLE_RANGE;
						sphere_radiusMaxY = VEHICLE_RANGE;
						sphere_radiusMaxZ = VEHICLE_RANGE;
						sphere_radiusMinX = -VEHICLE_RANGE;
						sphere_radiusMinY = -VEHICLE_RANGE;
						sphere_radiusMinZ = -VEHICLE_RANGE;
					}
					break;
				default:
					{
						sphere_radiusMaxX = DEFAULT_RANGE;
						sphere_radiusMaxY = DEFAULT_RANGE;
						sphere_radiusMaxZ = DEFAULT_RANGE;
						sphere_radiusMinX = -DEFAULT_RANGE;
						sphere_radiusMinY = -DEFAULT_RANGE;
						sphere_radiusMinZ = -DEFAULT_RANGE;
					}
					break;
				}		
				
				Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX);
				Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY);
				Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ);
				
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID));				
			}
			break;


		case MWEntityManager::FirstPersonWeaponNoTargetCommandMessageID:
			// originator connection id is derived from packet header
			// no target no offset just shoot
			{
				Scalar min_z, max_z, min_x, max_x;
				Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x);
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID));
				
//				SPEWALWAYS(("jackyc", "First Person No Target Write - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));
			}
			break;

		case MWEntityManager::ThirdPersonWeaponNoTargetCommandMessageID:
			// originator id is in the packet
			// no target no offset just shoot
			{
				BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID;
				memory_stream->WriteBits(&connection_id, 8);

				Scalar min_z, max_z, min_x, max_x;
				Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x);
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID));

//				SPEWALWAYS(("jackyc", "Third Person No Target Write - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z));
			}
			break;

		case MWEntityManager::AIWeaponCommandToNoTargetMessageID:
			// originator connection id is server and local is in packet
			// no target no offset just shoot
			{
				WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID;
				memory_stream->WriteBits(&local_id, 16);

				Scalar min_z, max_z, min_x, max_x;
				Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x);
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID));
				memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID));
			}
			break;

	}


	//Write the ams data...
	Vehicle *vehicle = Cast_Object(Vehicle *, weapon_command.originator.GetCurrent());


	if (weapon_command.target.GetCurrent() != NULL)
	{
		Stuff::ChainIteratorOf<Weapon*> iterator(&vehicle->weaponChain);
		Weapon *weapon;
		
		while ((weapon = iterator.ReadAndNext()) != NULL)
		{
			int id = weapon->GetWeaponID();
			if (weapon_command.weaponFired & (0x1 << id))
			{
				if (weapon->IsDerivedFrom(MissileWeapon::DefaultData))
				{
					MissileWeapon *missile_weapon;
					missile_weapon = Cast_Object(MissileWeapon *, weapon);

					if (missile_weapon->IsAMSValid(weapon_command.target.GetCurrent()))
					{
						//write the target number...
						memory_stream->WriteBits(&weapon_command.AntiWeaponCount[id], 3);
					}
				}
			}
		}
	}

}

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