
// hitscan actors
kActor@ Dummy1, Dummy2;

kVec3 EyePos()
{
	kPuppet @src = Player.Actor();
	kVec3 v = src.Origin();
	v.z += src.ViewHeight() + src.LandingViewOffset();
	return v;
}

// kVec3::ToQuat() tends to stick when close to parallel to y-axis
kQuat ToQuat( kVec3&in v )
{
	return kQuat( v.ToYaw(), 0,0,1 ) * kQuat( -v.ToPitch(), 1,0,0 );
}

//==============================================================================

class Q2ArmorPickup : ScriptObject
{
	kActor@ self;
	Q2ArmorPickup( kActor@ a ) { @self = a; }
	void OnSpawn() {}

	// cap to 50 displayed armor after being picked up (and level end, which is redundant but fine)
	~Q2ArmorPickup()
	{
		if ( Player.Armor() > 150 ) Player.Armor() = 150;
	}

	// only allow picking up if displayed armor is < 50
	void OnTick()
	{
		if ( Player.Armor() <= 147 ) self.Flags() |=  AF_CANBETOUCHED;
		else                         self.Flags() &= ~AF_CANBETOUCHED;
	}
}

class GroundPickup : ScriptObject
{
	kActor@ self;
	GroundPickup( kActor@ a )
	{  @self = a;  }
	void OnPostBeginLevel()
	{
		// if we appear to be outside the level, lift to original model's elevation
		if ( self.SectorIndex() < 0 || self.Origin().z - self.FloorHeight() <= -GAME_SCALE/4 )
		{
			float lift;
			if ( self.Definition().GetFloat( "lift", lift ) )
				self.RenderModel().Offset().z = lift * self.Scale().z;
		}
	}
	void OnSpawn() {}
	void OnTick() {}
}

class RailSlugs : GroundPickup
{
	RailSlugs( kActor@ a )
	{
		super(a);
	}

	void OnSpawn()
	{
		if ( Player.HasWeapon( Q2_Wep_Railgun ) )
			self.Flags() |= AF_DORMANT | AF_ALWAYSACTIVE;
	}

	void OnPostBeginLevel()
	{
		GroundPickup::OnPostBeginLevel();

		if ( Player.HasWeapon( Q2_Wep_Railgun ) )
			return;

		kStr str;
		self.Definition().GetString( "bulletPickup", str );
		kActor@ a = ActorFactory.Spawn( str, self.Origin().x, self.Origin().y, self.Origin().z, 0, self.SectorIndex() );
		if ( a is null )
		{
			self.Flags() |= AF_DORMANT | AF_ALWAYSACTIVE;
			return;
		}
		self.SetTarget( a );
		a.Scale()      = self.Scale();
		a.Radius()     = self.Radius();
		a.Height()     = self.Height();
		a.StepHeight() = self.StepHeight();
		if ( self.Flags() & AF_CASTSHADOW  != 0 ) a.Flags() |= AF_CASTSHADOW;
		if ( self.Flags() & AF_SNAPTOFLOOR != 0 ) a.Flags() |= AF_SNAPTOFLOOR;
		// other pickup's lift is relative to the bullet pickup it replaces, not the tek arrow pickup we replace
		// so apply our own correct lift to it here
		a.RenderModel().Offset().z = self.RenderModel().Offset().z;
	}

	void OnTick()
	{
		if ( self.GetTarget() is null || self.GetTarget().IsStale() )
		{
			self.MarkPersistentBit( false );
			self.Remove();
		}
		else if ( Player.HasWeapon( Q2_Wep_Railgun ) )
		{
			self.GetTarget().Remove();
			self.Flags() &= ~AF_HIDDEN;
			self.Flags() |=  AF_CANBETOUCHED | AF_DORMANT | AF_ALWAYSACTIVE;
		}
		else
		{
			self.Flags() |=  AF_HIDDEN;
			self.Flags() &= ~AF_CANBETOUCHED;
		}
	}
}

// change mega-health back to "+" for Turok+ title screen
class MegaHealth : GroundPickup
{
	MegaHealth( kActor@ a )
	{  super( a );  }
	void OnPostBeginLevel()
	{
		if ( Game.GetCurrentMapID() == 42 ) self.RenderModel().SetModel( "models/health_ultra.bin", "" );
		else                                GroundPickup::OnPostBeginLevel();
	}
}

//==============================================================================

class RailSpiral : ScriptObject
{
	kActor@ self;
	kQuat q;

	RailSpiral( kActor@ a )
	{
		@self = a;
	}

	void OnSpawn()
	{
		// make sure distant segments don't freeze
		self.Flags() |= AF_ALWAYSACTIVE;
	}

	void OnTick()
	{
		if ( self.GameTicks() >= 76 )
			self.Remove();
		else
		{
			self.Rotation() = q;
			self.Scale() += kVec3( 0.05f, 0, 0.05f );
			float f = self.GameTicks() / 76.0f;
			self.ModelVariation() = int( 10 * f );
		}
	}
}

class RailBeam : ScriptObject
{
	kActor@ self;
	kQuat q;

	RailBeam( kActor@ a )
	{
		@self = a;
	}

	void OnSpawn()
	{
		// make sure distant segments don't freeze
		self.Flags() |= AF_ALWAYSACTIVE;
	}

	void OnTick()
	{
		if ( self.GameTicks() >= 38 )
			self.Remove();
		else
		{
			self.Rotation() = q;
//			self.Scale() += kVec3( 0.02f, 0, 0.02f );
			float f = self.GameTicks() / 38.0f;
			self.ModelVariation() = int( 10 * f );
		}
	}
}
