rott/rottlib/tests/fixtures/KVehicle.uc
dkanus 588790b9b4 Refactor everything
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.
2026-04-05 20:32:11 +07:00

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
}