
enum eBioAnims
{
	anim_Bio_Charge = anim_weaponFire,
	anim_Bio_Fire   = anim_weaponFireCharged
}

enum eBioFrames
{
	Bio_SwapIn1  =   0, Bio_SwapIn2  =  28,
//	Bio_SwapOut1 = 329, Bio_SwapOut2 = 344,
//	Bio_Charge1  =  28, Bio_Charge2  = 278,
//	Bio_Fire1    = 279, Bio_Fire2    = 329,
	Bio_SwapOut1 = 356, Bio_SwapOut2 = 371,
	Bio_Charge1  =  28, Bio_Charge2  = 305,
	Bio_Fire1    = 306, Bio_Fire2    = 356,
	Bio_Idle     =  28
}

final class TurokAlienRifle : TurokWeapon
{
	float charge;
	float recoilPitch, recoilRoll;

	TurokAlienRifle( kWeapon@ a )
	{
		super( a );
		BobDamping = 0.972f;
	}

	void AnimProperties( int&out first, int&out last, float&out rate, bool&out bLoop )
	{
		rate = 60; bLoop = false;
		switch ( PlayingID() )
		{
			case anim_weaponSwapIn:  first = Bio_SwapIn1;  last = Bio_SwapIn2;  break;
			case anim_weaponSwapOut: first = Bio_SwapOut1; last = Bio_SwapOut2; break;
			case anim_Bio_Charge:    first = Bio_Charge1;  last = Bio_Charge2;  break;
			case anim_Bio_Fire:      first = Bio_Fire1;    last = Bio_Fire2;
				rate = charge - 1;  rate = 1 - rate*rate;
				rate = Math::Lerp( 60.0f*31.5f/12.0f, 60.0f, rate ); break;
			default: /* idle */      first = last = Bio_Idle; bLoop = true; break;
		}
	}

	void AnimEnd()
	{
		if ( !IsPlaying( anim_Bio_Charge ) )
			TurokWeapon::AnimEnd();
	}

	bool Refire()
	{
		return IsPlaying( anim_Bio_Fire );
	}

	void OnTick()
	{
		TurokWeapon::OnTick();
		if ( !IsPlaying(anim_Bio_Fire) || PlayTime() > 0.3f + 0.1f*charge ) return;
		float f = 1 - PlayTime() / (0.3f + 0.1f*charge);
		OwnerP().RecoilPitch() = Math::Sin( Math::pi * f ) * f * -0.02f  * recoilPitch;
		f *= f;
		OwnerP().Roll()        = Math::Sin( Math::pi * f ) * f * -0.025f * recoilRoll;
	}

	void OnBeginFire()
	{
		if ( !bFire2 )
			ShootLoad();
		else
		{
			PlayAnim( anim_Bio_Charge );
			PlayWeaponSound( "UT/sounds/Bio/Charge.ksnd" );
		}
	}

	void OnFire()
	{
		if ( IsPlaying(anim_Bio_Charge) && !bFire2 )
			ShootLoad();
	}

	void ShootLoad()
	{
		if ( IsPlaying(anim_Bio_Charge) )
			charge = float( self.ModelVariation() - Bio_Charge1 ) / ( Bio_Charge2 - Bio_Charge1 );
		else
			charge = 0;
		int iCharge = int( charge * 9 );
		if ( 1 + iCharge > GetAmmo() ) iCharge = GetAmmo() - 1;
		charge = iCharge / 9.0f;
		UseAmmo( 1 + iCharge );

		PlayAnim( anim_Bio_Fire );
		StopWeaponSound(); // stop charge sound
		self.PlaySound( "U1/sounds/Bio/Fire.ksnd" );
		recoilPitch = 0.5f + 0.5f*Math::RandFloat() + charge*1.5f;
		recoilRoll  = 0.5f + 0.5f*Math::RandFloat() + charge*1.5f;

		kVec3 offset = kVec3( 9.5f, 25, -4 ) * OwnerP().Rotation();
		offset += EyePos();
		offset.z -= 5;
		kVec3 v = CheckPosition( offset );
		kActor@ a = ActorFactory.Spawn( "BioGel", v.x, v.y, v.z, OwnerP().Yaw(), OwnerP().SectorIndex() );
		if ( a is null || a.ScriptObject() is null || a.ScriptObject().obj is null )
			return;
		BioGel@ g = cast<BioGel@>( a.ScriptObject().obj );
		if ( g !is null )
			g.Setup( iCharge, kVec3( -0.0095f, 1, 0 ).Normalize() * OwnerP().Rotation(), UDamage() );
	}
}
