Legacy:Vehicles Pre2004/Passengers
From Unreal Wiki, The Unreal Engine Documentation Site
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)