// ----------------------------------------------------------------------- //
//
// MODULE  : LOFProxMineTrigger.h
//
// PURPOSE : ProxMineTrigger - Implementation
//
// CREATED : 1/3/99 by Ewen Vowels for Anarchy Arts
//
// ----------------------------------------------------------------------- //

#include "LOFProxMineTrigger.h"
#include "cpp_server_de.h"
#include "RiotObjectUtilities.h"
#include "InventoryTypes.h"
#include "RiotMsgIds.h"
#include "PlayerObj.h"
#include <stdio.h>

BEGIN_CLASS(ProxMineTrigger)
	ADD_VECTORPROP_VAL_FLAG(Dims, 128.0f, 128.0f, 128.0f, PF_DIMS) 
END_CLASS_DEFAULT_FLAGS(ProxMineTrigger, BaseClass, NULL, NULL, CF_HIDDEN)

// Static global variables...

#define UPDATE_DELTA					0.1f
#define TRIGGER_DEACTIVATION_TIME		0.001f
	
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	ProxMineTrigger::ProxMineTrigger()
//
//	PURPOSE:	Initialize object
//
// ----------------------------------------------------------------------- //

ProxMineTrigger::ProxMineTrigger() : BaseClass()
{
	VEC_SET( m_vDims, 128.0f, 128.0f, 128.0f );
	m_hProxMine = DNULL;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	ProxMineTrigger::~ProxMineTrigger()
//
//	PURPOSE:	Deallocate object
//
// ----------------------------------------------------------------------- //

ProxMineTrigger::~ProxMineTrigger()
{
	if (m_hProxMine) 
	{
		// don't remove the Proximity Mine, or ourself because the proximity mine
		// will handle removing us!
		m_hProxMine = DNULL;
	}
}

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

DDWORD ProxMineTrigger::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
	switch(messageID)
	{
		case MID_TOUCHNOTIFY:
		{
			ObjectTouch((HOBJECT)pData);
		}
		break;

		case MID_PRECREATE:
		{
			ObjectCreateStruct *pStruct = (ObjectCreateStruct *)pData;
			if (!pStruct) return 0;

			pStruct->m_UserData = USRFLG_IGNORE_PROJECTILES;
		}
		break;

		case MID_INITIALUPDATE:
		{
			if (fData != INITIALUPDATE_SAVEGAME)
			{
				InitialUpdate();
			}
		}
		break;

		case MID_LINKBROKEN :
		{
			HOBJECT hLink = (HOBJECT)pData;
			if (hLink == m_hProxMine)
			{
				m_hProxMine = DNULL;
			}
		}
		break;

		case MID_SAVEOBJECT:
		{
			Save((HMESSAGEWRITE)pData, (DDWORD)fData);
		}
		break;

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

		default : break;
	}


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


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	ProxMineTrigger::ObjectMessageFn
//
//	PURPOSE:	Handle object messages
//
// ----------------------------------------------------------------------- //

DDWORD ProxMineTrigger::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
	switch (messageID)
	{
		// gets a handle to the ProximityMine that created us!
		case MID_PROXMINE_INIT :
		{
			CServerDE* pServerDE = BaseClass::GetServerDE();
			if (pServerDE)
			{
				HOBJECT hPM = pServerDE->ReadFromMessageObject(hRead);
				SetProximityMine(hPM);
			}
		}
		break;
		//case MID_DAMAGE :
		// not used for now, but perhaps this should trigger the explosion?
		//break;
	}
	return BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	ProxMineTrigger::SetProximityMine
//
//	PURPOSE:	Set the proximity mine that made us
//
// ----------------------------------------------------------------------- //

void ProxMineTrigger::SetProximityMine(HOBJECT hObj)
{
	if (!hObj) return;

	m_hProxMine = hObj;
	
	// Make sure we don't create links with ourself...

	if (m_hObject != m_hProxMine)
	{
		CServerDE* pServerDE = GetServerDE();
		if (!pServerDE) return;

		pServerDE->CreateInterObjectLink(m_hObject, m_hProxMine);
	}
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Trigger::ObjectTouch
//
//	PURPOSE:	Handle object touch
//
// ----------------------------------------------------------------------- //

void ProxMineTrigger::ObjectTouch(HOBJECT hObj)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	HCLASS hClassBaseCharacter = pServerDE->GetClass("CBaseCharacter");
	HCLASS hClassObj		   = pServerDE->GetObjectClass(hObj);
	HCLASS hClassAI			   = pServerDE->GetClass("BaseAI");

	// Only AI and players can detonate the proximity mine...

	if (!pServerDE->IsKindOf(hClassObj, hClassBaseCharacter))
	{
		return;
	}

	if (m_hProxMine)
	{
		HMESSAGEWRITE hMsg = pServerDE->StartMessageToObject(this, m_hProxMine, MID_PROXMINE_TOUCHED);
		pServerDE->WriteToMessageObject(hMsg, hObj);
		pServerDE->EndMessage(hMsg);
	}
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	ProxMineTrigger::InitialUpdate
//
//	PURPOSE:	Initial update
//
// ----------------------------------------------------------------------- //

DBOOL ProxMineTrigger::InitialUpdate()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return DFALSE;

	pServerDE->SetObjectDims(m_hObject, &m_vDims);
	pServerDE->SetObjectFlags(m_hObject, FLAG_TOUCH_NOTIFY);
	pServerDE->SetObjectUserFlags(m_hObject, USRFLG_IGNORE_PROJECTILES);

	// Wait until my object touch notification message 'wakes' me up
	pServerDE->SetNextUpdate(m_hObject, 0.0f);
	pServerDE->SetDeactivationTime(m_hObject, TRIGGER_DEACTIVATION_TIME);
	return DTRUE;
}


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

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

	pServerDE->WriteToLoadSaveMessageObject(hWrite, m_hProxMine);
}


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

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

	pServerDE->ReadFromLoadSaveMessageObject(hRead, &m_hProxMine);
}

