
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_InventoryWeapon_Shotgun.cpp
// Author : Chris Wallace
// Date   : 04-Feb-2009
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header...
#include "Inventory/Items/Weapons/AVP_InventoryWeapon_Shotgun.h"

// Asura independent header-files...
#include "Sound/Asura_Sound_Event_Storage.h"

// Game independent header-files...
#include "Inventory/AVP_Inventory_Group.h"
#include "Inventory/AVP_Inventory_HashIDs.h"
#include "Inventory/AVP_Inventory_System.h"
#include "Inventory/AVP_AmmoStore.h"

#include "Actor/Vertebrates/AVP_Vertebrate_InputHandler.h"
#include "Actor/Vertebrates/Human/AVP_Human_HUDHandler.h"
#include "Entity/PhysicalObject/Actor/AVP_ClientEntity_Actor.h"

AVP_InventoryWeapon_Shotgun::AVP_InventoryWeapon_Shotgun( AVP_Inventory_Group& xParentGroup, const Asura_Hash_ID uHash, const Asura_Hash_ID uBlueprintHash )
: PARENT(xParentGroup, uHash, uBlueprintHash)
{
	m_eItemType = AVP_INVENTORYITEMTYPE_SHOTGUN;
}

void AVP_InventoryWeapon_Shotgun::HandleReload( void )
{
	// Get our ammo store
	AVP_AmmoStore* pxAmmoStore = GetParentSystem().GetAmmoStore();

	AVP_AmmoStore::ReloadSubTypeFromAmmoStore(m_ppxSubTypes[ST_PRIMARY], pxAmmoStore);
}

bool AVP_InventoryWeapon_Shotgun::HandleHalfShot(int& iFullBulletsToFire)
{
	PARENT::HandleHalfShot(iFullBulletsToFire);
	
	AVP_RangedWeapon_SubType* pxSubType = static_cast<AVP_RangedWeapon_SubType*>(GetSubTypeFromUsageType(GetCurrentUsageType()));
	if ( pxSubType && pxSubType->GetCurrentQuantity() >= 1.0f )
	{
		SetCurrentUsageType(UT_N_BULLET_BURST_PRIMARY);

		iFullBulletsToFire = 1; // Fire off last shell

		const Asura_Sound_Event* pxSoundEvent = Asura_Sound_Event_Storage::FindEvent( static_cast<AVP_RangedWeapon_SubType*>(GetSubTypeFromUsageType(GetCurrentUsageType()))->GetClickHash() );
		if(pxSoundEvent)
		{
			if(GetParentSystem().IsClientSide())
			{
				Asura_Sound_Event_System::PlayEvent( pxSoundEvent, NULL, NULL );
			}
		}
		return true;
	}
	return false;
}

void AVP_InventoryWeapon_Shotgun::ProcessPlayerInput( const AVP_ClientEntity_Actor& xActor )
{
	AVP_InventoryItem_Weapon::ProcessPlayerInput( xActor ); // Replaces parent call - but call to layer below that...

	const AVP_Actor_InputHandler* pxInputHandler = xActor.GetInputHandler();
	if ( GetCurrentState() == IDLING && pxInputHandler != NULL && ( GetTimeInState() > 0.0f ) )
	{
		// Work out if we should reload...
		const bool bNoPrimaryAmmo		= m_ppxSubTypes[ ST_PRIMARY ]->IsEmpty();
		const bool bNoSecondaryAmmo		= this->GetNumSubTypes() == 2 ? m_ppxSubTypes[ ST_SECONDARY ]->IsEmpty() : true;
		const bool bNoAmmo				= bNoPrimaryAmmo && bNoSecondaryAmmo;

		bool bAllowReload = ShouldAllowReload();

		bool bFiredPrimary = false;
		// Check for the appropriate input...
		if ( !xActor.IsMovingFast() )
		{
			if ( ( pxInputHandler->GetControlMapValue( AVP_Vertebrate_InputHandler::RELOAD ) > 0.0f ) && bAllowReload && CanReload() )
			{
				RequestUsing( UT_RELOAD_ALL );
			}
			else
			{
				if ( m_ppxSubTypes[ ST_PRIMARY ] != NULL )
				{
					if ( pxInputHandler->GetControlMapValue( AVP_Vertebrate_InputHandler::PRIMARY_ATTACK_TAP ) > 0.0f && ( !bNoAmmo ) )
					{
						if ( m_fPrimaryShotTimer <= 0.0f )
						{
							m_fPrimaryShotTimer = 1.0f / ( static_cast< AVP_RangedWeapon_SubType* >( m_ppxSubTypes[ ST_PRIMARY ] ) )->GetRateOfFire();
							RequestUsing( UT_N_BULLET_BURST_PRIMARY );
							bFiredPrimary = true;
						}
					}
				}

				if ( !bFiredPrimary && this->GetNumSubTypes() == 2 )
				{
					
					if ( pxInputHandler->GetControlMapValue( AVP_Vertebrate_InputHandler::SECONDARY_ATTACK_TAP ) > 0.0f && ( !bNoAmmo ) )
					{
						if ( m_fSecondaryShotTimer <= 0.0f )
						{
							m_fSecondaryShotTimer = 1.0f / ( static_cast< AVP_RangedWeapon_SubType* >( m_ppxSubTypes[ ST_SECONDARY ] ) )->GetRateOfFire();
							RequestUsing( UT_N_BULLET_BURST_SECONDARY );
						}
					}
				}
			}
		}
	}
}


void AVP_InventoryWeapon_Shotgun::CheckForAutomaticReload(void)
{
	const AVP_Inventory_System&	xParentSystem	= GetParentSystem();

	if(xParentSystem.IsMaster())
	{
		const float	fTimeInState	= 1.0f;	//GetTimeInState();

		if(fTimeInState >= 0.100f)
		{
			int iIndex = GetSubTypeIndexFromUsageType(UT_N_BULLET_BURST_PRIMARY);

			// Sanity check
			if(iIndex>=static_cast<int>(m_uNumSubTypes))
			{
				Asura_Assert(false, "Shotgun checking to reload on a subtype that does not exist!");
				return;
			}

			AVP_RangedWeapon_SubType* pxSubType = static_cast<AVP_RangedWeapon_SubType*>(m_ppxSubTypes[ iIndex ]);

			if( pxSubType && pxSubType->ReadyToAutoReloadNow() )	
			{
				if(GetParentSystem().GetAmmoStore())
				{
					bool bPrimaryAmmoAvailable = GetParentSystem().GetAmmoStore()->GetAmmoQuantity(pxSubType->GetAmmoType())>=1.0f;
					if(bPrimaryAmmoAvailable)
					{
						DoReloadMuzzleSmoke( iIndex );
						RequestUsing(UT_RELOAD_ALL);
						return;
					}
				}
			}
		}
	}
}

/// End of file. ///
