//===========================================================================//
// File:	messmgr.hh                                                          //
// Project: BattleTech                         										  //
// Contents:  Consolidates Messages from Subsystems and Graphics Generation  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 09/30/95  JM  Initial coding.                                             //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. All Rights reserved //
//                   	PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//
//
// GROUND TRUTH: this header is the surviving MESSMGR.HPP
// (410SRC/Telsa40/Rel410/CODE/BT/BT/MESSMGR.HPP), reproduced verbatim.
// The only additions are the //@offset reconstruction comments tying each
// data member to the byte offset observed in the shipped object (see
// messmgr.cpp for the originating @ADDR evidence).  Declarations are
// UNCHANGED.
//
// Class summary (recovered):
//   SubsystemMessageManager : public Subsystem
//     vtable @0050b954   ClassID 0xBD3 ("SubsystemMessageManagerClassID")
//     ctor   @0049bca4   dtor @0049bd7c   CreateStreamedSubsystem @0049be10
//     object layout >= 0x130 bytes; new members begin at +0xE4.
//
#if !defined (MESSMGR_HPP)
#	define MESSMGR_HPP

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

#if !defined (RESOURCE_HPP)
#	include <resource.hpp>
#endif

#if !defined (VCHAIN_HPP)
#	include <vchain.hpp>
#endif

#if !defined (PLUG_HPP)
#	include <plug.hpp>
#endif

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

class Entity;
class Mech;
class Entity__TakeDamageMessage;

//##########################################################################
//##########    SubsystemMessageManager::SubsystemResource   ###############
//##########################################################################
//
// Parsed by CreateStreamedSubsystem @0049be10.  Stamps ClassID 0xBD3 and
// model-record size 0x38 at resource +0x20/+0x24, then reads:
//   +0x30 terrainHitExplosionID   ("TerrainHitExplosion", a resource lookup)
//   +0x34 rendererCompensateTime  ("RendererCompensateTime", a Scalar)
//
struct SubsystemMessageManager__SubsystemResource :
	public Subsystem::SubsystemResource
{
	ResourceDescription::ResourceID
		terrainHitExplosionID;		// resource +0x30

	Scalar
		rendererCompensateTime;		// resource +0x34
};

//##########################################################################
//#####################    SubsystemMessageManager       ###################
//##########################################################################
class
	  SubsystemMessageManager :
	public Subsystem

{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data Support
//
	public:
		static Derivation ClassDerivations;		// static @0050b6cc (BSS)
		static SharedData DefaultData;			// default Performance ptr @0050b6fc -> 0049b784
		//
		// Added to satisfy the real Simulation__SharedData 4-arg ctor
		// (derivation, message-handlers, attribute-index, state-count).  The
		// shipped record carried only the derivation + default Performance; the
		// handler set / attribute index are empty for this class.
		//
		static Receiver::MessageHandlerSet MessageHandlers;
		static AttributeIndexSet           AttributeIndex;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Death and Damage Support
//

	public:

		void DeathReset(Logical) {}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model Support
//
	protected:

		struct CommonDamageInformation
		{
			Entity
				*entityHit;			//@0xE4  (ctor/reset -> 0)

			int
				damageZoneIndex;	//@0xE8  (ctor/reset -> -1)

			Point3D
				impactPoint;		//@0xEC  (Point3D, 3 Scalars)

		} commonDamageInformation;	//@0xE4

	public:

		struct	DamageInformation
			: public Plug			// Plug vtable @0050b9a8, dtor @0049c3e3, size 0x14
		{
			Enumeration
				damageType;			//@0x0C  (= TakeDamageMessage+0x2C)

			int
				subsystemID;		//@0x10  (= TakeDamageMessage+0x5C)
		};

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

		void
			SetPerformance(Performance performance)
			{
				Check(this);
				activePerformance = (Simulation::Performance)performance;
			}
		void
			ConsolidateAndSendDamage(Scalar time_slice);	// Performance @0049b784

		Mech*
			GetEntity()
				{Check(this); return Cast_Object(Mech*, Subsystem::GetEntity());}

	protected:

		Scalar
			rendererCompensateTime;	//@0xF8  (resource +0x34)

		typedef PlugOf<ResourceDescription::ResourceID>
			ResourceIDPlug;

		VChainOf<ResourceIDPlug*, ResourceDescription::ResourceID>
			weaponExplosions;		//@0xFC  (VChain hdr 0x18 bytes)

		VChainOf<DamageInformation*, Scalar> damageInformation;	//@0x114 (VChain hdr 0x18 bytes)

		ResourceDescription::ResourceID
			terrainHitExplosionID;	//@0x12C (resource +0x30)

		void
			CreateWeaponExplosions(
				Logical terrain_hit,
				EntityID entity_hit,
				Point3D explode_position
			);						// inlined into ConsolidateAndSendDamage @0049b784

		//
		// @0049baa0 -- per-frame flush of the accumulated weaponExplosions queue
		// (own method; not a streamed override).
		//
		void
			SendQueuedExplosions();

		//
		// CROSS-FAMILY shim.  In the original the per-subsystem explosion resource
		// id is read off the engine Subsystem (Subsystem::GetExplosionID(),
		// subsystem+0x3E4).  The WinTesla Subsystem does not expose it yet, so we
		// resolve through this local helper until the base provides it.  See
		// report "CROSS-FAMILY NEEDS".
		//
		ResourceDescription::ResourceID
			ResolveExplosionID(Subsystem *subsystem);

		//
		// CROSS-FAMILY shim.  The original built a renderer command (FUN_004336f0)
		// and submitted it to the global graphics pipe (theGraphicsPipe->Submit,
		// FUN_0041acbc).  WinTesla replaced the IG graphics pipe with L4D3D and the
		// submission entry point is not present in these headers; isolate the
		// missing call here so the queueing/timing logic compiles.
		//
		void
			SubmitExplosion(
				ResourceDescription::ResourceID explosion_id,
				Scalar fire_time
			);

	public:

		void
			AddDamageMessage(
				Entity *damaged_entity,
				Entity__TakeDamageMessage *message
			);						//@0049b6d8

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

		typedef SubsystemMessageManager__SubsystemResource SubsystemResource;

		SubsystemMessageManager(
			Mech *owner,
			int subsystem_ID,
			SubsystemResource *sub_res,
			SharedData &shared_data=DefaultData
		);							// ctor @0049bca4

		~SubsystemMessageManager();	// dtor @0049bd7c (vtable slot 0)

		Logical
      	TestInstance() const;

		static Logical
			CreateStreamedSubsystem(
				ResourceFile					*resource_file,
				NotationFile					*model_file,
				const char						*model_name,
				const char						*subsystem_name,
				SubsystemResource *subsystem_resource,
				NotationFile					*subsystem_file,
				const ResourceDirectories	*directories
			);						// @0049be10 (ClassID 0xBD3)
};
#endif
