//===========================================================================//
// File:	MODL.cpp											
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 05/21/01  JPS	Class for the MODL in the expansion

//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "MW4Headers.hpp"

#include "MODL.hpp"
#include "gameinfo.hpp"
#include "AI.hpp"
#include "AI_UserConstants.hpp"
#include "Mech.hpp"
#include "Torso.hpp"
#include "MWDamageObject.hpp"
#include <adept\effect.hpp>
#include <Adept\Site.hpp>
#include "obstacle.hpp"

#include <Adept\EntityManager.hpp>
#include <Adept\CollisionVolume.hpp>
#include <Adept\DamageObject.hpp>
#include <Adept\Map.hpp>

//#############################################################################
//###############################    MODL    ##############################
//#############################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MODL::ClassData*
	MODL::DefaultData = NULL;


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MODL::InitializeClass()
{
	Check_Object(MWMover::ExecutionStateEngine::DefaultData);
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MODLClassID,
	        "MechWarrior4::MODL",
			BaseClass::DefaultData,
			0, NULL,
			(Entity::Factory)Make,
			(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
			ExecutionStateEngine::DefaultData,
			(Entity::GameModel::Factory)GameModel::ConstructGameModel,
			(Entity::GameModel::Factory)GameModel::ConstructOBBStream,
			(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
			(Entity::GameModel::ModelWrite)GameModel::WriteToText,
			(Entity::GameModel::ModelSave)GameModel::SaveGameModel,
			AnimationStateEngine::Make
		);
	Register_Object(DefaultData);

	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MODL::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MODL*
	MODL::Make(
		CreateMessage *message,
		ReplicatorID *base_id
	)

{
	Check_Object(message);
	gos_PushCurrentHeap(Heap);
	MODL *new_entity = new
		MODL(DefaultData, message, base_id, NULL);
	gos_PopCurrentHeap();
	Check_Object(new_entity);
	
	
	Check_Object(EntityManager::GetInstance());
	EntityManager::GetInstance()->AddMover(new_entity);
	return new_entity;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MODL::MODL(
	ClassData *class_data,
	CreateMessage *message,
	ReplicatorID *base_id,
	ElementRenderer::Element *element
):
	Tank(class_data, message, base_id, element),
	m_enginesDead (false),
	m_fireCannon (false)
{
	Check_Pointer(this);
	Check_Object(message);

	HookUpSubsystems();
	CommonCreation(message);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

MODL::~MODL()
{
	Check_Object(EntityManager::GetInstance());
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MODL::Reuse(
		const CreateMessage *message,
		ReplicatorID *base_id
	)
{
	Check_Object(this);
	Check_Object(message);

	STOP(("Not implemented"));
	BaseClass::Reuse(message, base_id);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MODL::CommonCreation(CreateMessage *message)
{
	Check_Object(this);
	Check_Object(message);

	InitializeDamageArray();

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MODL::Respawn(Entity::CreateMessage *message)
{
	Check_Object(this);
	Check_Object(message);

	BaseClass::Respawn(message);
	CreateMessage *vehicle_message = Cast_Pointer(CreateMessage *, message);
	CommonCreation(vehicle_message);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MODL::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}

void
	MODL::SaveInstanceText(Page *instance_page)
{
	Check_Object(this);
	Check_Object(instance_page);

	BaseClass::SaveInstanceText(instance_page);
}

void
	MODL::InitializeDamageArray()
{
	Check_Object(this);

	memset(damageArray, -1, sizeof(int) * 11);
	for(int i=0; i<11; i++)
	{
		DamageObject *damage_object = damageObjects.Find(i);
		if(damage_object)
		{
			damageArray[i] = damage_object->damageLevel;
			damage_object->SetDamageArrayEntry(&damageArray[i]);
		}
		else
		{
			damageArray[i] = -1;
		}
	}
}

void MODL::Eject()
{
	m_fireCannon = true;

}

void MODL::EngineDead(void)
{	
	//The engine internal damage zone has been destroyed,
	//The MODL must now stop
	m_enginesDead = true;

}

void
	MODL::ComputeForwardSpeed(Stuff::Scalar time_slice)
{
	if (m_enginesDead)
	{
		speedDemand = 0.0f;
		speedDemandKPH = 0.0f;
	}
	BaseClass::ComputeForwardSpeed (time_slice);
}


void MODL::PostCollisionExecute (Stuff::Time time)
{
	Tank::PostCollisionExecute(time);
	if (m_fireCannon)
	{
		//check to see if still has a right arm 
		DamageObject *damage_object = damageObjects.Find(3);
		if (damage_object->currentArmorValue != 0)
		{
			const GameModel *model = GetGameModel();
			Adept::Site* cannonSite = FindSite ("site_biggun");
			Resource resource(model->ejectEffectResource);
			Verify(resource.DoesResourceExist());
			CreateEffect (model->ejectEffectResource,cannonSite,true);
		}
		m_fireCannon = false;
	}
}




