// ----------------------------------------------------------------------- //
//
// MODULE  : LOFAlienSonic.cpp
//
// PURPOSE : AlienSonic - Implementation
//
// CREATED : 28/1/99 - by Ewen Vowels for Anarchy-Arts
//
// ----------------------------------------------------------------------- //

#include "LOFAlienSonic.h"


#define ANIM_LASER		"SHREDDER"

#define ASSAULTRIFLE_PERCENTAGE	50

// These values are used as offsets from the model position for the indicated
// weapon...

#define NUM_LASER_POS 1
DVector s_vSonicLaserPos[1] =
{	// F,     U,     R
	DVector(42.0f, 13.0f, 0.0f)
};

BEGIN_CLASS(AlienSonic)
	ADD_LONGINTPROP( State, Vehicle::AGGRESSIVE )
	ADD_LONGINTPROP(WeaponId, GUN_LASERCANNON_ID)
	ADD_STRINGPROP_FLAG(Filename, GetModel(MI_AI_ALIENSONIC_ID), PF_DIMS | PF_HIDDEN )
	ADD_BOOLPROP_FLAG(Small, 0, PF_HIDDEN)
END_CLASS_DEFAULT(AlienSonic, Vehicle, NULL, NULL)

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::AlienSonic()
//
//	PURPOSE:	Constructor
//
// ----------------------------------------------------------------------- //

AlienSonic::AlienSonic() : Vehicle()
{
	m_nModelId	 = MI_AI_ALIENSONIC_ID;
	m_bIsMecha	 = DTRUE;

	m_hLaserAni	= INVALID_ANI;
	m_nWeaponId = GUN_LASERCANNON_ID;

	m_pIdleSound = "Sounds\\Enemies\\Vehicle\\AlienSonic\\Idle.wav";
	m_pRunSound	 = "Sounds\\Enemies\\Vehicle\\AlienSonic\\Run.wav";

	m_bCreateHandHeldWeapon	= DFALSE;
	m_bChangeAnimation		= DFALSE;
	m_cc		 = ALIEN;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::SetAnimationIndexes()
//
//	PURPOSE:	Initialize model animation indexes
//
// ----------------------------------------------------------------------- //
	
void AlienSonic::SetAnimationIndexes()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !m_hObject) return;

	Vehicle::SetAnimationIndexes();

	m_hLaserAni	= pServerDE->GetAnimIndex(m_hObject, ANIM_LASER);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::UpdateWeapon()
//
//	PURPOSE:	Update the our weapon
//
// ----------------------------------------------------------------------- //

void AlienSonic::UpdateWeapon()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !m_hObject) return;

	m_bChangeAnimation = DFALSE;

	// See if we are firing...

	if (IsFiring())
	{
		// If we just started firing, figure out what weapon/animation to use...

		if (!(m_dwLastAction & AI_AFLG_FIRE))
		{
			m_bChangeAnimation = DTRUE;
		}
	}

	Vehicle::UpdateWeapon();
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::UpdateAnimation()
//
//	PURPOSE:	Update the current animation
//
// ----------------------------------------------------------------------- //

void AlienSonic::UpdateAnimation()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !m_hObject) return;


	// See if we should change our animation...

	if (m_bChangeAnimation)
	{
		m_bAllowMovement = DFALSE;

		ModelSize eSize				= MS_NORMAL;
		DFLOAT	fMinFireDuration	= 1.0f;
		DFLOAT	fMaxFireDuration	= 2.0f;
		DFLOAT	fMinFireRest		= 3.0f;
		DFLOAT	fMaxFireRest		= 6.0f;

		//m_nWeaponId = GUN_LASERCANNON_ID;
		SetAnimation(m_hLaserAni, DTRUE);
/*
		m_weapons.ObtainWeapon(m_nWeaponId);
		m_weapons.DeselectCurWeapon();
		m_weapons.ChangeWeapon(m_nWeaponId);
		m_weapons.AddAmmo(m_nWeaponId, GetWeaponMaxAmmo(m_nWeaponId));
*/

		CWeapon* pWeapon = m_weapons.GetCurWeapon();
		if (pWeapon) 
		{
			pWeapon->SetSize(eSize);
			pWeapon->SetMinFireDuration(fMinFireDuration);
			pWeapon->SetMaxFireDuration(fMaxFireDuration);
			pWeapon->SetMinFireRest(fMinFireRest);	
			pWeapon->SetMaxFireRest(fMaxFireRest);
		}
	}
	else if (!IsFiring())
	{
		m_bAllowMovement = DTRUE;

		Vehicle::UpdateAnimation();
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::GetFirePos()
//
//	PURPOSE:	Get the current weapon fire position
//
// ----------------------------------------------------------------------- //

DVector AlienSonic::GetFirePos(DVector* pvPos)
{
	DVector vPos;
	VEC_INIT(vPos);

	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !m_hObject || !pvPos) return vPos;

	DVector vOffset;
	int nIndex = GetRandom(0, NUM_LASER_POS-1);
	VEC_COPY(vOffset, s_vSonicLaserPos[nIndex]);

	// Adjust fire position...

	DRotation rRot;
	pServerDE->GetObjectRotation(m_hObject, &rRot);

	DVector vU, vF, vR;
	pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

	DVector vTemp;
	VEC_MULSCALAR(vTemp, vF, vOffset.x);
	VEC_ADD(vPos, *pvPos, vTemp);

	VEC_MULSCALAR(vTemp, vU, vOffset.y);
	VEC_ADD(vPos, *pvPos, vTemp);

	VEC_MULSCALAR(vTemp, vR, vOffset.z);
	VEC_ADD(vPos, *pvPos, vTemp);

	return vPos;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::EngineMessageFn
//
//	PURPOSE:	Handle engine messages
//
// ----------------------------------------------------------------------- //

DDWORD AlienSonic::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
	switch(messageID)
	{
		case MID_SAVEOBJECT:
		{
			Save((HMESSAGEWRITE)pData, (DDWORD)fData);
		}
		break;

		case MID_LOADOBJECT:
		{
			Load((HMESSAGEREAD)pData, (DDWORD)fData);
		}
		break;

		default : break;
	}

	return Vehicle::EngineMessageFn(messageID, pData, fData);
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::Save
//
//	PURPOSE:	Save the object
//
// ----------------------------------------------------------------------- //

void AlienSonic::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !hWrite) return;

	pServerDE->WriteToMessageDWord(hWrite, m_hLaserAni);
	pServerDE->WriteToMessageByte(hWrite, m_bSaveAllowmovement);
	pServerDE->WriteToMessageByte(hWrite, m_bChangeAnimation);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	AlienSonic::Load
//
//	PURPOSE:	Load the object
//
// ----------------------------------------------------------------------- //

void AlienSonic::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE || !hRead) return;

	m_hLaserAni				= pServerDE->ReadFromMessageDWord(hRead);
	m_bSaveAllowmovement	= pServerDE->ReadFromMessageByte(hRead);
	m_bChangeAnimation		= pServerDE->ReadFromMessageByte(hRead);
}
