Huge dump of refactored code. Still in the middle of the changes that are to be squashed later in a one huge monster commit, because there is no value in anything atomic here.
327 lines
8.2 KiB
Ucode
327 lines
8.2 KiB
Ucode
// Generic 'Karma Vehicle' base class that can be controlled by a Pawn.
|
|
|
|
class KVehicle extends Vehicle
|
|
native
|
|
abstract;
|
|
|
|
cpptext
|
|
{
|
|
#ifdef WITH_KARMA
|
|
virtual void PostNetReceive();
|
|
virtual void PostEditChange();
|
|
virtual void setPhysics(BYTE NewPhysics, AActor *NewFloor, FVector NewFloorV);
|
|
virtual void TickSimulated( FLOAT DeltaSeconds );
|
|
virtual void TickAuthoritative( FLOAT DeltaSeconds );
|
|
#endif
|
|
|
|
}
|
|
|
|
// Effect spawned when vehicle is destroyed
|
|
var (KVehicle) class<Actor> DestroyEffectClass;
|
|
|
|
// Simple 'driving-in-rings' logic.
|
|
var (KVehicle) bool bAutoDrive;
|
|
|
|
// The factory that created this vehicle.
|
|
//var KVehicleFactory ParentFactory;
|
|
|
|
// Weapon system
|
|
var bool bVehicleIsFiring, bVehicleIsAltFiring;
|
|
|
|
const FilterFrames = 5;
|
|
var vector CameraHistory[FilterFrames];
|
|
var int NextHistorySlot;
|
|
var bool bHistoryWarmup;
|
|
|
|
// Useful function for plotting data to real-time graph on screen.
|
|
native final function GraphData(string DataName, float DataValue);
|
|
|
|
// if _RO_
|
|
function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation,
|
|
vector momentum, class<DamageType> damageType, optional int HitIndex)
|
|
// else UT
|
|
//function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation,
|
|
// vector momentum, class<DamageType> damageType)
|
|
{
|
|
Super.TakeDamage(Damage,instigatedBy,HitLocation,Momentum,DamageType);
|
|
}
|
|
|
|
// You got some new info from the server (ie. VehicleState has some new info).
|
|
event VehicleStateReceived();
|
|
|
|
// Called when a parameter of the overall articulated actor has changed (like PostEditChange)
|
|
// The script must then call KUpdateConstraintParams or Actor Karma mutators as appropriate.
|
|
simulated event KVehicleUpdateParams();
|
|
|
|
// The pawn Driver has tried to take control of this vehicle
|
|
function bool TryToDrive(Pawn P)
|
|
{
|
|
if ( P.bIsCrouched || (P.Controller == None) || (Driver != None) || !P.Controller.bIsPlayer )
|
|
return false;
|
|
|
|
if ( !P.IsHumanControlled() || !P.Controller.IsInState('PlayerDriving') )
|
|
{
|
|
KDriverEnter(P);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Events called on driver entering/leaving vehicle
|
|
|
|
simulated function ClientKDriverEnter(PlayerController pc)
|
|
{
|
|
pc.myHUD.bCrosshairShow = false;
|
|
pc.myHUD.bShowWeaponInfo = false;
|
|
pc.myHUD.bShowPoints = false;
|
|
|
|
pc.bBehindView = true;
|
|
pc.bFreeCamera = true;
|
|
|
|
pc.SetRotation(rotator( vect(-1, 0, 0) >> Rotation ));
|
|
}
|
|
|
|
function KDriverEnter(Pawn P)
|
|
{
|
|
local PlayerController PC;
|
|
local Controller C;
|
|
|
|
// Set pawns current controller to control the vehicle pawn instead
|
|
Driver = P;
|
|
|
|
// Move the driver into position, and attach to car.
|
|
Driver.SetCollision(false, false);
|
|
Driver.bCollideWorld = false;
|
|
Driver.bPhysicsAnimUpdate = false;
|
|
Driver.Velocity = vect(0,0,0);
|
|
Driver.SetPhysics(PHYS_None);
|
|
Driver.SetBase(self);
|
|
|
|
// Disconnect PlayerController from Driver and connect to KVehicle.
|
|
C = P.Controller;
|
|
p.Controller.Unpossess();
|
|
Driver.SetOwner(C); // This keeps the driver relevant.
|
|
C.Possess(self);
|
|
|
|
PC = PlayerController(C);
|
|
if ( PC != None )
|
|
{
|
|
PC.ClientSetViewTarget(self); // Set playercontroller to view the vehicle
|
|
|
|
// Change controller state to driver
|
|
PC.GotoState('PlayerDriving');
|
|
|
|
ClientKDriverEnter(PC);
|
|
}
|
|
}
|
|
|
|
simulated function ClientKDriverLeave(PlayerController pc)
|
|
{
|
|
pc.bBehindView = false;
|
|
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.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 KDriverLeave(bool bForceLeave)
|
|
{
|
|
local PlayerController pc;
|
|
local int i;
|
|
local bool havePlaced;
|
|
local vector HitLocation, HitNormal, tryPlace;
|
|
|
|
// Do nothing if we're not being driven
|
|
if(Driver == None)
|
|
return false;
|
|
|
|
// Before we can exit, we need to find a place to put the driver.
|
|
// Iterate over array of possible exit locations.
|
|
|
|
if (!bRemoteControlled)
|
|
{
|
|
|
|
Driver.bCollideWorld = true;
|
|
Driver.SetCollision(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( !Driver.SetLocation(tryPlace) )
|
|
continue;
|
|
|
|
havePlaced = true;
|
|
}
|
|
|
|
// If we could not find a place to put the driver, leave driver inside as before.
|
|
if(!havePlaced && !bForceLeave)
|
|
{
|
|
Log("Could not place driver.");
|
|
|
|
Driver.bCollideWorld = false;
|
|
Driver.SetCollision(false, false);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
pc = PlayerController(Controller);
|
|
ClientKDriverLeave(pc);
|
|
|
|
// Reconnect PlayerController to Driver.
|
|
pc.Unpossess();
|
|
pc.Possess(Driver);
|
|
|
|
pc.ClientSetViewTarget(Driver); // Set playercontroller to view the persone that got out
|
|
|
|
Controller = None;
|
|
|
|
Driver.PlayWaiting();
|
|
Driver.bPhysicsAnimUpdate = Driver.Default.bPhysicsAnimUpdate;
|
|
|
|
// Do stuff on client
|
|
//pc.ClientSetBehindView(false);
|
|
//pc.ClientSetFixedCamera(true);
|
|
|
|
if (!bRemoteControlled)
|
|
{
|
|
|
|
Driver.Acceleration = vect(0, 0, 24000);
|
|
Driver.SetPhysics(PHYS_Falling);
|
|
Driver.SetBase(None);
|
|
}
|
|
|
|
// Car now has no driver
|
|
Driver = None;
|
|
|
|
// Put brakes on before you get out :)
|
|
Throttle=0;
|
|
Steering=0;
|
|
|
|
// Stop firing when you get out!
|
|
bVehicleIsFiring = false;
|
|
bVehicleIsAltFiring = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Special calc-view for vehicles
|
|
simulated function bool SpecialCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation )
|
|
{
|
|
local vector CamLookAt, HitLocation, HitNormal;
|
|
local PlayerController pc;
|
|
local int i, averageOver;
|
|
|
|
pc = PlayerController(Controller);
|
|
|
|
// Only do this mode we have a playercontroller viewing this vehicle
|
|
if(pc == None || pc.ViewTarget != self)
|
|
return false;
|
|
|
|
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;
|
|
}
|
|
|
|
simulated function Destroyed()
|
|
{
|
|
// If there was a driver in the vehicle, destroy him too
|
|
if ( Driver != None )
|
|
Driver.Destroy();
|
|
|
|
// Trigger any effects for destruction
|
|
if(DestroyEffectClass != None)
|
|
spawn(DestroyEffectClass, , , Location, Rotation);
|
|
|
|
Super.Destroyed();
|
|
}
|
|
|
|
simulated event Tick(float deltaSeconds)
|
|
{
|
|
}
|
|
|
|
// Includes properties from KActor
|
|
defaultproperties
|
|
{
|
|
Steering=0
|
|
Throttle=0
|
|
|
|
ExitPositions(0)=(X=0,Y=0,Z=0)
|
|
|
|
DrivePos=(X=0,Y=0,Z=0)
|
|
DriveRot=()
|
|
|
|
bHistoryWarmup = true;
|
|
|
|
|
|
Physics=PHYS_Karma
|
|
bEdShouldSnap=True
|
|
bStatic=False
|
|
bShadowCast=False
|
|
bCollideActors=True
|
|
bCollideWorld=False
|
|
bProjTarget=True
|
|
bBlockActors=True
|
|
bBlockNonZeroExtentTraces=True
|
|
bBlockZeroExtentTraces=True
|
|
bWorldGeometry=False
|
|
bBlockKarma=True
|
|
bAcceptsProjectors=True
|
|
bCanBeBaseForPawns=True
|
|
bAlwaysRelevant=True
|
|
RemoteRole=ROLE_SimulatedProxy
|
|
bNetInitialRotation=True
|
|
bSpecialCalcView=True
|
|
//bSpecialHUD=true
|
|
}
|