class MineBarrageProjectile extends BaseProjectile
{
	private editable var m_landIndicatorFX : FxResource;
	var m_fxInstance : FxInstance;
	var m_visualComponent : MeshComponent;
	var m_onGround : Bool;
	var m_onGroundTimer : Float;
	var m_weapon : weak< WeaponObject >;
	var m_attack_record : Attack_Record;
	var m_detonationTimer : Float;
	var m_explosionRadius : Float;
	var m_playerPuppet : weak< PlayerPuppet >;
	protected var m_mappinID : NewMappinID;

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		super.OnTakeControl( ri );
		m_visualComponent = ( ( MeshComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'MeshComponent' ) ) );
	}

	protected event OnProjectileInitialize( eventData : gameprojectileSetUpEvent )
	{
		var attack : IAttack;
		super.OnProjectileInitialize( eventData );
		m_explosionRadius = AITweakParams.GetFloatFromTweak( T"Attacks.MineMissileChimera", "explosionRadius" );
		m_user = eventData.owner;
		m_weapon = ( ( WeaponObject )( eventData.weapon ) );
		m_detonationTimer = AITweakParams.GetFloatFromTweak( T"Attacks.MineMissileChimera", "detonationTimer" );
		attack = m_weapon.GetCurrentAttack();
		m_attack_record = attack.GetRecord();
		m_playerPuppet = GetPlayer( GetGame() );
		m_projectileComponent.LockOrientation( true );
	}

	protected event OnTick( eventData : gameprojectileTickEvent )
	{
		var distanceToPlayer : Float;
		if( m_onGround )
		{
			distanceToPlayer = Vector4.DistanceSquared( Matrix.GetTranslation( m_projectileComponent.GetLocalToWorld() ), m_playerPuppet.GetWorldPosition() );
			m_onGroundTimer += eventData.deltaTime;
			if( ( m_onGroundTimer >= m_detonationTimer ) || ( distanceToPlayer <= m_explosionRadius ) )
			{
				Explode();
			}
		}
	}

	protected event OnShoot( eventData : gameprojectileShootEvent )
	{
		var grenadeMappinData : MappinData;
		var grenadeMappinScriptData : GrenadeMappinData;
		m_projectileSpawnPoint = eventData.startPoint;
		if( ( m_user != NULL ) && ( m_mappinID.value == ( ( Uint64 )( 0 ) ) ) )
		{
			grenadeMappinScriptData = new GrenadeMappinData;
			grenadeMappinScriptData.m_iconID = T"MappinIcons.GrenadeMappin";
			grenadeMappinData.mappinType = T"Mappins.InteractionMappinDefinition";
			grenadeMappinData.variant = gamedataMappinVariant.GrenadeVariant;
			grenadeMappinData.active = true;
			grenadeMappinData.scriptData = grenadeMappinScriptData;
			m_mappinID = GameInstance.GetMappinSystem( m_user.GetGame() ).RegisterGrenadeMappin( grenadeMappinData, ( ( GameObject )( this ) ) );
		}
	}

	protected event OnShootTarget( eventData : gameprojectileShootTargetEvent )
	{
		var parabolicParams : ParabolicTrajectoryParams;
		parabolicParams = ParabolicTrajectoryParams.GetAccelTargetAngleParabolicParams( Vector4( 0.0, 0.0, -7.0, 0.0 ), eventData.params.targetPosition, 30.0 );
		m_projectileComponent.AddParabolic( parabolicParams );
		m_projectileComponent.SetOnCollisionAction( gameprojectileOnCollisionAction.Stop );
		m_fxInstance = SpawnLandVFXs( m_landIndicatorFX, eventData.params.targetPosition );
		m_onGround = false;
		m_onGroundTimer = 0.0;
		if( m_weapon.GetItemData().HasTag( 'JurijProjectile' ) )
		{
			OnShoot( eventData );
		}
	}

	protected event OnCollision( eventData : gameprojectileHitEvent )
	{
		var hitInstance : gameprojectileHitInstance;
		var puppet : ScriptedPuppet;
		var normal : Vector4;
		var rotation : EulerAngles;
		var lastHitNormal : Vector4;
		normal = GameInstance.GetBlackboardSystem( GetGame() ).Get( GetAllBlackboardDefs().Mines ).GetVector4( GetAllBlackboardDefs().Mines.CurrentNormal );
		rotation = Vector4.ToRotation( normal );
		m_visualComponent.SetLocalOrientation( EulerAngles.ToQuat( rotation ) );
		hitInstance = eventData.hitInstances[ 0 ];
		puppet = ( ( ScriptedPuppet )( hitInstance.hitObject ) );
		if( !( puppet ) )
		{
			lastHitNormal = ( ( Vector4 )( hitInstance.traceResult.normal ) );
			if( Vector4.GetAngleBetween( lastHitNormal, Vector4( 0.0, 0.0, 1.0, 0.0 ) ) > 35.0 )
			{
				Explode();
			}
			m_onGround = true;
			m_onGroundTimer = 0.0;
		}
		else
		{
			Explode();
		}
	}

	protected function ReleaseMappin()
	{
		if( m_mappinID.value != ( ( Uint64 )( 0 ) ) )
		{
			GameInstance.GetMappinSystem( m_user.GetGame() ).UnregisterMappin( m_mappinID );
			m_mappinID.value = ( ( Uint64 )( 0 ) );
		}
	}

	protected virtual function Explode()
	{
		var attack : Attack_GameEffect;
		var effect : EffectInstance;
		var attackContext : AttackInitContext;
		var flag : SHitFlag;
		var hitFlags : array< SHitFlag >;
		var explosionAttackRecord : Attack_Record;
		var explosionRange : Float;
		explosionRange = AITweakParams.GetFloatFromTweak( T"Attacks.MineMissileChimera", "explosionRange" );
		explosionAttackRecord = IAttack.GetExplosiveHitAttack( m_attack_record );
		attackContext.record = explosionAttackRecord;
		attackContext.instigator = m_user;
		attackContext.source = m_user;
		attackContext.weapon = m_weapon;
		attack = ( ( Attack_GameEffect )( IAttack.Create( attackContext ) ) );
		effect = attack.PrepareAttack( m_user );
		flag.flag = hitFlag.CanDamageSelf;
		flag.source = 'GrenadeDetonation';
		hitFlags.PushBack( flag );
		EffectData.SetVariant( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.flags, hitFlags );
		EffectData.SetFloat( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.range, explosionRange );
		EffectData.SetFloat( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.radius, m_explosionRadius );
		EffectData.SetVector( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.position, GetWorldPosition() );
		EffectData.SetVariant( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.attack, ( ( IAttack )( attack ) ) );
		attack.StartAttack();
		m_projectileComponent.ClearTrajectories();
		m_fxInstance.BreakLoop();
		SetMeshVisible( false );
		Release();
		if( m_weapon.GetItemData().HasTag( 'JurijProjectile' ) )
		{
			ReleaseMappin();
		}
	}

	protected event OnHit( evt : gameHitEvent )
	{
		var instigatorIsPlayer : Bool;
		instigatorIsPlayer = evt.attackData.GetInstigator() == GetPlayer( GetGame() );
		if( instigatorIsPlayer )
		{
			Explode();
		}
	}

}

