//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose: Resource chunks
//
// $NoKeywords: $
//=============================================================================
#include "cbase.h"
#include "tf_func_resource.h"
#include "tf_team.h"
#include "tf_basecombatweapon.h"
#include "tf_obj.h"
#include "resource_chunk.h"
#include "vstdlib/random.h"
#include "tf_stats.h"
#include "engine/IEngineSound.h"

ConVar	resource_chunk_value( "resource_chunk_value","20", FCVAR_NONE, "Resource value of a single resource chunk." );
ConVar	resource_chunk_processed_value( "resource_chunk_processed_value","80", FCVAR_NONE, "Resource value of a single processed resource chunk." );

// Resource Chunk Models
char *sResourceChunkModel = "models/resources/resource_chunk_B.mdl";
char *sProcessedResourceChunkModel = "models/resources/processed_resource_chunk_B.mdl";

BEGIN_DATADESC( CResourceChunk )

	// functions
	DEFINE_FUNCTION( CResourceChunk, ChunkTouch ),
	DEFINE_FUNCTION( CResourceChunk, ChunkRemove ),

END_DATADESC()

IMPLEMENT_SERVERCLASS_ST( CResourceChunk, DT_ResourceChunk )
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( resource_chunk, CResourceChunk );
PRECACHE_REGISTER( resource_chunk );

//-----------------------------------------------------------------------------
// Purpose: Remove me from any lists I'm in when I'm deleted
//-----------------------------------------------------------------------------
void CResourceChunk::UpdateOnRemove( void )
{
	if ( m_hZone )
	{
		m_hZone->RemoveChunk( this, false );
		m_hZone = NULL;
	}

	// Chain at end to mimic destructor unwind order
	BaseClass::UpdateOnRemove();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CResourceChunk::Spawn( )
{
	// Init model
	if ( IsProcessed() )
	{
		SetModelName( MAKE_STRING( sProcessedResourceChunkModel ) );
	}
	else
	{
		SetModelName( MAKE_STRING( sResourceChunkModel ) );
	}

	BaseClass::Spawn();

	UTIL_SetSize( this, Vector(-4,-4,-4), Vector(4,4,4) );
	SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
	SetSolid( SOLID_BBOX );
	SetSolidFlags( FSOLID_TRIGGER );
	SetCollisionGroup( TFCOLLISION_GROUP_RESOURCE_CHUNK );
	SetGravity( 1.0 );
	SetFriction( 1 );
	SetTouch( ChunkTouch );
	SetThink( ChunkRemove );
	SetNextThink( gpGlobals->curtime + random->RandomFloat( 50.0, 80.0 ) ); // Remove myself the
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CResourceChunk::Precache( void )
{
	engine->PrecacheModel( sResourceChunkModel );
	engine->PrecacheModel( sProcessedResourceChunkModel );
	engine->PrecacheModel( "sprites/redglow1.vmt" );
}

//------------------------------------------------------------------------------
// Purpose : Override to make chunks easier to pick up
//------------------------------------------------------------------------------
void CResourceChunk::SetObjectCollisionBox( void )
{
	ComputeSurroundingBox();

	SetAbsMins( GetAbsMins() + Vector( -24, -24, -24 ) );
	SetAbsMaxs( GetAbsMaxs() + Vector( 24, 24, 24 ) );
}

//-----------------------------------------------------------------------------
// Purpose: Create a resource chunk
//-----------------------------------------------------------------------------
CResourceChunk *CResourceChunk::Create( bool bProcessed, const Vector &vecOrigin, const Vector &vecVelocity )
{
	CResourceChunk *pChunk = (CResourceChunk*)CreateEntityByName("resource_chunk");

	UTIL_SetOrigin( pChunk, vecOrigin );
	pChunk->m_bIsProcessed = bProcessed;
	pChunk->m_bBeingCollected = false;
	pChunk->Spawn();
	pChunk->SetAbsVelocity( vecVelocity );
	pChunk->SetLocalAngularVelocity( RandomAngle( -100, 100 ) );
	pChunk->SetLocalAngles( vec3_angle );

	return pChunk;
}

//-----------------------------------------------------------------------------
// Purpose: If we're picked up by another pla`yer, give resources to that team
//-----------------------------------------------------------------------------
void CResourceChunk::ChunkTouch( CBaseEntity *pOther )
{
	if ( pOther->IsPlayer() || pOther->GetServerVehicle() )
	{
		// Give the team the resources
		int iAmountPerPlayer = ((CTFTeam *)pOther->GetTeam())->AddTeamResources( GetResourceValue(), TF_PLAYER_STAT_RESOURCES_ACQUIRED_FROM_CHUNKS );
		TFStats()->IncrementTeamStat( pOther->GetTeamNumber(), TF_TEAM_STAT_RESOURCE_CHUNKS_COLLECTED, GetResourceValue() );

		pOther->EmitSound( "ResourceChunk.Pickup" );

		// Tell the player
		CSingleUserRecipientFilter user( (CBasePlayer*)pOther );
		UserMessageBegin( user, "PickupRes" );
			WRITE_BYTE( iAmountPerPlayer ); 
		MessageEnd();

		// Tell our zone to remove this chunk from it's list
		if ( m_hZone )
		{
			m_hZone->RemoveChunk( this, false );
			m_hZone = NULL;
		}

		// Remove this chunk
		SetTouch( NULL );
		UTIL_Remove( this );
		return;
	}
}

//-----------------------------------------------------------------------------
// Purpose: Remove myself if I'm not being harvested
//-----------------------------------------------------------------------------
void CResourceChunk::ChunkRemove( void )
{
	// Remove this chunk
	if ( m_hZone )
	{
		m_hZone->RemoveChunk( this, true );
		m_hZone = NULL;
	}
	UTIL_Remove( this );
}


//-----------------------------------------------------------------------------
// Purpose: Return the resource value of this chunk
//-----------------------------------------------------------------------------
float CResourceChunk::GetResourceValue( void )
{
	// Init value & model
	if ( IsProcessed() )
		return resource_chunk_processed_value.GetFloat();

	return resource_chunk_value.GetFloat();
}