Open Source/TeamVehicleFactory - Unreal Wiki

# Open Source/TeamVehicleFactory

### From Unreal Wiki, The Unreal Engine Documentation Site

UT2004 :: Actor >> SVehicleFactory >> TeamVehicleFactory (custom)

This custom actor really duplicates much of the functionality of the ONSVehicleFactory subclasses, but the big feature is that nearly any vehicle class can be spawned. Although this actor cannot display the selected vehicle class in the editor, it does offer added controls that mappers for VCTF or other vehicle gametypes might want.

## Features

- The ability to spawn random vehicles from a list of vehicle classes
- The ability to spawn nearly any vehicle class in gametypes that allow vehicles
- The ability to trigger PreSpawn and (Post)Spawn events
- The option to allow the vehicle to spawn over and crush other actors
- The option to use this as either a triggerable or an automatic (timed) vehicle factory.
- Greater control over spawn timing

## Notes

- If you use a TeamVehicleFactory "as is" in your custom map, please credit me in the readme file of the map. (SuperApe)
- You have to supply spawning effects and sounds, via ScriptedTrigger, Emitter and the like. This is meant to allow flexibilty in the ways you want vehicles to spawn. An example VCTF map posted on this UP Forum thread gives my suggestion for spawning particles and sound. (It appears similar to pickup spawning.)
- With bAutoSpawn on and without a PreSpawnTime of around 2 seconds, you run the risk of spawning a vehicle before headlights can be properly spawned at map start. Subsequent vehicles after map start will spawn headlights normally.
- Turrets that are spawned automatically get an AIController. They are auto turrets; firing at enemies, or if set to neutral (team 255), firing at any non-neutral controlled pawn it detects.
- The AS Spacefighters are spawned with a minimum velocity that makes them impractical to use. However, a custom launcher for these is easy to make with a TryToDrive() function.
- This has a slightly larger bBlocked check radius than ONSVehicleFactory. ( 1.33 : 1.25 )

## Properties

### Main

int TeamNum
  Team Number to be set on spawn. 0= red, 1= blue, 255= neutral / none
bool bPlayerControl
  Only player instigators can trigger.
bool bAutoSpawn
  Will spawn at regular intervals. The triggering ability is disabled.
int RespawnTime
  Interval to wait before AutoSpawning.

name PreSpawnEvent
  Event to trigger before spawn.
int PreSpawnTime
  Time before spawn to trigger event. Will begin event this many seconds before the factory is set to AutoSpawn.
name SpawnEvent
  Event to trigger after spawn. A post spawn event.
bool bCrushable
  Allow spawning over colliding actors. Note: Turrets will normally spawn in collision with other actors, spawned vehicles will generally move out of the way.
int RetrySpawnTime
  Interval to wait if bBlocked.
bool bRandomFlip
  Neutral vehicles may face backwards.
bool bRandomSpawn
  Will spawn random vehicle class.
struct class<Vehicle> SpawnedVehicle
  Selected random vehicle class.
array<SpawnedVehicle> RandomVehicles
  List for random vehicle spawn.

### Hidden

bool bWaiting
  Waiting to spawn.
int FactoryTime
  Time last spawn. (in Level.TimeSeconds)
bool bPreSpawn
  Should trigger PreSpawnEvent next.

## Code

    </span><div class="hidden">//==================================================================================
    // TeamVehicleFactory.
    // Spawn any Vehicle or Turret, set Team, pre & post spawn Events, timing, and more.
    // Glenn 'SuperApe' Storm -- June 2004 -- Updated: July 2005
    //==================================================================================
    class TeamVehicleFactory extends SVehicleFactory
            placeable;

    var()        int                    TeamNum ;                  // 0= red, 1= blue, 255= neutral / none
    var()        bool           bPlayerControl ;   // Only player instigators can trigger

    var()        bool           bAutoSpawn ;               // Will spawn at regular intervals
    var()        int                    RespawnTime ;              // Interval to wait before AutoSpawning

    var            bool           bWaiting ;                 // About to spawn
    var            int                    FactoryTime     ;               // Time last spawn

    var()        name           PreSpawnEvent ;            // Event to trigger before spawn
    var()        int                    PreSpawnTime ;             // Time before spawn to trigger event
    var            bool           bPreSpawn ;                        // Should trigger PreSpawnEvent next
    var()        name           SpawnEvent ;               // Event to trigger after spawn

    var()        bool           bCrushable ;               // Allow spawning over colliding actors
    var()        int                    RetrySpawnTime ;   // Interval to wait if bBlocked

    var()        bool           bRandomFlip ;              // Neutral vehicles may face backwards

    var()        bool                                   bRandomSpawn ;             // Spawn random vehicle class
    struct SpawnedVehicle
    {
            var()        class<Vehicle>            SpawnVehicle;           // Selected random vehicle class
    };
    var()        array<SpawnedVehicle>     RandomVehicles ;   // List for random vehicle spawn

    simulated function PostBeginPlay()
    {
            Super.PostBeginPlay();

            if ( bAutoSpawn )
                    bWaiting = true;
                    bPreSpawn = true;
                    if ( RespawnTime > 0 )
                            FactoryTime = Level.TimeSeconds - RespawnTime + PreSpawnTime;
                    else
                            FactoryTime = Level.TimeSeconds - PreSpawnTime;
    }

    simulated event Trigger( Actor Other, Pawn EventInstigator )
    {
            if ( bAutoSpawn )
                    // bAutoSpawn overrides Trigger
                    return;

            if ( !EventInstigator.IsA('UnrealPawn') && bPlayerControl )
                    return;

            if ( VehicleCount >= MaxVehicleCount )
                    return;

            if ( VehicleClass == None || ( bRandomSpawn && RandomVehicles.length > 0 ) )
            {
                    Log("TeamVehicleFactory:"@self@"has no VehicleClass");
                    return;
            }

            bWaiting = true;
            bPreSpawn = true;
            if ( RespawnTime > 0 )
                    FactoryTime = Level.TimeSeconds - RespawnTime + PreSpawnTime;
            else
                    FactoryTime = Level.TimeSeconds - PreSpawnTime;
    }

    simulated function SpawnItNow()
    {
            local  Vehicle         CreatedVehicle;
            local  bool           bBlocked;
            local  Pawn              P;
            local  float          SV;

            bBlocked = false;

            if ( VehicleClass != None || ( bRandomSpawn && RandomVehicles.length > 0 ) )
            {
                    if ( bRandomSpawn && RandomVehicles.length > 0 )
                            VehicleClass = RandomVehicles[ int( FRand() * RandomVehicles.length ) ].SpawnVehicle;
                foreach CollidingActors(class'Pawn', P, VehicleClass.default.CollisionRadius * 1.33)
                            bBlocked = true;
            }
            else
            {
                    Log("TeamVehicleFactory:"@self@"has no VehicleClass");
                    return;
            }

        if ( bBlocked && !bCrushable )
            {
                    bWaiting = true;
                    bPreSpawn = true;
                    if ( RespawnTime > 0 )
                            FactoryTime = Level.TimeSeconds - RespawnTime + RetrySpawnTime + PreSpawnTime;
                    else
                            FactoryTime = Level.TimeSeconds - RetrySpawnTime + PreSpawnTime;
                    return;
            }
        else
                    {
                            if ( TeamNum == 255 )

                            {
                                    if ( bRandomFlip && Rand(2) == 1 )
                                            CreatedVehicle = spawn(VehicleClass, , , Location, Rotation + rot(0,32768,0));
                                    else
                                            CreatedVehicle = spawn(VehicleClass, , , Location, Rotation);
                                    // Unlock neutral vehicles
                                    CreatedVehicle.bTeamLocked = false;
                            }
                            else
                                    CreatedVehicle = spawn(VehicleClass, , , Location, Rotation);
                            if ( CreatedVehicle != None )
                            {
                                    VehicleCount++;
                                    CreatedVehicle.Event = Tag;
                                    CreatedVehicle.ParentFactory = self;
                                    CreatedVehicle.SetTeamNum(TeamNum);
                                    TriggerEvent(SpawnEvent, self, None);
                            }
                    }
    }

    event VehicleDestroyed(Vehicle V)
    {
            Super.VehicleDestroyed(V);

            if ( bAutoSpawn )
            {
                    bWaiting = true;
                    bPreSpawn = true;
                    FactoryTime = Level.TimeSeconds;
            }
    }

    simulated function Tick(float DeltaTime)
    {
            if ( bWaiting )
            {
                    if ( Level.TimeSeconds - FactoryTime < RespawnTime - PreSpawnTime )
                            return;

                    if ( VehicleCount < MaxVehicleCount )
                            if ( !bPreSpawn )
                            {
                                    if ( Level.TimeSeconds - FactoryTime >= RespawnTime )
                                    {
                                            bWaiting = false;
                                            FactoryTime = Level.TimeSeconds;
                                            SpawnItNow();
                                    }
                            }
                            else
                            {
                                    bPreSpawn = false;
                                    TriggerEvent(PreSpawnEvent, self, None);
                            }
            }
    }

    simulated function Reset()
    {
        local Vehicle V;

        if ( VehicleCount > 0 )
            forEach AllActors ( class 'Vehicle', V )
                if ( V.ParentFactory == self )
                    V.Destroy();

        Super.Reset();
    }

## External Links

- Mapping for VCTF – A thread on UnrealPlayground that includes a test map using this actor and suggested spawn EFX.

## Related Topics

- Mapping for AS (UT2004)
- Mapping for ONS
- Mapping for VCTF
- Mapping for OSM Adventure (Note: A version of TeamVehicleFactory is included in OSMT)
- Pathing For Vehicles
- Pathing 2k4 Flying Vehicles
- Vehicles – Hub for all vehicle topics
  - Vehicle – UT2004 parent class for all vehicles and turrets
  - Vehicle Gameplay – Placing VehicleFactories for strong Map Flow

## Discussion

SuperApe: Originally this actor included a bForceAllow option that overrode the Level.bAllowVehicles setting. Since the latest patch to UT2004 moved that check up to SVehicle, that will not work anymore. Alas, that very cool option to include vehicles in any gametype would have to be left out. :( Now, I offer it as simply a way to get any vehicle class into gametypes which *do* allow vehicles. Enjoy! :)

MythOpus: Why couldn't you just set the bAllowVehicles property through the code?

SuperApe: You mean like this?

    if ( !Level.Game.bAllowVehicles && bForceAllow )
        Level.Game.bAllowVehicles = true;

MythOpus: Yes, something like that :P :) Good luck.

SuperApe: No luck. I believe the new patch for 2k4 moved many of the bAllowVehicle checks either higher in the actor heirarchy, or like into SVehicle itself.

SuperApe: A request has been made by a mapper for Red Orchestra to include a Reset() function for this actor. If you have a triggered version of this factory and the map is reset, any outstanding vehicles are still there. Working...

SuperApe: I've added the Reset() function that should work fine. In fact, I had difficulty duplicating the problem of a stranded vehicle after map reset. Nevertheless, this Reset() function won't hurt and it may solve the problem for the Red Orchestra mapper.

SuperApe: Thanks to a suggestion by ZedMaestro on the BUF, I've added a feature for spawning random vehicle classes. Just set bRandomSpawn = true and the list of possible vehicle classes in RandomVehicles. Also, in relation to the above discussion about forcing to allow vehicles in any gametype, there is a SuperVehicleFactory in testing on the UnrealPlayground forums.

VitalOverdose: when i got cut offline i took a whole buch of the most difficult problems from atari forums and wiki and decided to crack each one as i was gonna be ofline for atleast 4months.your teamvehiclefactory idea was on i decided to have a go at.As far as i can see it does everything you specified in the orignal design spec. i was thinking between us we could come up with an ultimate solution but if not np.

SuperApe: I think I understand the confusion. The TeamVehicleFactory is not a problem which I am trying to find a solution for, it is a custom actor I've posted on the wiki after testing thoroughly and developing somewhere else. I post it here for others to use at their discretion, as a Third-Party component. If you would like to take the code, use it in a custom map, or even expand on it and modify it for specific purposes, that's fine by me. That's why I posted it here. Just remember, the normal etiquette is to give credit for the source in those situations, either in the map's readme file or the code's initial comment block, or both. If you would like help finding a solution to a problem you're having with your own code, I suggest posting (in brief) the problem's details on the Help Desk. Personally, I wasn't at all clear what you wanted help with. But at any rate, that code didn't belong here in the Discussion of this page. Thanks for moving it. :)

Moofed: I noticed the first vehicle that is spawned from a TeamVehicleFactory doesn't have a HeadlightProjector, but all vehicles afterwards do. Not sure what's causing it. :-/

SuperApe: Hmm. I'm not seeing that bug. Headlights are spawned from the vehicle (ONSVehicle) during PostNetBeginPlay(). Can't think of why your first vehicle wouldn't have them when you jump in.

Moofed: Fixed by setting PreSpawnTime=2. I think bDropDetail gets set (and the coronas and projectors not spawned) because the computer is bogged down by the level loading, which happens to be at the same time as the vehicles are spawning when using bAutoSpawn.

SuperApe: Ah, that makes more sense. Without including a default spawn effect, that is a potential problem with this script. I didn't see it due to the effects I include in the test map, linked to above. Perhaps I should add the suggested spawn effects as a small block of code. Thanks. :)

SuperApe: I believe the Reset() function does absolutely nothing. Vehicles themselves have their own Reset() functon, so it's redundant, IIRC. I will update the code with defaultproperties and include code for a default spawning Effects class to use with this factory as an option, so that mappers can choose to use custom spawning efx or not.

SuperApe: This class is included in Old Skool Monsta Toolz and adds the feature of bDefaultEFX, which spawns particles and sounds that indicate the team the vehicle is spawning for and the size of the vehicle about to spawn. I will update the code to match OSMT.TeamVehicleFactory soon.

Category: Legacy Custom Class (UT2004)

##### Views

- Page
- Discussion
- Current revision

##### Search