//==========================================================================//
// File:        mechdmg.hpp                                                  //
// Project: BattleTech                                                       //
// Contents: Mech::DamageZone													           //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 06/05/95  JM  Initial coding.                                             //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if !defined(MECHDMG_HPP)
#	define MECHDMG_HPP

#	if !defined(DAMAGE_HPP)
#		include <damage.hpp>
#	endif

#	if !defined(SLOT_HPP)
#		include <slot.hpp>
#	endif

#	if !defined(TABLE_HPP)
#		include <table.hpp>
#	endif

#	if !defined(ENTITYID_HPP)
#		include <entityid.hpp>
#	endif

	class Mech;
	class Subsystem;
	class DamageZone;

	//##########################################################################
	//######################    MechCriticalSubsystem          #################
	//##########################################################################

	class
		MechCriticalSubsystem  SIGNATURED
	{
		public:

		MechCriticalSubsystem(DamageZone *owner);

		virtual ~MechCriticalSubsystem();

		SlotOf<Subsystem*>
			subsystemPlug;

		Scalar
			damagePercentage, damagePercentageUsed;

		Scalar
			criticalWeight;

		Logical
			TestInstance() const;

	};


	//##########################################################################
	//####################    Mech::DamageZone       ###########################
	//##########################################################################

	class Mech__DamageZone :
		public DamageZone
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// LOD Support
	//
		protected:

			void
				LODDamageRouter(EntityID inflicting, Damage damage);

			int
				RandomRedirect();

			typedef PlugOf<int> IntegerPlug;

			typedef TableOf<IntegerPlug*, int> DamageZoneIndexTable;

			typedef TableIteratorOf<IntegerPlug*, int> DamageZoneIndexTableIterator;


			// Zones which are artifacts have a table of their real children.

			DamageZoneIndexTable redirectTable;

			// The result of the last random redirect

			int lastHitZone;
			Scalar lastDamageTime;
			EntityID lastInflicting;
			//
			// Zones which are real have a pointer (slot) back to their artifact parent.
			// With the current art (1/30/96) no zone has both a parent and children,
			// and many zones have neither.

			SlotOf<Mech__DamageZone*> parentArtifactZone;

			void
				UpdateLODDamageLevel();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Descending Heirarchy when DamageZone Destroyed Support
	//
			void
				ShortAttachedGenerators();

			void
				SendSubsystemDamage();

			void
				RecurseSegmentTable(Mech *my_mech);

			int
				segmentIndex;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Damage Support
	//
		public:

			void
				TakeDamage(Damage& damage);

			Subsystem*
				CriticalHit(Damage &damage_data);

		protected:

      	Logical
				vitalDamageZone;

			Logical
         	descendOnDestruction;

			Logical
			destroySiblingsOnDestruction;

			Logical
				leftLeg;

			Logical
				rightLeg;

			int
				criticalSubsystemCount;

			Scalar
				criticalWeightSum;

			MechCriticalSubsystem
				**criticalSubsystems;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Graphic State Support
	//

	public:

		void
				SetGraphicState(Enumeration new_state);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction / Destruction
	//

	public:

			static const int NullDamageZone;

			Mech__DamageZone(
				Mech *mech,
				int	damage_zone_index,
				MemoryStream *stream
			);

			void SetLODParentPointers();

			~Mech__DamageZone();

			static Logical
			CreateStreamedDamageZone(
				ResourceFile   *resource_file,
				NotationFile	*model_file,
				const char		*model_name,
				NotationFile	*skl_file,
				const char     *damage_zone_name,
				NotationFile   *dmg_file,
				const ResourceDirectories  *directories,
				MemoryStream    *damage_zone_stream
			);

         static int
				GetSegmentIndex(
					CString	damage_zone_name,
					NotationFile *skl_file
				);
	};

#endif
