class BaseBullet extends BaseProjectile
{
	private var m_meshComponent : IComponent;
	protected var m_countTime : Float;
	protected editable var m_startVelocity : Float;
	protected editable var m_acceleration : Float;
	protected editable var m_lifetime : Float;
	private var m_alive : Bool;
	default m_alive = true;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		super.OnRequestComponents( ri );
		EntityRequestComponentsInterface.RequestComponent( ri, 'MeshComponent', 'IComponent', true );
	}

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

	private function Reset()
	{
		m_countTime = 0.0;
		m_alive = true;
		m_meshComponent.Toggle( true );
	}

	protected event OnProjectileInitialize( eventData : gameprojectileSetUpEvent )
	{
		var linearParams : LinearTrajectoryParams;
		linearParams = new LinearTrajectoryParams;
		linearParams.startVel = m_startVelocity;
		linearParams.acceleration = m_acceleration;
		m_projectileComponent.AddLinear( linearParams );
		m_projectileComponent.ToggleAxisRotation( true );
		m_projectileComponent.AddAxisRotation( Vector4( 0.0, 1.0, 0.0, 0.0 ), 100.0 );
	}

	private function StartTrailEffect()
	{
		m_projectileComponent.SpawnTrailVFX();
		GameObject.PlaySoundEvent( this, 'Time_Dilation_Bullet_Trails_bullets_normal' );
	}

	protected event OnShoot( eventData : gameprojectileShootEvent )
	{
		Reset();
		StartTrailEffect();
	}

	protected event OnShootTarget( eventData : gameprojectileShootTargetEvent )
	{
		Reset();
		StartTrailEffect();
	}

	protected event OnTick( eventData : gameprojectileTickEvent )
	{
		m_countTime += eventData.deltaTime;
		if( ( m_countTime > m_lifetime ) || !( m_alive ) )
		{
			Release();
		}
	}

	protected event OnCollision( eventData : gameprojectileHitEvent )
	{
		if( m_alive )
		{
			GameObject.PlaySoundEvent( this, 'Stop_Time_Dilation_Bullet_Trails_bullets_normal' );
			DealDamage( eventData );
		}
	}

	protected virtual function DealDamage( eventData : gameprojectileHitEvent )
	{
		var object : GameObject;
		var i : Int32;
		var damageEffect : EffectInstance;
		damageEffect = m_projectileComponent.GetGameEffectInstance();
		EffectData.SetVariant( damageEffect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.projectileHitEvent, eventData );
		damageEffect.Run();
		for( i = 0; i < eventData.hitInstances.Size(); i += 1 )
		{
			object = ( ( GameObject )( eventData.hitInstances[ i ].hitObject ) );
			if( !( object.HasTag( 'bullet_no_destroy' ) ) )
			{
				m_countTime = 0.0;
				m_alive = false;
				m_meshComponent.Toggle( false );
				m_projectileComponent.ClearTrajectories();
				break;
			}
		}
	}

	protected function PerformAttack( eventData : gameprojectileHitEvent )
	{
		var explosionAttack : Attack_GameEffect;
		var explosionEffect : EffectInstance;
		var attackContext : AttackInitContext;
		var statMods : array< gameStatModifierData >;
		attackContext.record = TweakDBInterface.GetAttackRecord( T"Attacks.REMOVE_BulletWithDamage" );
		attackContext.instigator = this;
		attackContext.source = this;
		explosionAttack = ( ( Attack_GameEffect )( IAttack.Create( attackContext ) ) );
		explosionEffect = explosionAttack.PrepareAttack( this );
		explosionAttack.GetStatModList( statMods );
		EffectData.SetVariant( explosionEffect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.attack, ( ( IAttack )( explosionAttack ) ) );
		EffectData.SetVariant( explosionEffect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.attackStatModList, statMods );
		EffectData.SetVariant( explosionEffect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.projectileHitEvent, eventData );
		explosionAttack.StartAttack();
	}

}

