//===========================================================================//
// File:	MissileWeapon.hpp													
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 05/18/99	 DPB  Created File
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

#include "MW4.hpp"
#include "ProjectileWeapon.hpp"

namespace MechWarrior4
{
	
	typedef ProjectileWeapon__CreateMessage				MissileWeapon__CreateMessage;
	typedef ProjectileWeapon__ExecutionStateEngine		MissileWeapon__ExecutionStateEngine;
	typedef ProjectileWeapon__Message					MissileWeapon__Message;
	typedef ProjectileWeapon__ClassData					MissileWeapon__ClassData;


	void MissileSecurityCheckStart();
	void MissileSecurityCheckStop();

	//##########################################################################
	//#####################   MissileWeapon::GameModel    ######################
	//##########################################################################

	class MissileWeapon__GameModel:
		public ProjectileWeapon::GameModel
	{
	public:
		typedef ProjectileWeapon::GameModel BaseClass;

		Stuff::Scalar
			burnTime;

		enum {
			BurnTimeAttributeID = ProjectileWeapon__GameModel::NextAttributeID,
			NextAttributeID
		};

		static bool
			ReadAndVerify(
				MissileWeapon__GameModel *model,
				ModelAttributeEntry *attribute_entry,
				const char *data,
				char **error,
				int error_buffer = 128
			);

		static void
			ConstructGameModel(Script *script);
	};

	//##########################################################################
	//###########################   MissileWeapon    ###########################
	//##########################################################################


	class MissileWeapon:
		public ProjectileWeapon
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef MissileWeapon__ClassData							ClassData;
		typedef MissileWeapon__GameModel							GameModel;
		typedef MissileWeapon__Message							Message;
		typedef MissileWeapon__ExecutionStateEngine				ExecutionStateEngine;
		typedef MissileWeapon__CreateMessage						CreateMessage;


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		static MissileWeapon*
			Make(
				CreateMessage *message,
				ReplicatorID *base_id
			);
		void
			CommonCreation(CreateMessage *message);
		// for Mercs, have to override this for Arrow weapons
		virtual
			void
				Respawn(Adept::Entity::CreateMessage *message);

	protected:
		MissileWeapon(
			ClassData *class_data,
			CreateMessage *message,
			ReplicatorID *base_id,
			ElementRenderer::Element *element
		);

		~MissileWeapon();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Shared Data support
	//
	public:
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data & Game Model Support
	//
	public:
		const GameModel*
			GetGameModel()
				{return Cast_Pointer(const GameModel*, gameModelResource.GetPointer());}

	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Simulation Support
	//
	public:
		void
			CreateProjectile(Stuff::Time till);


		//Berger, you weenie.  That's Affected not Effected.  Gesh, get a spell checker.

		bool
			rollAMSNumber;
		int
			numberEffectedByAMS;
		Stuff::Point3D
			m_lockedTargetEntityPartOffset;

		void SetAMSNumber(int number)
		{
			rollAMSNumber = false;
			numberEffectedByAMS = number;
		}

		int GetAMSNumber()
		{
			return numberEffectedByAMS;
		}

// MSL 5.05 Advance Mode
		int
			m_AdvanceMode;
// MSL 5.06 Armor Mode
		int
			m_ArmorMode;

		bool IsAMSValid(Entity *target);

		void PreCollisionExecute(Time till);

	protected:
	// in Mercs, Arrow missiles can't be shot down by AMS
		bool
			unaffectedByAMS;
		void
			Fire(CollisionQuery *query, Stuff::Time time_locked, const Stuff::Point3D& lockedTargetEntityPartOffset);

		void QuickFire (Adept::Entity *target);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test Support
	//
	public:
		void
      		TestInstance() const;
	};
}


