The three virtues of a programmer: Laziness, Impatience, and Hubris. – Larry Wall

Legacy:Bulldog

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
UT2003 :: Actor >> Pawn >> KVehicle >> KCar >> Bulldog (Package: Vehicles)
UT2004 :: Actor >> Pawn >> Vehicle >> KVehicle >> KCar >> Bulldog (Package: Vehicles)

This is the first vehicle included with an Unreal gametype. It was introduced in UT2003, but was only available as a test map, "VehicleDemo". This is a Karma based vehicle (KVehicle). It is equipped with a homing rocket launcher.

Note: As the bulldog is not an ONSVehicle or ASVehicle class, the UT2004 version does not contain the proper code to navigate. While you are able to spawn a Bulldog from other Vehicle Factories and enter it, players will be unable to drive it or fire its weapon without custom modification. See UT2004 Bulldog Fix below.

Properties[edit]

Main[edit]

float FireInterval 
float TargettingInterval 
vector RocketFireOffset 
Position (car ref frame) that rockets are launched from.
float TargettingRange 
Material TargetMaterial 
vector HeadlightCoronaOffset[8] 
float TriggerSpeedThresh 
Maximum speed at which you can get in the vehicle.

Wheel Slip and Dust[edit]

float DustSlipRate 
Ratio between dust kicked up and amount wheels are slipping.
float DustSlipThresh 

Bulldog Sounds[edit]

float EnginePitchScale 
sound BulldogStartSound 
sound BulldogIdleSound 
float HitSoundThreshold 
sound BulldogSquealSound 
float SquealVelThresh 
sound BulldogHitSound 

Bulldog Forces[edit]

string BulldogStartForce 
string BulldogIdleForce 
string BulldogSquealForce 
string BulldogHitForce 

Destroyed Bulldog[edit]

class<Actor> DestroyedEffect 
sound DestroyedSound 

Hidden[edit]

float UntilNextImpact 
Used to prevent triggering sounds continuously.
float DustDrop 
Distance below centre of tire to place dust.

Bulldog Triggers[edit]

vector FrontTriggerOffset (const) 
BulldogTrigger FLTrigger 
BulldogTrigger FRTrigger 
BulldogTrigger FlipTrigger 
bool TriggerState 
true for on, false for off.
bool FlipTriggerState 

Headlight Projector[edit]

vector HeadlightOffset (const) 
BulldogHeadlight Headlight 
bool HeadlightOn 

Light Materials[edit]

Material ReverseMaterial 
Material BrakeMaterial 
Material TailOffMaterial 
Material HeadlightOnMaterial 
Material HeadlightOffMaterial 
BulldogHeadlightCorona HeadlightCorona[8] 

Wheel Dirt Emitter[edit]

BulldogDust Dust[4] 
FL, FR, RL, RR

Weapon[edit]

float FireCountdown 
float SinceLastTargetting 
Pawn CurrentTarget 

Functions[edit]

(incomplete)

Events[edit]

UT2004 Bulldog Fix[edit]

The Bulldog in UT2004 is broken for a number of reasons; in part due to a move of KVehicle from a subclass of Pawn to a subclass of Vehicle, but also due to other changes that enable Vehicle support in UT2004.

Source Code[edit]

To fix it, you'll need to Create A Subclass of the Bulldog, ModifiedBulldog, and use this custom code. For a tutorial on using custom code, see Mapping Hello World. (Note: If you use the Script Editor to compile this code, omit the defaultProperties block and set those manually for each class.)

//=============================================================================
// ModifiedBulldog.
// Uses Vehicle.KDriverEnter() instead of KVehicle.KDriverEnter(), etc.
// by SuperApe -- Dec 2005
//=============================================================================
class ModifiedBulldog extends Bulldog
	placeable;
 
var(Bulldog) sound     BulldogShutDownSound;
 
function Timer()
{
	// Finished start sound
	AmbientSound = BulldogIdleSound;
}
 
function KDriverEnter( Pawn P )
{
	local Controller C;
 
 
	AmbientSound = BulldogStartSound;
	SetTimer( 1.0, false );
 
	bDriving = True;
	StuckCount = 0;
 
	// We don't have pre-defined exit positions here, so we use the original player location as an exit point
	if ( !bRelativeExitPos )
	{
		PlayerEnterredRotation = P.Rotation;
		ExitPositions[0] =  P.Location + Vect(0,0,16);
	}
 
	// Set pawns current controller to control the vehicle pawn instead
	C = P.Controller;
	if ( !bCanCarryFlag && ( C.PlayerReplicationInfo.HasFlag != None )  )
		P.DropFlag();
 
	Driver = P;
	Driver.StartDriving( Self );
 
	// Disconnect PlayerController from Driver and connect to SVehicle.
	C.bVehicleTransition = true; // to keep Bots from doing Restart()
	C.Unpossess();
	Driver.SetOwner( self ); // This keeps the driver relevant.
	C.Possess( self );
	C.bVehicleTransition = false;
 
	DrivingStatusChanged();
 
	if ( PlayerController( C ) != None )
		VehicleLostTime = 0;
 
	AttachFlag( PlayerReplicationInfo.HasFlag );
 
	Level.Game.DriverEnteredVehicle( self, P );
 
	ReceiveLocalizedMessage( class'Vehicles.BulldogMessage', 1 );
}
 
event bool KDriverLeave( bool bForceLeave )
{
	local Controller C;
	local PlayerController	PC;
	local bool havePlaced;
	local Pawn	OldDriver;
	local	int 	i;
 
	if( !bForceLeave && !Level.Game.CanLeaveVehicle(self, Driver) )
		return false;
 
	if ( (PlayerReplicationInfo != None) && (PlayerReplicationInfo.HasFlag != None) )
		Driver.HoldFlag(PlayerReplicationInfo.HasFlag);
 
	// Do nothing if we're not being driven
	if (Controller == 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 ( (Driver != None) && (!bRemoteControlled || bHideRemoteDriver) )
    {
	    Driver.bHardAttach = false;
	    Driver.bCollideWorld = true;
	    Driver.SetCollision(true, true);
	    havePlaced = PlaceExitingDriver();
 
	    // If we could not find a place to put the driver, leave driver inside as before.
	    if (!havePlaced && !bForceLeave )
	    {
	        Driver.bHardAttach = true;
	        Driver.bCollideWorld = false;
	        Driver.SetCollision(false, false);
	        return false;
	    }
	}
 
	bDriving = False;
 
	// Turn off bulldog headlights
	Headlight.DetachProjector();
	Skins[2] = HeadlightOffMaterial;
	for(i=0; i<8; i++)
		HeadlightCorona[i].bHidden = true;
 
	// Reconnect Controller to Driver.
	C = Controller;
	if (C.RouteGoal == self)
		C.RouteGoal = None;
	if (C.MoveTarget == self)
		C.MoveTarget = None;
	C.bVehicleTransition = true;
	Controller.UnPossess();
 
	if ( (Driver != None) && (Driver.Health > 0) )
	{
		Driver.SetOwner( C );
		C.Possess( Driver );
 
		PC = PlayerController(C);
		if ( PC != None )
			PC.ClientSetViewTarget( Driver ); // Set playercontroller to view the person that got out
 
		Driver.StopDriving( Self );
	}
	C.bVehicleTransition = false;
 
	if ( C == Controller )	// If controller didn't change, clear it...
		Controller = None;
 
	Level.Game.DriverLeftVehicle(self, Driver);
 
	// Car now has no driver
	OldDriver = Driver;
	Driver = None;
 
	DriverLeft();
 
	// Put brakes on before you get out :)
    Throttle	= 0;
    Steering	= 0;
	Rise		= 0;
 
	PlaySound( BulldogShutDownSound, SLOT_Misc );
 
	// If we succesfully got out of the car, make driver visible again.
	OldDriver.bHidden = false;
	AmbientSound = None;
	return true;
}
 
function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation,
						Vector Momentum, class<DamageType> DamageType)
{
	Super.TakeDamage( Damage, InstigatedBy, HitLocation, Momentum, DamageType );
 
	KAddImpulse( Momentum, HitLocation);
}
 
defaultproperties
{
     DestroyedEffect=Class'myLevel.DECO_DestroyedBulldog'
     DestroyedSound=Sound'ONSVehicleSounds-S.Explosions.VehicleExplosion01'
     BulldogShutDownSound=Sound'ONSVehicleSounds-S.PRV.PRVStop01'
     BulldogStartSound=Sound'ONSVehicleSounds-S.PRV.PRVStart01'
     BulldogIdleSound=Sound'ONSVehicleSounds-S.RV.RVEng01'
     BulldogSquealSound=Sound'ONSVehicleSounds-S.PRV.DirtSkid03'
     BulldogHitSound=Sound'ONSVehicleSounds-S.CollisionSounds.VehicleCollision04'
     HornSounds(0)=Sound'ONSVehicleSounds-S.Horns.Horn03'
     bDontPossess=False
     Begin Object Class=KarmaParamsRBFull Name=KarmaParamsRBFull1
         KInertiaTensor(0)=20.000000
         KInertiaTensor(3)=30.000000
         KInertiaTensor(5)=48.000000
         KCOMOffset=(X=0.800000,Z=-0.700000)
         KLinearDamping=0.000000
         KAngularDamping=0.000000
         KStartEnabled=True
         bHighDetailOnly=False
         bClientOnly=False
         bKDoubleTickRate=True
         KFriction=1.600000
     End Object
     KParams=KarmaParamsRBFull'myLevel.KarmaParamsRBFull1'
}

This ModifiedBulldog uses a static mesh as a Destroyed Vehicle mesh. It's a subclass of Decoration -> DECO_Smashable. Here's it's code:

//=============================================================================
// DECO_DestroyedBulldog.
//=============================================================================
class DECO_DestroyedBulldog extends DECO_Smashable
	placeable;
 
defaultproperties
{
     EffectWhenDestroyed=Class'XEffects.RocketExplosion'
     Health=100
     DrawType=DT_StaticMesh
     StaticMesh=StaticMesh'BulldogMeshes.Simple.S_Chassis'
     Physics=PHYS_Falling
     LifeSpan=5.000000
     DrawScale=0.400000
     Skins(0)=Texture'AS_Vehicles_TX.IonPlasmaTank.IonTankBodyDEAD'
}

ModifiedBulldog Notes[edit]

Things that work:

  • You can get in and out of the Bulldog and other vehicles.
  • You can hear the horn, startup, idle and shutdown sounds (borrowed heavily from ONS vehicles)
  • The destroyed Bulldog shows a mesh, not just a RocketExplosion effect.
  • Headlights come on when driving, go off when not.
  • All normal drivability and BulldogRocket turret functionality, including homing rockets to vehicles or players with hud display on lock.

Things that don't work:

  • If you jump out and the Bulldog keeps rolling (it has no parking brake without a driver, ATM) you loose the BulldogTriggers that enable you to get back in.
  • The Deco_DestroyedBulldog mesh doesn't quite fall and hit the ground like it should, the tires simply disappear and there's no neat explosion or smoke.
  • The Bulldog "dust" and "rocks" trail behind the bulldog no matter what terrain (or BSP) it's on. (should probably take the level's dust color property)

Technical Notes[edit]

The code for KVehicle, KCar and Bulldog is exactly the same as in UT2003, but it was it's interaction with Vehicle and Controller code that seemed to cause problems. The main things that were breaking the Bulldog were KVehicle.KDriverEnter() and KVehicles.KDriverLeave(), although there were many disabled things in the Bulldog code like sounds and the KAddImpulse when it gets hit.

Related Topics[edit]

Discussion[edit]

SuperApe: I've been curious about this since UT2004 came out. Although, this just reminds me how badly the Bulldog handles; bad shocks that flop around and the momentum keeps the front tires from gripping enough to steer well. I'm still not sure exactly what part of those KVehicle functions broke it. Any thoughts on this are welcome here in the Discussion section. I will update the source code when we know more.

DaWrecka: On the subject of Bulldog handling, I did play around with this some in UT2003...While I stress I've NOT tried this with UT2004, in 2k3 I found cranking up the KActorGravScale of the Bulldog's KParams actually made it handle more-or-less as you would expect a jeep-thing to handle. A value of 3 worked nicely. That's assuming the level was in normal gravity of course...Reduced level gravity would bollocks the whole thing up just like normal.

Sweavo: I wonder whether a better idea is to steal the hellbender code and re-mesh it as a bulldog... Not that I'll get time to do that but there we go.