//===========================================================================//
// File:	NetWeapon.hpp											
//---------------------------------------------------------------------------//
//   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               //
//===========================================================================//




#pragma once

#include "NetConstants.hpp"
#include "NetUpdateManager.hpp"

namespace MechWarrior4 
{

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

	void NetWeaponSecurityCheckStart();
	void NetWeaponSecurityCheckStop();

	class WeaponUpdate:
		public Stuff::Plug
	{
		public:

			private:
				static Stuff::MemoryBlock *AllocatedMemory;

			public:
				void*
					operator new(size_t)
						{return AllocatedMemory->New();}
				void
					operator delete(void *where)
						{AllocatedMemory->Delete(where);}

			WeaponUpdate():
				Stuff::Plug(DefaultData),
				originator(NULL),
				target(NULL)
			{
				weaponFired = 0;
				targetOffset = Point3D::Identity;
				lockTime = 0.0f;
			};

			void Reset()
			{
				weaponFired = 0;
				originator.Remove();
				target.Remove();
				targetOffset = Point3D::Identity;
				lockTime = 0.0f;
			};

			// bit field of the weapons fired
			DWORD weaponFired;

			// the person pulling the trigger
			SlotOf<Entity *> originator;

			// the person being hit
			SlotOf<Entity *> target;

			// offset of the hit to the target. 
			// Multiply the world hit point by the inverse of the targets local to world
			// if you hit nothing or hit the ground just world co-ords with no extra transform
			Point3D targetOffset;

			// how long you have been locked
			// currently not implemented
			Scalar lockTime;

			// If you fire a missile you need to call missilesubsystem->GetAMSNumber() after you call fireweapon.
			// put that number into AntiWeaponCount[weaponsubsystem->GetWeaponID()]
			// You probably can do this every frame after you would have potentially called fireweapon()
			// as long as weaponfired doesn't have the missile in it, this value won't be sent over the network.
			
			int AntiWeaponCount[32];




			// FOR OFFICE USE ONLY! DO NOT FILL IN
			// this flag is for reading on the server/client
			// if the target or originator is not found
			// than obsolete is set to true and the packet is ignored
			bool obsolete;



			static void
				InitializeClass();
		
			static void
				TerminateClass();

		

	};


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	
	struct WeaponCommand
	{
	public:

		enum {
			TargetOffsetXEntryID = 0,
			TargetOffsetYEntryID,
			TargetOffsetZEntryID,
			TerrainXEntryID,
			TerrainZEntryID,
			NoTargetXEntryID,
			NoTargetYEntryID,
			NoTargetZEntryID,
			UpdateEntryCount
		};

		enum {
			UpdateType = UpdateManager::WeaponCommandID
		};

		static int GetUpdateEntryCount(){return UpdateEntryCount;};
		static int GetUpdateEntryType(){return UpdateManager::WeaponCommandID;};


		
		static void Decode(Entity *entity, MemoryStream *memory_stream, Time till, Scalar packet_latency, int connection, int debug_level, int bandwidth, Scalar rate){STOP(("NOT SUPPORTED"));};
		static void Skip(MemoryStream *memory_stream, int size, Time till, int connection, int debug_level, int bandwidth){STOP(("NOT SUPPORTED"));};
		static void Encode(Entity *entity, DynamicMemoryStream *memory_stream, int connection, int debug_level, int bandwidth){STOP(("NOT SUPPORTED"));};
		static int SizeFunction(Entity *entity){return -1;};
		static int  MaxSize(Entity *entity, int debug_level, int bandwidth){return -1;};
		static bool MaintainActiveFlagFunction(Entity *entity,Point3D cull_location){return true;}

		static void SpecialDecode(int connection, int type, WeaponUpdate &weapon_command, MemoryStream *memory_stream);
		static void SpecialEncode(int connection, int type, WeaponUpdate &weapon_command, DynamicMemoryStream *memory_stream);

	};



};