There is no spoon

Legacy:Vehicles Pre2004/Passengers

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

Much of this is experimental code and needs a custom Controller class. Tested in multiplayer, the camera of the Passengers has the message "viewing from ..." I’ll look into that later. If you have any problems with this code, you should contact me at sneakeye_@hotmail.com

MyVehicle

class MyVehicle extends KVehicle;
 
var()	int		MaxPassengers;	//Number of Passengers (without driver)
var	Pawn		Passengers[10];
var	Controller	PassengersControllers[10];
 
var()	bool		bAllowDriver;
 
function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, 
						Vector momentum, class<DamageType> damageType)
{
	Local int i;
 
	Health -= Damage;
 
	// The vehicle is dead!
	if(Health <= 0)
	{
		if ( Controller != None )
		{
			if( Controller.bIsPlayer )
			{
				ClientKDriverLeave(PlayerController(Controller)); // Just to reset HUD etc.
				Controller.PawnDied(self); // This should unpossess the controller and let the player respawn
			}
			else
				Controller.Destroy();
		}
		for (i=0;i<MaxPassengers;i++)
		{
			if ( PassengersControllers[i] != None )
			{
				KPassengerLeave(True, MyPlayerController(PassengersControllers[i])); // Just to reset HUD etc.
				PassengersControllers[i].PawnDied(self); // This should unpossess the controller and let the player respawn
			}
		}
 
		Destroy(); // Destroy the vehicle itself (see Destroyed below)
	}
 
	//KAddImpulse(momentum, hitlocation);
}
 
simulated function Destroyed()
{
	local int i;
	// If there where passengers in the vehicle, destroy them too
	for (i=0;i<MaxPassengers;i++)
		if ( Passengers[i] != None )
			Passengers[i].Destroy();
	Super.Destroyed();
}
 
function TryToDrive(Pawn p)
{
	local Controller C;
	C = p.Controller;
 
	if ( (Driver == None) && (C != None) && C.bIsPlayer && !C.IsInState('PlayerDriving') && p.IsHumanControlled() && bAllowDriver)
	{
		KDriverEnter(p);
	}else if (C != None && C.IsA('MyPlayerController') && !C.IsInState('PlayerDriving') && p.IsHumanControlled()) {
		TryToPassenger(p);
	}
}
 
function KDriverEnter(Pawn p)
{
	Super.KDriverEnter(p);
	p.bHidden = True;
}
 
function bool KDriverLeave(bool bForceLeave)
{
	local Pawn OldDriver;
 
	OldDriver = Driver;
 
	// If we succesfully got out of the car, make driver visible again.
	if( Super.KDriverLeave(bForceLeave) )
	{
		OldDriver.bHidden = false;
		return true;
	}
	else
		return false;
}
 
function TryToPassenger(Pawn p)
{
	local int i;
	for(i=0;i<MaxPassengers;i++)
	{
		if (Passengers[i] == None)
		{
			KPassengerEnter(p, i);	//Enter passenger
			i = MaxPassengers;	//Make sure not added as another passenger
		}
	}
}
 
simulated function ClientKPassengerEnter(PlayerController pc)
{
	pc.myHUD.bCrosshairShow = false;
	pc.myHUD.bShowWeaponInfo = false;
	//pc.myHUD.bShowPersonalInfo = false;
	pc.myHUD.bShowPoints = false;
 
	pc.bBehindView = true;
	pc.bFixedCamera = false;
	pc.bFreeCamera = true;
 
	pc.SetRotation(rotator( vect(-1, 0, 0) >> Rotation ));
}
 
function KPassengerEnter(Pawn p, int i)
{
	local MyPlayerController pc;
 
	//log("KVehicle KDriverEnter");
 
	// Set pawns current controller to control the vehicle pawn instead
	Passengers[i] = p;
 
	// Move the driver into position, and attach to car.
	p.SetCollision(false, false, false);
	p.bCollideWorld = false;
	p.bPhysicsAnimUpdate = false;
	p.Velocity = vect(0,0,0);
	p.SetPhysics(PHYS_None);
	p.SetBase(self);
 
	pc = MyPlayerController(p.Controller);
	//pc.ClientSetBehindView(true);
	//pc.ClientSetFixedCamera(false);
 
	// Disconnect PlyaerController from Driver and connect to KVehicle.
	pc.Unpossess();
	Passengers[i].SetOwner(pc); // This keeps the driver relevant.
	pc.PossessPassenger(self);
	PassengersControllers[i] = pc;
 
	pc.ClientSetViewTarget(self); // Set playercontroller to view the vehicle
 
	// Change controller state to driver
	pc.GotoState('PlayerPassenger');
 
	ClientKPassengerEnter(pc);
 
	p.bHidden = True;
}
 
simulated function ClientKPassengerLeave(PlayerController pc)
{
	//local vector exitLookDir;
 
	//log("Leave: "$pc.Pawn);
 
	pc.bBehindView = false;
	pc.bFixedCamera = true;
	pc.bFreeCamera = false;
	// This removes any 'roll' from the look direction.
	//exitLookDir = Vector(pc.Rotation);
	//pc.SetRotation(Rotator(exitLookDir));
 
	pc.myHUD.bCrosshairShow = pc.myHUD.default.bCrosshairShow;
	pc.myHUD.bShowWeaponInfo = pc.myHUD.default.bShowWeaponInfo;
	//pc.myHUD.bShowPersonalInfo = pc.myHUD.default.bShowPersonalInfo;
	pc.myHUD.bShowPoints = pc.myHUD.default.bShowPoints;
 
	// Reset the view-smoothing
	NextHistorySlot = 0;
	bHistoryWarmup = true;
}
 
// Called from the PlayerController when player wants to get out.
function bool KPassengerLeave(bool bForceLeave, MyPlayerController pc)
{
	local int i, PassengerNum;
	local bool havePlaced;
	local vector HitLocation, HitNormal, tryPlace;
 
	PassengerNum = -1;
 
	for (i=0;i<MaxPassengers;i++)
		if (PassengersControllers[i] == pc)
			PassengerNum = i;
 
	if(PassengerNum == -1)
		return false;
 
	// Before we can exit, we need to find a place to put the driver.
	// Iterate over array of possible exit locations.
 
	Passengers[PassengerNum].bCollideWorld = true;
	Passengers[PassengerNum].SetCollision(true, true, true);
 
	havePlaced = false;
	for(i=0; i < ExitPositions.Length && havePlaced == false; i++)
	{
		//Log("Trying Exit:"$i);
 
		tryPlace = Location + (ExitPositions[i] >> Rotation);
 
		// First, do a line check (stops us passing through things on exit).
		if( Trace(HitLocation, HitNormal, tryPlace, Location, false) != None )
			continue;
 
		// Then see if we can place the player there.
		if( !Passengers[PassengerNum].SetLocation(tryPlace) )
			continue;
 
		havePlaced = true;
 
		//Log("SUCCESS!");		
	}
 
	// If we could not find a place to put the driver, leave driver inside as before.
	if(!havePlaced && !bForceLeave)
	{
		Log("Could not place driver.");
 
		Passengers[PassengerNum].bCollideWorld = false;
		Passengers[PassengerNum].SetCollision(false, false, false);
 
		return false;
	}
 
	ClientKPassengerLeave(pc);
 
	// Reconnect PlayerController to Driver.
	pc.UnpossessPassenger();
	pc.Possess(Passengers[PassengerNum]);
 
	pc.ClientSetViewTarget(Passengers[PassengerNum]); // Set playercontroller to view the persone that got out
 
	PassengersControllers[PassengerNum] = None;
 
	Passengers[PassengerNum].PlayWaiting();
	Passengers[PassengerNum].bPhysicsAnimUpdate = Passengers[PassengerNum].Default.bPhysicsAnimUpdate;
 
	// Do stuff on client
	//pc.ClientSetBehindView(false);
	//pc.ClientSetFixedCamera(true);
 
	Passengers[PassengerNum].Acceleration = vect(0, 0, 24000);
	if (Passengers[PassengerNum].TouchingWaterVolume())
	{
		Passengers[PassengerNum].SetPhysics(PHYS_Swimming);
	}else{
		Passengers[PassengerNum].SetPhysics(PHYS_Falling);
	}
	Passengers[PassengerNum].SetBase(None);
	Passengers[PassengerNum].bHidden = False;
 
	// Car now has no Passenger[Num]
	Passengers[PassengerNum] = None;
 
	return true;
}
 
function PossessedByPassenger(Controller C)
{
	NetPriority = 3;
 
	if ( C.IsA('PlayerController') )
	{
		if ( Level.NetMode != NM_Standalone )
			RemoteRole = ROLE_AutonomousProxy;
		BecomeViewTarget();
	}
	else
		RemoteRole = Default.RemoteRole;
 
//	The real controller is already owner
//	SetOwner(C);	// for network replication
	Eyeheight = BaseEyeHeight;
	ChangeAnimation();
}
 
simulated event Tick(float deltaSeconds)
{
	local int i;
 
	if(bGetOut && ROLE==Role_Authority)
	{
		for(i=0;i<MaxPassengers;i++)
		if(Passengers[i] != None)
		{
			KPassengerLeave(false, MyPlayerController(PassengersControllers[i]));
		}
	}
	Super.Tick(deltaSeconds);
}
 
simulated function bool SpecialCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation )
{
	local vector CamLookAt, HitLocation, HitNormal;
	local int i, averageOver;
 
	ViewActor = self;
	CamLookAt = Location + (vect(-100, 0, 100) >> Rotation); 
 
	//////////////////////////////////////////////////////
	// Smooth lookat position over a few frames.
	CameraHistory[NextHistorySlot] = CamLookAt;
	NextHistorySlot++;
 
	if(bHistoryWarmup)
		averageOver = NextHistorySlot;
	else
		averageOver = FilterFrames;
 
	CamLookAt = vect(0, 0, 0);
	for(i=0; i<averageOver; i++)
		CamLookAt += CameraHistory[i];
 
	CamLookAt /= float(averageOver);
 
	if(NextHistorySlot == FilterFrames)
	{
		NextHistorySlot = 0;
		bHistoryWarmup=false;
	}
	//////////////////////////////////////////////////////
 
	CameraLocation = CamLookAt + (vect(-600, 0, 0) >> CameraRotation);
 
	if( Trace( HitLocation, HitNormal, CameraLocation, CamLookAt, false, vect(10, 10, 10) ) != None )
	{
		CameraLocation = HitLocation;
	}
 
	return true;
}
 
defaultproperties
{
	MaxPassengers = 1;
	bAllowDriver = True;
}

MyPlayerController

class MyPlayerController extends xPlayer;
 
simulated event Destroyed()
{
	local int i;
	local MyVehicle Vehicle;
	local Pawn Passenger;
	//Don't destroy driver if in vehicle, could also be passenger!
	if (Pawn != None)
	{
		if (Pawn.IsA('MyVehicle'))	//Now you've done it, your in a vehicle
		{
			Vehicle = MyVehicle(Pawn);
			for(i=0;i<Vehicle.MaxPassengers;i++)	//If find self in vehicle, throw out, and destroy the pawn.
				if (Vehicle.PassengersControllers[i] == Self)
				{
					Passenger = Vehicle.Passengers[i];
					Vehicle.KPassengerLeave(true, Self); // Force the driver out of the car
					Passenger.Destroy();
					Pawn = None;
				}
		}
	}
	Super.Destroyed();
}
 
// Possess a pawn
function PossessPassenger(MyVehicle aPawn)
{
    if ( PlayerReplicationInfo.bOnlySpectator )
        return;
 
    SetRotation(aPawn.Rotation);
    aPawn.PossessedByPassenger(self);
    Pawn = aPawn;
    Pawn.bStasis = false;
    PlayerReplicationInfo.bIsFemale = Pawn.bIsFemale;
    Restart();
}
 
// unpossessed a pawn (not because pawn was killed)
function UnPossessPassenger()
{
    if ( Pawn != None )
    {
        SetLocation(Pawn.Location);
        if ( Viewtarget == Pawn )
            SetViewTarget(self);
    }
    Pawn = None;
    GotoState('Spectating');
}
 
state PlayerPassenger
{
ignores SeePlayer, HearNoise, Bump;
 
	function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
	{
	}
 
	exec function Fire(optional float F)
	{
	}
 
	exec function AltFire(optional float F)
	{
	}
 
	// Set the throttle, steering etc. for the vehicle based on the input provided
	function ProcessDrive(float InForward, float InStrafe, bool InJump)
	{
		local MyVehicle DrivenVehicle;
 
		DrivenVehicle = MyVehicle(Pawn);
 
		if(DrivenVehicle == None)
		{
			log("PlayerPassenger.PlayerMove: No Vehicle");
			return;
		}
 
		// check for 'jump' to throw the driver out.
		if(InJump && Role == ROLE_Authority)
		{
			Log("Passenger tries to leave");
			DrivenVehicle.KPassengerLeave(False, Self);
			return;
		}
	}
 
	function PlayerMove( float DeltaTime )
	{
		local KVehicle DrivenVehicle;
 
		// Only servers can actually do the driving logic.
		if(Role < ROLE_Authority)
			ServerDrive(aForward, aStrafe, bPressedJump);
		else
			ProcessDrive(aForward, aStrafe, bPressedJump);
 
		// If the vehicle is being controlled here - set replicated variables.
		DrivenVehicle = KVehicle(Pawn);
 
		// update 'looking' rotation - no affect on driving
		UpdateRotation(DeltaTime, 2);
	}
 
	function BeginState()
	{
		CleanOutSavedMoves();
	}
 
	function EndState()
	{
		CleanOutSavedMoves();
	}
}

Discussion

mosquito What does the second one do? I looks like an extendion of the first

Highlander: First one is the actual code for the vehicle, second one looks like it handles the players inside the vehicle. (new controller class)