class minibossPlasmaProjectile extends BaseProjectile
{
	private var m_countTime : Float;
	private editable var m_startVelocity : Float;
	private editable var m_lifetime : Float;
	private editable var m_effectName : CName;
	private editable var m_hitEffectName : CName;
	private editable var m_followTarget : Bool;
	default m_followTarget = false;
	private editable var m_bendFactor : Float;
	private editable var m_bendRatio : Float;
	private editable var m_shouldRotate : Bool;
	editable var m_attackRecordID : TweakDBID;
	protected var m_instigator : weak< GameObject >;
	private editable var m_spawnGameEffectOnCollision : Bool;
	default m_spawnGameEffectOnCollision = false;
	private editable var m_collisionAttackRecord : Attack_Record;
	private var m_alive : Bool;
	default m_alive = true;
	private var m_owner : weak< ScriptedPuppet >;
	private var m_target : weak< GameObject >;

	protected event OnProjectileInitialize( eventData : gameprojectileSetUpEvent )
	{
		m_owner = ( ( ScriptedPuppet )( eventData.owner ) );
	}

	private function StartEffect()
	{
		var spawnEffectEvent : entSpawnEffectEvent;
		spawnEffectEvent = new entSpawnEffectEvent;
		spawnEffectEvent.effectName = m_effectName;
		this.QueueEvent( spawnEffectEvent );
	}

	private function StopEffect()
	{
		var killEffectEvent : entKillEffectEvent;
		killEffectEvent = new entKillEffectEvent;
		killEffectEvent.effectName = m_effectName;
		this.QueueEvent( killEffectEvent );
	}

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

	protected event OnShoot( eventData : gameprojectileShootEvent )
	{
		m_instigator = eventData.owner;
		OnShootTarget( ( ( gameprojectileShootTargetEvent )( eventData ) ) );
	}

	protected event OnShootTarget( eventData : gameprojectileShootTargetEvent )
	{
		var followParams : FollowCurveTrajectoryParams;
		var linearParams : LinearTrajectoryParams;
		var targetPosition : Vector4;
		followParams = new FollowCurveTrajectoryParams;
		linearParams = new LinearTrajectoryParams;
		targetPosition = eventData.params.targetPosition;
		if( !( m_instigator ) )
		{
			m_instigator = eventData.owner;
		}
		Reset();
		StartEffect();
		if( !( m_followTarget ) )
		{
			if( m_owner )
			{
				if( m_owner.GetUpperBodyStateFromBlackboard() == gamedataNPCUpperBodyState.Defend )
				{
					linearParams.startVel = m_owner.GetFloatFromCharacterTweak( "stance_turtle_projectileSpeed", -1.0 );
				}
				else
				{
					linearParams.startVel = m_owner.GetFloatFromCharacterTweak( "attack_pulse_projectileSpeed", -1.0 );
				}
			}
			if( linearParams.startVel <= 0.0 )
			{
				linearParams.startVel = m_startVelocity;
			}
			m_projectileComponent.AddLinear( linearParams );
		}
		else
		{
			m_projectileComponent.ClearTrajectories();
			followParams.startVelocity = m_startVelocity;
			followParams.targetPosition = targetPosition;
			followParams.bendFactor = m_bendFactor;
			followParams.bendTimeRatio = m_bendRatio;
			followParams.angleInHitPlane = 0.0;
			followParams.shouldRotate = m_shouldRotate;
			followParams.accuracy = 1.0;
			m_projectileComponent.AddFollowCurve( followParams );
		}
	}

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

	protected event OnCollision( eventData : gameprojectileHitEvent )
	{
		if( m_alive && ( eventData.hitInstances[ 0 ].hitObject != m_owner ) )
		{
			GameObject.PlaySoundEvent( this, 'w_gun_special_plasma_cutter_exploding_projectile_3D' );
			if( m_spawnGameEffectOnCollision )
			{
				Explode( m_attackRecordID );
			}
			DealDamage( eventData );
			Release();
			StopEffect();
			GameObjectEffectHelper.StartEffectEvent( this, m_hitEffectName );
			m_alive = false;
		}
	}

	protected event OnAreaEnter( evt : AreaEnteredEvent )
	{
		if( m_alive )
		{
			GameObject.PlaySoundEvent( this, 'w_gun_special_plasma_cutter_exploding_projectile_3D' );
			StopEffect();
			GameObjectEffectHelper.StartEffectEvent( this, m_hitEffectName );
			if( m_spawnGameEffectOnCollision )
			{
				Explode( m_attackRecordID );
			}
			m_alive = false;
			Release();
		}
	}

	private function DealDamage( eventData : gameprojectileHitEvent )
	{
		var damageEffect : EffectInstance;
		damageEffect = m_projectileComponent.GetGameEffectInstance();
		EffectData.SetVariant( damageEffect.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.projectileHitEvent, eventData );
		damageEffect.Run();
		m_countTime = 0.0;
		m_alive = false;
		m_projectileComponent.ClearTrajectories();
	}

	private function Explode( record : TweakDBID )
	{
		if( TDBID.IsValid( record ) )
		{
			FireAttack();
		}
	}

	public function FireAttack()
	{
		var Attack : Attack_GameEffect;
		var hitFlags : array< SHitFlag >;
		var flag : SHitFlag;
		flag.flag = hitFlag.SuccessfulAttack;
		flag.source = 'Attack';
		hitFlags.PushBack( flag );
		Attack = RPGManager.PrepareGameEffectAttack( GetGame(), m_instigator, this, m_attackRecordID, , hitFlags );
		Attack.StartAttack();
	}

}

