//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================//

#include "cbase.h"
#include "tf_passtime_ball.h"
#include "tf_passtime_logic.h"
#include "trigger_passtime_ball.h"
#include "tf_player.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

//----------------------------------------------------------------------
LINK_ENTITY_TO_CLASS( trigger_passtime_ball, CTriggerPasstimeBall );

//-----------------------------------------------------------------------------
BEGIN_DATADESC( CTriggerPasstimeBall )
	DEFINE_OUTPUT( m_onBallEnter, "OnBallEnter" ),
	DEFINE_OUTPUT( m_onBallExit, "OnBallExit" ),
END_DATADESC()

//-----------------------------------------------------------------------------
void CTriggerPasstimeBall::Spawn()
{
	m_bPresent = false;
	BaseClass::Spawn();

	SetSolid( SOLID_BSP );	
	AddSolidFlags( FSOLID_NOT_SOLID | FSOLID_TRIGGER );
	SetMoveType( MOVETYPE_NONE );
	SetModel( STRING( GetModelName() ) );    // set size and link into world
	AddEffects( EF_NODRAW );

	SetThink( &CTriggerPasstimeBall::Update );
	SetNextThink( gpGlobals->curtime );
}

//-----------------------------------------------------------------------------
static CBaseEntity *s_EntitiesInSphere[32];
bool CTriggerPasstimeBall::BTouching( CBaseEntity *pEnt )
{
	Ray_t ray;
	trace_t tr;
	ICollideable *pCollide = CollisionProp();
	ray.Init( pEnt->GetAbsOrigin(), pEnt->GetAbsOrigin() );
	enginetrace->ClipRayToCollideable( ray, MASK_ALL, pCollide, &tr );
	return ( tr.startsolid );
}

//-----------------------------------------------------------------------------
void CTriggerPasstimeBall::Update()
{
	// This is a crappy way to do this, but I couldn't find any way to make
	// a normal trigger do what I want because I want enter/exit to be handled
	// correctly when the ball is hidden.
	// It would be more efficient to have the ball do this, but I'm 
	// trying to isolate this hack to where it makes the most sense.

	SetNextThink( gpGlobals->curtime );
	
	if ( !g_pPasstimeLogic || !g_pPasstimeLogic->GetBall() )
		return;

	CPasstimeBall *pBall = g_pPasstimeLogic->GetBall();
	CBaseEntity *pEnt = pBall->GetCarrier();
	if ( !pEnt ) pEnt = pBall;

	bool bPresentNow = (pEnt && BTouching( pEnt ));
	if ( bPresentNow && !m_bPresent )
	{
		m_onBallEnter.FireOutput( this, this );
	}
	else if ( !bPresentNow && m_bPresent )
	{
		m_onBallExit.FireOutput( this, this );
	}
	m_bPresent = bPresentNow;
}