//============================================================================//
// File:	misthrst.hh                                                          //
// Project: BattleTech																	      //
// Contents: Missile Thruster provides power to move the missile  				//
//----------------------------------------------------------------------------//
//   Date    Who  Modification                                                //
// --------  ---  ------------------------------------------------------------//
// 04/13/95  JM  Initial coding.                                              //
//----------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. All Rights reserved  //
//                   	PROPRIETARY AND CONFIDENTIAL                          //
//============================================================================//
//
// This header is the SURVIVING MISTHRST.HPP, reproduced verbatim with the only
// addition being the byte-offset / @ADDR annotations recovered from the shipped
// binary (Ghidra pseudo-C, module cluster @004be7c4-@004be8e8 + the streamed
// resource parser @004bf8ec, all in part_013.c).  See misthrst.cpp for the
// per-method evidence.
//
// Inheritance chain established from the decomp:
//      Simulation -> Subsystem (FUN_0041c52c base ctor) -> MissileThruster
// The ctor (@004be7c4) chains the Subsystem base ctor @0041c52c with the shared
// default record &DAT_00512a9c, installs vtable PTR_LAB_00512bbc, and copies the
// four streamed tuning scalars out of its SubsystemResource.  Every vtable slot
// other than the destructor inherits the Subsystem base (vtable @00512bbc holds
// only 0x41xxxx engine slots, slot0 = ~MissileThruster @004be8bc), so the real
// behaviour lives in the non-virtual Performance MissileThrusterSimulation().
//
// Object byte offsets (this is an int* in the decomp, word index in parens):
//      burnTimeRemaining        @0xE4  (word 0x39)
//      maxThrusterRotationRate  @0xE8  (word 0x3A)  Degree*0.0174533 -> Radian
//      thrusterAcceleration     @0xEC  (word 0x3B)
//      thrusterClimb            @0xF0  (word 0x3C)
//      acceleration (Motion)    @0xF4  (word 0x3D..) linear@0xF4 / angular@0x100
//

#if !defined (MISTHRST_HPP)
	#define	MISTHRST_HPP

	#if !defined(SUBSYSTM_HPP)
		#include <subsystm.hpp>
	#endif

	#if !defined(ANGLE_HPP)
		#include <angle.hpp>
	#endif

	#if !defined(MOTION_HPP)
		#include <motion.hpp>
	#endif

//###################    Froward Class Declarations   ######################
class Missile;

//###################    MissileThruster  SubsystemResource    #################
//
//	The streamed scalar block begins at +0x30 past the Subsystem::SubsystemResource
//	header (verified by the ctor reads at param_4+0x30..+0x3c, @004be7c4).  The
//	streamed-entity model parser @004bf8ec lays these out (plus an extra
//	SplashRadius) at model-record offsets +0x40..+0x50; the Missile ctor
//	(@004bf5b4) copies model+0x40..+0x4c into this resource before constructing
//	the thruster.
//
	struct MissileThruster__SubsystemResource:
		public Subsystem::SubsystemResource
	{
		Scalar	burnTime;					// +0x30  "BurnTime"
		Degree	maxThrusterRotationRate;	// +0x34  "MaxThrusterRotationRate"
		Scalar	thrusterAcceleration;		// +0x38  "ThrusterAcceleration"
		Scalar	thrusterClimb;				// +0x3C  "ThrusterClimb"
		// NB: the model record also carries "SplashRadius" @+0x50 (parsed by
		// CreateStreamedSubsystem @004bf8ec) which the detonation path reads;
		// it is not a thruster member and is not declared here.
	};


//###########################################################################
//#########################     CLASS -- MissileThruster   ##################
//###########################################################################
//
//	(vtable @00512bbc, ctor @004be7c4, dtor @004be8bc, CSS @004bf8ec.)
//

	class MissileThruster :
		public Subsystem
	{

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data Support
//
	public:
		typedef MissileThruster__SubsystemResource SubsystemResource;	// declared early so CSS sees it
		static Derivation ClassDerivations;		// IsDerivedFrom tag 0x512aac
		static Receiver::MessageHandlerSet MessageHandlers;
		static SharedData DefaultData;			// resolved as &DAT_00512a9c

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//
//	Attribute IDs verified against the IndexEntry table @00512ad0
//	(BurnTimeRemaining 0xE5, MaxThrusterRotationRate 0xE9, ThrusterAcceleration 0xED).
//

public:
		enum {
			BurnTimeRemainingAttributeID = Subsystem::NextAttributeID,
			MaxThrusterRotationRateAttributeID,
			ThrusterAccelerationAttributeID,
			NextAttributeID
		};

	public:
		static const IndexEntry AttributePointers[];

	protected:
		static AttributeIndexSet	AttributeIndex;

	//
	// public attribute declarations go here
	//
	public:
		Scalar 			burnTimeRemaining;		// @0xE4  resource burnTime
		Radian			maxThrusterRotationRate;// @0xE8  resource Degree * (PI/180)
		Scalar			thrusterAcceleration;	// @0xEC  resource +0x38
		Scalar			thrusterClimb;		// @0xF0  resource +0x3C
      Motion			acceleration;			// @0xF4  base thrust (0,0,-thrusterAcceleration)


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model Support
//
	public:
		enum {
			ThrusterBurning= Subsystem::StateCount,
			StateCount
		};

		typedef void
			(MissileThruster::*Performance)(Scalar time_slice);

		void
			MissileThrusterSimulation(Scalar time_slice);	// Performance @PTR_LAB_00512b20

		void
			SetPerformance(Performance performance)
			{
				Check(this);
				activePerformance = (Simulation::Performance)performance;
			}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 	TestClass Support
//
	public:

		static Logical
			TestClass(Missile &);
		Logical
			TestInstance() const;					// @004be8e8

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Streamed resource support (recovered)
//
	public:
		static int
			CreateStreamedSubsystem(				// @004bf8ec (record size 0x54)
				NotationFile				*model_file,
				const char					*model_name,
				NotationFile				*subsystem_file,
				const ResourceDirectories	*directories,
				SubsystemResource			*subsystem_resource
			);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
	public:

		typedef MissileThruster__SubsystemResource SubsystemResource;

		MissileThruster(								// @004be7c4
			Missile			*owner,
         int				subsystem_ID,
			SubsystemResource	*subsystem_resource
			);
		~MissileThruster();							// @004be8bc

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Local Support
//

};
#endif
