1
0
KF2-Dev-Scripts/UDKBase/classes/UDKVehicleBase.uc
2020-12-13 18:01:13 +03:00

310 lines
6.3 KiB
Ucode

/**
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
*/
class UDKVehicleBase extends SVehicle
abstract
native
notplaceable;
/** If true the driver will be ejected if he leaves*/
var bool bShouldEject;
cpptext
{
virtual UBOOL ReachedDesiredRotation();
}
/**
* Attach GameObject to mesh.
* @param GameObj Game object to hold
*/
simulated event HoldGameObject(UDKCarriedObject GameObj);
/**
* Use the SwitchWeapon binding (number keys bound on keyboard by default)
* to switch seats when in a multi-seat vehicle.
*/
simulated function SwitchWeapon(byte NewGroup)
{
ServerChangeSeat(NewGroup-1);
}
/**
* Request change to adjacent vehicle seat
*/
simulated function AdjacentSeat(int Direction, Controller C)
{
ServerAdjacentSeat(Direction, C);
}
/**
request change to adjacent vehicle seat
*/
reliable server function ServerAdjacentSeat(int Direction, Controller C);
/**
* Called when a client is requesting a seat change
*
* @network Server-Side
*/
reliable server function ServerChangeSeat(int RequestedSeat);
/**
* @Returns the scale factor to apply to damage affecting this vehicle
*/
function float GetDamageScaling()
{
if (Driver != None)
{
return (Driver.GetDamageScaling() * Super.GetDamageScaling());
}
else
{
return Super.GetDamageScaling();
}
}
/**
* @Returns true if the AI needs to turn towards a target
*/
function bool NeedToTurn(vector Targ)
{
local UDKWeapon VWeapon;
// vehicles can have weapons that rotate independently of the vehicle, so check with the weapon instead
VWeapon = UDKWeapon(Weapon);
if (VWeapon != None)
{
return !VWeapon.IsAimCorrect();
}
else
{
return Super.NeedToTurn(Targ);
}
}
simulated function DrivingStatusChanged()
{
Super.DrivingStatusChanged();
if (!bDriving)
{
StopFiringWeapon();
}
}
function bool DriverEnter(Pawn P)
{
local AIController C;
if (Super.DriverEnter(P))
{
// update AI enemy
foreach WorldInfo.AllControllers(class'AIController', C)
{
if (C.Enemy == P)
{
C.Enemy = self;
}
}
return true;
}
else
{
return false;
}
}
/** Stub: applies weapon effects based on the passed in bitfield */
simulated function ApplyWeaponEffects(int OverlayFlags, optional int SeatIndex);
/**
* Statistics gathering
*/
function name GetVehicleDrivingStatName()
{
local name VehicleStatName;
VehicleStatName = name('DRIVING_'$Class.name);
return VehicleStatName;
}
/**
EjectDriver() throws the driver out at high velocity
*/
function EjectDriver()
{
local float Speed;
local rotator ExitRotation;
if ( Driver == None )
{
return;
}
if ( PlayerController(Driver.Controller) != None )
{
ExitRotation = Rotation; //rotator(Velocity); <-- this resulted in weirdness if ejecting from a stop.
ExitRotation.Pitch = -8192;
ExitRotation.Roll = 0.0;
Driver.Controller.SetRotation(ExitRotation);
Driver.Controller.ClientSetRotation(ExitRotation);
}
Speed = VSize(Velocity);
if (Speed < 2600 && Speed > 0)
{
Driver.Velocity = -0.6 * (2600 - Speed) * Velocity/Speed;
Driver.Velocity.Z = 600;
}
else
{
Driver.Velocity = vect(0,0,600);
}
if ( UDKPawn(Driver) != None )
{
UDKPawn(Driver).CustomGravityScaling = 0.5;
UDKPawn(Driver).bNotifyStopFalling = true;
UDKPawn(Driver).MultiJumpRemaining = 0;
}
}
simulated function DetachDriver(Pawn P)
{
local UDKPawn UTP;
Super.DetachDriver(P);
UTP = UDKPawn(P);
if (UTP != None)
{
// Turn on cloth again
UTP.Mesh.UpdateRBBonesFromSpaceBases(TRUE,TRUE);
if (UTP.Mesh.PhysicsAssetInstance != None)
{
UTP.Mesh.PhysicsAssetInstance.SetAllBodiesFixed(TRUE);
UTP.Mesh.PhysicsAssetInstance.SetFullAnimWeightBonesFixed(FALSE, UTP.Mesh);
}
UTP.Mesh.bUpdateKinematicBonesFromAnimation = UTP.default.Mesh.bUpdateKinematicBonesFromAnimation;
UTP.SetWeaponAttachmentVisibility(true);
UTP.SetHandIKEnabled(true);
}
}
/**
* AI - Returns the best firing mode for this weapon
*/
function byte ChooseFireMode()
{
if (UDKWeapon(Weapon) != None)
{
return UDKWeapon(Weapon).BestMode();
}
return 0;
}
/**
* AI - An AI controller wants to fire
*
* @Param bFinished unused
*/
function bool BotFire(bool bFinished)
{
local UDKBot Bot;
Bot = UDKBot(Controller);
if (Bot != None && Bot.ScriptedFireMode != 255)
{
StartFire(Bot.ScriptedFireMode);
}
else
{
StartFire(ChooseFireMode());
}
return true;
}
/**
* Shut down the weapon
*/
simulated function StopFiringWeapon()
{
if (Weapon != none)
{
Weapon.ForceEndFire();
}
}
/**
* Called on both the server and owning client when the player leaves the vehicle. We want to make sure
* any active weapon is shut down
*/
function DriverLeft()
{
local AIController C;
// update AI enemy
foreach WorldInfo.AllControllers(class'AIController', C)
{
if (C.Enemy == self)
{
C.Enemy = Driver;
}
}
if (bShouldEject)
{
EjectDriver();
bShouldEject = false; // so next driver doesn't get ejected.
}
Super.DriverLeft();
}
/** handles the driver pawn of the dead vehicle (decide whether to ragdoll it, etc) */
function HandleDeadVehicleDriver()
{
local Pawn OldDriver;
local UDKVehicle VehicleBase;
if (Driver != None)
{
VehicleBase = UDKVehicle(self);
if ( VehicleBase == None )
VehicleBase = UDKVehicle(GetVehicleBase());
// if Driver wasn't visible in vehicle, destroy it
if (VehicleBase != None && VehicleBase.bEjectKilledBodies && (WorldInfo.TimeSeconds - LastRenderTime < 1.0) && (bDriverIsVisible || ((WorldInfo.GetDetailMode() != DM_Low) && !WorldInfo.bDropDetail)) )
{
// otherwise spawn dead physics body
if (!bDriverIsVisible && PlaceExitingDriver())
{
Driver.StopDriving(self);
Driver.DrivenVehicle = self;
}
Driver.TearOffMomentum = Velocity * 0.25;
Driver.SetOwner(None);
Driver.Died(None, VehicleBase.GetRanOverDamageType(), Driver.Location);
}
else
{
OldDriver = Driver;
Driver = None;
OldDriver.DrivenVehicle = None;
OldDriver.Destroy();
}
}
}
defaultproperties
{
Begin Object Name=SVehicleMesh
End Object
SightRadius=12000.0
bCanBeAdheredTo=TRUE
bCanBeFrictionedTo=TRUE
}