class ExplodingBullet extends BaseBullet
{
	editable var explosionTime : Float;
	editable var effectReference : EffectRef;
	var hasExploded : Bool;
	var m_initialPosition : Vector4;
	var m_trailStarted : Bool;
	var m_weapon : weak< WeaponObject >;
	var m_attack_record : Attack_Record;
	var m_attackID : TweakDBID;
	editable var colliderBox : Vector4;
	editable var rotation : Quaternion;
	editable var range : Float;
	editable var explodeAfterRangeTravelled : Bool;
	default explodeAfterRangeTravelled = true;
	private var m_attack : IAttack;
	private var m_BulletCollisionEvaluator : BulletCollisionEvaluator;

	protected event OnProjectileInitialize( eventData : gameprojectileSetUpEvent )
	{
		super.OnProjectileInitialize( eventData );
		hasExploded = false;
		m_countTime = 0.0;
		m_user = eventData.owner;
		m_trailStarted = false;
		m_weapon = ( ( WeaponObject )( eventData.weapon ) );
		m_attack = m_weapon.GetCurrentAttack();
		m_attack_record = m_attack.GetRecord();
		m_attackID = m_attack_record.GetID();
		m_BulletCollisionEvaluator = new BulletCollisionEvaluator;
		m_projectileComponent.SetCollisionEvaluator( m_BulletCollisionEvaluator );
		m_BulletCollisionEvaluator.SetIsExplodingBullet( true );
		m_BulletCollisionEvaluator.SetUser( m_user );
	}

	protected event OnTick( eventData : gameprojectileTickEvent )
	{
		m_countTime += eventData.deltaTime;
		if( !( m_trailStarted ) )
		{
			GameObjectEffectHelper.StartEffectEvent( this, 'trail', true );
			m_trailStarted = true;
		}
		if( hasExploded )
		{
			Release();
		}
		if( ( m_countTime > explosionTime ) && !( hasExploded ) )
		{
			Explode();
		}
		if( Vector4.IsZero( m_initialPosition ) )
		{
			m_initialPosition = this.GetWorldPosition();
		}
		if( !( hasExploded ) && ( !( m_user ) || !( m_user.IsPlayer() ) ) )
		{
			GameInstance.GetAudioSystem( this.GetGame() ).TriggerFlyby( this.GetWorldPosition(), this.GetWorldForward(), m_initialPosition, m_weapon );
		}
	}

	protected event OnCollision( projectileHitEvent : gameprojectileHitEvent )
	{
		var object : GameObject;
		var isUserPlayer : Bool;
		var damage : EffectInstance;
		var damageHitEvent : gameprojectileHitEvent;
		var hitInstance : gameprojectileHitInstance;
		var i : Int32;
		damageHitEvent = new gameprojectileHitEvent;
		isUserPlayer = m_user == GameInstance.GetPlayerSystem( GetGame() ).GetLocalPlayerMainGameObject();
		for( i = 0; i < projectileHitEvent.hitInstances.Size(); i += 1 )
		{
			hitInstance = projectileHitEvent.hitInstances[ i ];
			object = ( ( GameObject )( hitInstance.hitObject ) );
			if( !( isUserPlayer && object.HasTag( 'ignore_player_bullets' ) ) )
			{
				damageHitEvent.hitInstances.PushBack( hitInstance );
				if( ( !( object.HasTag( 'bullet_no_destroy' ) ) && m_BulletCollisionEvaluator.HasReportedStopped() ) && hitInstance.position == m_BulletCollisionEvaluator.GetStoppedPosition() )
				{
					if( explodeAfterRangeTravelled && ( Vector4.Distance( m_initialPosition, hitInstance.position ) > range ) )
					{
						Explode( hitInstance.projectilePosition );
					}
					else if( explodeAfterRangeTravelled )
					{
						Release();
						GameObjectEffectHelper.BreakEffectLoopEvent( this, 'trail' );
					}
					else
					{
						Explode( hitInstance.projectilePosition );
					}
					break;
				}
			}
		}
		if( damageHitEvent.hitInstances.Size() > 0 )
		{
			damage = m_projectileComponent.GetGameEffectInstance();
			EffectData.SetVariant( damage.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.projectileHitEvent, damageHitEvent );
			damage.Run();
		}
	}

	protected function Explode( optional position : Vector4 )
	{
		var explosionAttackRecord : Attack_Record;
		if( !( hasExploded ) )
		{
			hasExploded = true;
			if( m_attack )
			{
				explosionAttackRecord = IAttack.GetExplosiveHitAttack( m_attack_record );
				if( explosionAttackRecord )
				{
					if( Vector4.IsZero( position ) )
					{
						position = Matrix.GetTranslation( m_projectileComponent.GetLocalToWorld() );
					}
					Attack_GameEffect.SpawnExplosionAttack( explosionAttackRecord, ( ( WeaponObject )( m_weapon ) ), m_user, this, position, 0.05 );
				}
			}
			GameObjectEffectHelper.BreakEffectLoopEvent( this, 'trail' );
		}
	}

	protected function RunGameEffect()
	{
		var effect : EffectInstance;
		effect = m_projectileComponent.GetGameEffectInstance();
		EffectData.SetVector( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.position, Matrix.GetTranslation( m_projectileComponent.GetLocalToWorld() ) );
		EffectData.SetFloat( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.range, range );
		EffectData.SetFloat( effect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.radius, range );
		effect.Run();
	}

	protected override function DealDamage( eventData : gameprojectileHitEvent )
	{
		PerformAttack( eventData );
		super.DealDamage( eventData );
	}

}

