//=============================================================================
// ProxyController.
//
//	30/8/99 - 1st release
//=============================================================================

class ProxyController expands Actor;


var() vector	mHoldingLocation ;		// Where to place the target actor during a proxy repacement

var PlayerPawn	mPlayerActor ;			// The origional player
var Pawn		mTargetActor ;			// The target actor of the proxy controller
var name		mTargetState ;			// Name of state target was in before being controlled
var bool		mNoProxy ;				// Set to true if proxy actor not needed
var PlayerPawn	mProxyActor ;			// The spawned actor taking the place of the actor, ie direct control of target
var bool		mPlayerConnected ;		// True if player is currently conencted to the proxy target
var bool		mRequireConnection ;	// True if the ProxyController is waiting to connect player to an actor
var bool		mRequireDisconnection ;	// True if the ProxyController is waiting to disconnect a player from a proxy
var float		mConnectionTimer ;		// Time left before connection terminated automatically


// ____________________________________________________________________________
// ____________________________________________________________________________

//
// Start of level.
//
// Set up some globals etc.
//
// Note, the rest of the initialisation is done in the start
// start up state stInitialise.
//

function BeginPlay()

{

	mTargetActor = none ;
	mNoProxy = true ;
	mProxyActor = none ;
	mPlayerConnected = false ;
	mRequireConnection = false ;
	mRequireDisconnection = false ;

}


//
// event PerformConnection()
//
// 'Connects' the player to the currently selected target actor.
// Actually a new PlayerPawn is spawned in place of the target and it's this actor
// that the player actually 'takes' over.
//
// During the period of the connection, the origional target player is kept hidden.
//

event PerformConnection()

{

local Vector temp_location ;
local Rotator temp_rotation ;


	log( "ProxyController: event PerformConnection" ) ;
	
	
	temp_location = mTargetActor.Location ;
	temp_rotation = mTargetActor.Rotation ;
	
//
//	Move the target actor to the safe location
//
	mTargetActor.bHidden = true ;
	mTargetState = mTargetActor.GetStateName() ;
	mTargetActor.SetLocation( mHoldingLocation ) ;


//
// Create a proxy actor and take it over.
//
	mProxyActor = spawn( class 'MaleThree', , , temp_location, temp_rotation ) ;
	mProxyActor.Health = mTargetActor.Health ;
	
	mPlayerActor.UnPossess() ;
	mProxyActor.Possess() ;	


//
// 220 fix for view direction
//
	mProxyActor.ViewRotation = temp_rotation ;
			
//
//	Stop the origional player from fireing etc
//
	mPlayerActor.bFire = 0 ;
	mPlayerActor.bAltFire = 0 ;
	mPlayerActor.bDuck = 0 ;
	mPlayerActor.bIsWalking = false ;
	mPlayerActor.Velocity = vect( 0, 0, 0 ) ;
	mPlayerActor.Acceleration = vect( 0, 0, 0 ) ;


	mPlayerConnected = true ;		// Player has been connected
	mRequireConnection = false ;	// Redirection now complete


	GoToState( 'stPlayerConnected' ) ;	

}


//
// event PerformDisconnection()
//
// 'Disconnects' the player from the proxy actor.
// The player is 'sent' back to the real player actor. The proxy actor
// is destroyed and the origional target actor is restored with the last position
// and orientation etc of the proxy actor.
//

event PerformDisconnection()

{

local Vector	temp_location ;
local Rotator	temp_rotation ;
local int		temp_health ;

	log( "ProxyController: event PerformDisconnection" ) ;
	
	temp_location = mProxyActor.Location ;
	temp_rotation = mProxyActor.Rotation ;
	temp_health = mProxyActor.Health ;
	
	
//
// Re-possess the real player actor
//
	mProxyActor.UnPossess() ;
	mPlayerActor.Possess() ;
	

//
// Make the origional target actor active and visible again
//
	mProxyActor.Destroy() ;
		
	mTargetActor.SetLocation( temp_location ) ;
	mTargetActor.SetRotation( temp_rotation ) ; 
	mTargetActor.Health = temp_health ;
	
	mTargetActor.bHidden = false ;
	
//
// Reset ProxyController state
//	
	mPlayerConnected = false ;
	mRequireDisconnection = false ;
	
//
//Attempts at fixing 220 to make current weapon visible
//
	mPlayerActor.myHud.Destroy() ;
	mPlayerActor.myHud = none ;	
	
	
	GoToState( 'stWaiting' ) ;
	
}


//
// Funtion ConnectPlayer( target, period )
//
// Called from Unrelscript. Requests the proxy controller to redirect
// the player to a target actor. The player effectively takes over
// the the target actor, ie all input etc is sent to that actor.
//
// The new target actor is set and the controller changes to stRequireRedirect.
// The next time the ProxyController is refreshed, the redirection will actually happen.
//
// The connection perdiod is how long before the connection is automatically terminated.
// A value of 0 means an indefinitive period.
//
function ConnectPlayer( Pawn target, optional float connection_period )

{

	mTargetActor = target ;
	mConnectionTimer = connection_period ;
	mRequireConnection = true ;
	
	GoToState( 'stRequireConnection' ) ;
	
}


//
// Function DisconnectPlayer()
//
// Disconnects the player from the current target. Actually the disconnection
// doesn't happen immediately, rather the mRequireDisconnection flag is set.
//

function DisconnectPlayer()

{

	mRequireDisconnection = true ;
	
	GoToState( 'stRequireDisconnection' ) ;

}

// ____________________________________________________________________________
//
//							State Handlers
// ____________________________________________________________________________


//
// State stInitialise
//
// Exectuted once at start of level. Finds the player's actor.
//

auto state stInitialise

{

	function find_player()
	 {

	 local PlayerPawn player ;
	
		foreach AllActors( class 'PlayerPawn', player )
	 	 {
	 		if ( player.bIsPlayer )
	 	 	 {
	 	 		mPlayerActor = player ;
	 	 		log( "ProxyController: Found player acter" ) ;
	 	 	 }
	 	 }
	 
		if ( mPlayerActor == none )
			log( "ProxyController: Player not found" ) ;
			
	 }
	

Begin:
	
	find_player() ;
	GoToState( 'stWaiting' ) ;
		
}

//
// ProxyController is waiting for a redirection request.
// So does nothing in the meantime.
//

state stWaiting
{

	 
Begin:
	
	log( "ProxyController: Entering state stWaiting" ) ;
	

}


state stRequireConnection
{

Begin:
	
	log( "ProxyController: Entering state stRequireRedirect" ) ;


}


//
// State stPlayerConnected
//
// Player is currently connected to the proxy actor.
// Checks the connection timer. If it's timed out then the player is disconnected.
//
// mConnectionTImer is the timer. A value > 0 means the timer is active.
// A value of 0 means an indefinitive period.
//

state stPlayerConnected
{

	function Tick( float deltaSeconds )
	 {
	 
	 	if ( mConnectionTimer > 0.0 )
	 	 {
	 	 
	 	 	mConnectionTimer -= deltaSeconds ;
	 	 	
	 	 	if ( mConnectionTimer <= 0.0 )
	 	 	 {
	 	 		DisconnectPlayer() ;
	 	 		log( "ProxyController: Timed out" ) ;
	 	 	 }
	 	 	 	 	 
	 	 }

	 }
	 
	 
Begin:
	
	log( "ProxyController: Entering state stPlayerConnected" ) ;

}



//
// The controller needs to switch the player back to the origional player.
//

state stRequireDisconnection
{

Begin:
	
	log( "ProxyController: Entering state stRequireDisconnection" ) ;

}

defaultproperties
{
}
