//===========================================================================//
// File:	entity3.hh                                                          //
// Project: MUNGA           Brick: Entity Manager                            //
// Contents: Interface specification for entity class                        //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 11/29/94  JMA  Initial coding.                                            //
// 12/14/95	 GDU  Revised TakeDamage message                                 //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if defined(ENTITY_CONTINUATION)

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

	//##########################################################################
	//####################    Entity::SharedData    ###########################
	//##########################################################################

	class Entity__SharedData:
		public Simulation::SharedData
	{
	public:
		Entity__SharedData(
			Derivation& derivation,
			Receiver::MessageHandlerSet &message_handlers,
			Entity::AttributeIndexSet &attribute_index,
			int state_count,
			Entity::MakeHandler make_handler
		):
			Simulation::SharedData(
				derivation,
				message_handlers,
				attribute_index,
				state_count
			),
			makeHandler(make_handler)
				{}

		Entity::MakeHandler			makeHandler;
	};

	inline Entity::SharedData*
		Entity::GetSharedData()
			{return Cast_Object(SharedData*,sharedData);}

	//##########################################################################
	//#####################    Entity::MakeMessage    ##########################
	//##########################################################################

	class Entity__MakeMessage:
		public Entity::Message
	{
	public:
		enum {
			MapStreamMarkerBit = Entity::Message::NextBit,
			NextBit
		};

		enum {
			MapStreamMarkerFlag = 1 << MapStreamMarkerBit
		};

		Entity::ClassID
			classToCreate;
		EntityID
			owningPlayerID;
		ResourceDescription::ResourceID
			resourceID;
		LWord
			instanceFlags;
		Origin
			localOrigin;

		Entity__MakeMessage(
			Receiver::MessageID message_ID,
			size_t length,
			Entity::ClassID class_ID,
			const EntityID &owner_ID,
			ResourceDescription::ResourceID resource_ID,
			LWord instance_flags,
			const Origin &origin
		):
			Entity::Message(message_ID, length),
			classToCreate(class_ID),
			owningPlayerID(owner_ID),
			resourceID(resource_ID),
			instanceFlags(instance_flags),
			localOrigin(origin)
				{}
		Entity__MakeMessage(
			Receiver::MessageID message_ID,
			size_t length,
			const EntityID &entity_ID,
			Entity::ClassID class_ID,
			const EntityID &owner_ID,
			ResourceDescription::ResourceID resource_ID,
			LWord instance_flags,
			const Origin &origin
		):
			Entity::Message(message_ID, length, entity_ID),
			classToCreate(class_ID),
			owningPlayerID(owner_ID),
			resourceID(resource_ID),
			instanceFlags(instance_flags),
			localOrigin(origin)
				{}
	};

	//##########################################################################
	//####################    Entity::UpdateMessage    #########################
	//##########################################################################

	class Entity__UpdateMessage:
		public Entity::Message
	{
	public:
		Entity__UpdateMessage(
			Receiver::MessageID message_ID,
			size_t length
		):
			Entity::Message(message_ID, length)
				{messageFlags &= ~ReliableFlag;}
	};

	//##########################################################################
	//##################    Entity::TakeDamageMessage    #######################
	//##########################################################################

	class Entity__TakeDamageMessage:
		public Entity::Message
	{
	public:
		EntityID
			inflictingEntity;

		// WARNING:
		// Since the current collision system cannot resolve the damage zone of
		// entities with  multiple damage zones, specializations of Entity's
		// TakeDamage message handler are responsible for handling an invalid zone.
		// Mechs use cylinder lookup table.
		// For BattleTech, damage zones are only valid via reticle based weapons.
		// Due to existing RP implementation, damageZone is not an optional
		// arg to the constructor.

		int
			damageZone;
		Logical invalidDamageZone;

		Damage
			damageData;


		// NOTE:
		// BattleTech's message manager needs to know the subsystemID of the
		// inflicting weapon in order to bundle explosion resource IDs.

		int inflictingSubsystemID;
		Logical invalidSubsystem;

		Entity__TakeDamageMessage(
			Receiver::MessageID message_ID,
			size_t length,
			const EntityID &entity_ID,
			int damage_zone,
			Damage &damage
		):
			Entity::Message(message_ID, length),
			inflictingEntity(entity_ID),
			damageZone(damage_zone),
			damageData(damage),
			invalidDamageZone(damageZone<0),
			inflictingSubsystemID(-1),
			invalidSubsystem(inflictingSubsystemID<0)

				{ }

		Entity__TakeDamageMessage(
			Receiver::MessageID message_ID,
			size_t length,
			const EntityID &entity_ID,
			int damage_zone,
			Damage &damage,
			int inflicting_subsystem_ID
		):
			Entity::Message(message_ID, length),
			inflictingEntity(entity_ID),
			damageZone(damage_zone),
			damageData(damage),
			invalidDamageZone(damageZone<0),
			inflictingSubsystemID(inflicting_subsystem_ID),
			invalidSubsystem(inflictingSubsystemID<0)
				{ }
	};

	//##########################################################################
	//###############   Entity::TakeDamageStreamMessage    #####################
	//##########################################################################

	class Entity__TakeDamageStreamMessage :
		public Entity::Message
	{
		//
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		// Holds A Group Of Damage Messages with some Common Fields
		// used for instantaneous hit weapons
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		//
		public:
			Point3D
				impactPoint;
			int
				damageZoneIndex;
			EntityID
				shootingEntity;

			Entity__TakeDamageStreamMessage(
				Entity::MessageID message_ID,
				size_t message_size,
				const EntityID &shooting_entity,
				int damage_zone_index,
				const Point3D &impact_point
			):
				Entity::Message(message_ID, message_size),
				shootingEntity(shooting_entity),
				damageZoneIndex(damage_zone_index),
				impactPoint(impact_point)
					{}

			~Entity__TakeDamageStreamMessage()
				{}
	};

	//##########################################################################
	//##################    Entity::PlayerLinkMessage    #######################
	//##########################################################################


	 class Entity__PlayerLinkMessage:
		public Entity::Message
	{
	public:
		EntityID
			playerID;

		Entity__PlayerLinkMessage(
			Receiver::MessageID message_ID,
			size_t length,
			EntityID player_id
		):
			Entity::Message(message_ID, length)
				{playerID = player_id;}
	};
	// Tool support function

	extern int
		Find_Subsystem_Index(
			NotationFile *file,
			const char* name
		);

	//##########################################################################
	//##################    Entity::PlayerLinkMessage    #######################
	//##########################################################################

	 class Entity__DestroyEntityMessage:
		public Entity::Message
	{
	public:
		Entity__DestroyEntityMessage(
			Receiver::MessageID message_ID,
			size_t length
		):
			Entity::Message(message_ID, length)
				{}
	};

	//##########################################################################
	//#################    Entity::DynamicMessage    ###########################
	//##########################################################################

	class Entity__DynamicMessage :
		public Receiver::DynamicMessage
	{
	public:
		Entity__DynamicMessage()
			{ }

		Entity__DynamicMessage(
			Entity::MessageID 	message_ID,
			size_t 					message_size = sizeof(Entity::Message)
		) : Receiver::DynamicMessage(message_ID, message_size)
			{ }

		Entity__DynamicMessage(
			void				   *message_ptr,
			size_t				stream_size,
			size_t 				initial_offset = sizeof(Entity::Message)
		) : Receiver::DynamicMessage(message_ptr, stream_size, initial_offset)
			{  }

		~Entity__DynamicMessage()
			{  }

	};



	//##########################################################################
	//#######################    Entity::MakeMapMessage    #####################
	//##########################################################################

	class Entity__MakeMapMessage:
		public Receiver::Message
	{
	public:
		//
		// The following fields need to be filled in by the sending manager
		//

		ResourceDescription::ResourceID
			resourceID;
		Origin
			localOrigin;

		Entity__MakeMapMessage(
			Receiver::MessageID messageID,
			size_t length
		):
			Receiver::Message(messageID, length)
				{}
	};

#endif

