Gah - a solution with more questions. – EntropicLqd

Legacy:VitalOverdose/BoostingVehicleFactory

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
UT2004 :: Actor >> SVehicleFactory >> ASVehicleFactory >> AllMapVecFactory (Package: custom)

by VitalOverdose

Overview

the boostingVecicle factory is a modified ASVehicle factory that adds an optional VitalOverdose/VecBooster to every vehicle it spawns. The auto boost is activated (on a timed delay) as soon as a player or bot enters the vehicle as a driver.Theres is a short delay between the driver entering and the actual boost taking place, this is to give the player time to position himself in the direction hes wishes to be boosted. The last 3 seconds of the boost has an optional vocal countdown. These can be switched off by simply removing the sounds in actor browser in unrealed at map creation time. The VecBoost process will happen every time a new driver gets in the vehicle depending on how many boosts the mapper has specified when they placed it in the map ( setting this property to -1 will result in Infinite boosts). the boost strength and direction can be altered be the mapper at map creation time. It is also possible to set the vehicle so that it will boost whoever enters the drivers seat no just a new driver.

There is a BotLock System used on the Vec for the boosting process (see VitalOverdose/VecBooster for details on why). This is automatic and the only settable property of the bot lock is 'BotCaptureTime'

BoostDelay          - Time delay for the boost on driver entry.
BotCaptureTime      - For the VitalOverdose/BotLock system.
bBoostsEmptyVecs    - If the vec should still boost if the driver leaves or dies during the countdown to the boost.
SameDriverRE_Boost  - If the current driver can leave then re-enter the vec and cause another boost
Voc_Booster         - For the vocal countdown.
Voc_one             - For the vocal countdown.
Voc_two             - For the vocal countdown.
Voc_three           - For the vocal countdown.
bDirectional        - Property already present in ASVehicleFactory. If true the vec will use the direction the.                                    BoostingVecFactory is facing to base the direction of the boost on.
TagfxClass          - An emitter actor to use as a trail for the boost effect. Simply leave blank to disable the trail.

Internal Variables (not available to the mapper).

Boosts              - How many available boosts this vec has.
LastDriver          - Valid actor ref of the last driver.
currentdriver       - Valid actor ref of the current driver.
RotRelation         - which actor to base the direction of the boost on ...indirectly set by mapper.
bPrimed             - Boolean to indicate if the vec is on a countdown to boost.
bBoosting           - Boolean to indicate if the vec has been boosted. Used to track the time on the botlock + trail Fx.
VocalCounter        - The vocal counter.
spawnedtagFX        - valid ref to the emitter making the fx trail.
bCounting           -

This Script is made possible by the way that the as vehicle factory keeps track of how many vehicles is spawned and whether it should be spawning a new one or not. When it does spawn a new vehicle the vehicles valid actor ref it recored by the factory and saved in the internal property called child. Also the vehicle itself takes a record of who spawned

function PostBeginPlay()

function PostBeginPlay()
{
 local Gameinfo FoundGameInfo;                                // blank variable of type 'Gameinfo' to store ref
 foreach DynamicActors(Class'Engine.Gameinfo', FoundGameInfo) // iterates though all dynamic actors that are 'gameinfos'
        {                                                     // and stores a ref to them in  FoundGameInfo
         FoundGameInfo.bAllowVehicles = True;                 // Sets the value FoundGameInfo.bAllowVehicles to true
        }
 RotRelation  = Self;
 if (voc_booster!=none)
    {
     VocalCounter=3;
    }
 enable ('tick');
 super.postbeginplay();                                       // copys any function related code from parent class
}

function Timer()

this is the hardest function to modify in this class as is already used for the delay on the spawning of the vehicle in the first place. So any extra code has to operate with out messing with the existing functions

function Timer()
{                                  
 if ( bCounting) 
     VocalCountdown();
else   
 if ((bPrimed)&&(bUseBoostvec==true) && (boosts!=-1))
     VecBoost();                       
 else
    if ((Bboosting) && ( ONSVehicle(child).bDriverCannotLeaveVehicle ))
        ONSVehicle(child).bDriverCannotLeaveVehicle = false;    
 
    if ( spawnedtagFX != None)
         spawnedtagFX.Destroyed();     
 
Super.Timer();
}

function VocalCountdown()

this function is real only here to make things easyer to follow in the timer function. The timer function calls this function once and then the next 3 timer calls are controled from the end of this function if vocal counting is required.

function VocalCountdown()
{
 VocalCounter -= 1;
 
if (VocalCounter == 0)
    {                                   
     child.playsound(Voc_booster);
     bcounting=false;
     bprimed=true;
    }
 else
 if (VocalCounter == 1)
     child.playsound(Voc_one);       
 else
 if (VocalCounter == 2)
     child.playsound(Voc_two);      
 else
 if (VocalCounter == 3)
     child.playsound(Voc_three);      
 
if (vocalcounter != -1) 
     SetTimer (1,false);
}

Simulated function VecBoost()

This is a modified version of the ONSVehicleBooster , it boosts the vehicle and spawns the Emitter fx. It then set the right flags in the boolean properties to indicate the new Virtual state of the vec. As we dont want to have to mess about with the vehicle code I'm keeping a 'VirtualRecord' of its state: either Primed ,Counting or Boosting so that decisions can be made based on what condition the vehicle is in at any one point in time.

Simulated function  VecBoost()
{
 local Vector PointBoostForce;                                                                            
 boosts -= 1;
 
 if ( bDirectional == True)
     RotRelation  = child;                                                   
 
  if ((child.driver != None)  &&  ( child.IsHumanControlled()==false))
      ONSVehicle(child).bDriverCannotLeaveVehicle = true;                     
 
 child.KAddImpulse( ActualBoostForce >> RotRelation.Rotation, PointBoostForce >> RotRelation.Rotation ) ;
 
 bPrimed   = false;                                                          
 bBoosting = true;                                                          
 
if (TagfxClass!=None)
    {
     spawnedtagFX=spawn(TagfxClass,child,,child.location,child.rotation);    
    if (spawnedtagFX != None )
        spawnedtagFX.setbase(child);
 
    }
    if ((child.driver != None)  &&  ( child.IsHumanControlled()==false))
        settimer(BotCaptureTime,false);                                        
 
}

Function VehicleSpawned()

this function is allready part of ASVhicle factory. it gets called from the function SpawnVehicle right after the vecfactory checks if the spawn whent ok. Here its being over written just to check the overall amount of boosts the vehicle has left. The new code is put in before the .super function and dosent contain any returns so it wont interfere with the way this function normaly works.

function VehicleSpawned()
{                                                                            
 
 if ( bUseBoostvec== true )
    {
     boosts = 1;
     boosts += RepeatBoosts;
    }
 
super.VehicleSpawned();
}

function Tick(float deltatime)

Here Tick() is over written to do most of the checking om the fx and the control over the botLock system. This leaves the timer function less cluttered and easyer to work with. Tick get run far more frequently that the timer (imn most cases) and it best not to have anything to complicated going on there as this is a strain on the cpu. There is a fair amount of code been added to tick in this case but i dont think its getting close to what would be considered to much

function Tick(float deltatime)
{
 
 if ( child != none )
    {
 
    if ((bBoosting) && (vocalcounter!= -1) && (Voc_Booster!=none))
        vocalcountdown();
 
    if ((child.Driver == none ) && (currentdriver!=None))
       {
        lastdriver    = currentdriver;                                       
        currentdriver = none;
 
        if ( bPrimed == true)
            bPrimed = false;                                                 
 
        if ( bboosting == true)
           {
            bboosting = false;                                               
            if ( spawnedtagfx!= none)
                 spawnedtagFX.Destroy();                                      
           }
        }
 
    if ((bBoosting)&& (onsvehicle(child).bVehicleOnGround))
       {
 
        bBoosting = false;
 
        if ( spawnedtagfx!= none)
            spawnedtagFX.Destroy();                                              
 
        if (onsvehicle(child).bDriverCannotLeaveVehicle == true)
            onsvehicle(child).bDriverCannotLeaveVehicle = false; 
 
       }
    }       
super.tick(deltatime);
}

function vehicledestroyed(Vehicle V)

This function is already present in asvehiclefactory and is called by the vehicle when it gets destroyed to tell the factory it needs to spawn another vehicle. Some code has been added to basically reset the timers and the virtual state of the vehicle (ie.primed,boosting etc).

function vehicledestroyed(Vehicle V)
{
 lastdriver    = currentdriver;                                              
 currentdriver = none;
 bboosting     = false;                                                      
 bPrimed       = false;                                                      
 
 if (spawnedtagfx != none)
     spawnedtagFX.Destroy();                                                 
 
Super.VehicleDestroyed(v);
}

Event VehicleUnPossessed( Vehicle V )

To save the stress on the cpu the trail fx are switched off if the driver leaves the vec while boosting. This also acts as a good visual indicator that someone has jumpped out that can be seen for some distance. The extra code here mainly deals with the seting of the right flags for the virtual state of the vec.

event VehicleUnPossessed( Vehicle V )
{
 lastdriver    = currentdriver;                                              
 currentdriver = none;
 if ( bBoosting == true)
    {
     bBoosting = false;                                                      
     if (spawnedtagFX!= none)
         spawnedtagFX.Destroyed();                                           
 
    if (bBoostsEmptyVecs != true)
       {
        if (vocalcounter != -1)
            vocalcounter = -1;
       }
    }
 else
 if ( bPrimed == true )
    {                                                                        
     if ( bBoostsEmptyVecs != true )
        {                                                                  
         bprimed = false;                                                   
 
        if( VocalCounter > -1)
            VocalCounter = -1;                                              
 
        }
    }
 
Super.VehicleUnPossessed(V);
}

Event VehiclePossessed( Vehicle V )

This is the function that really make this mod possible in the first place. The vehicle will report back to the factory that spawned it as soon as someone eneters it. This means that the vehicle code dosent have to be alltered at all as the vehicle factory can quite simply call kaddimpulse using either the valid ref stored in the property child or the new one gained through this function (just called V). One the function has called boost it just sets a few flags fort the veirtual status of the vec.

event VehiclePossessed( Vehicle V )
{
 currentdriver=v.Driver;                                                     
 if ((bUseBoostvec==true) && (boosts != -1))
    {
     if (voc_booster!=none)
        {
        VocalCounter=4;                                                      
        if ((voc_booster !=None) && (boostdelay >3))
           {
             boostdelay-=3;
             bCounting = true;
            }                     
        bPrimed=True;                                                         
       }
    }
Super.VehiclePossessed(V);
}

The Completed Script

Here is the completed Script for now;-

class BoostingVehicleFactory extends ASVehicleFactory
placeable;
 
var() bool              bUseBoostvec;
var() vector            ActualBoostForce;
var() int               RepeatBoosts;
var() int               BoostDelay;
var() int               BotCaptureTime;
var() bool              bBoostsEmptyVecs;
var() bool              SameDriverRE_Boost;
var() sound             Voc_Booster;
var() sound             Voc_one;
var() sound             Voc_two;
var() sound             Voc_three;
var   int               Boosts;
var   pawn              LastDriver;
var   pawn              currentdriver;
var   actor             RotRelation;
var   bool              bPrimed;
var   bool              bBoosting;
var   int               VocalCounter;
var   emitter           spawnedtagFX;
var() class<emitter>    TagfxClass< SEMI >
var   bool              bCounting;
 
function PostBeginPlay()
{
 local Gameinfo FoundGameInfo;                                // blank variable of type 'Gameinfo' to store ref
 foreach DynamicActors(Class'Engine.Gameinfo', FoundGameInfo) // iterates though all dynamic actors that are 'gameinfos'
        {                                                     // and stores a ref to them in  FoundGameInfo
         FoundGameInfo.bAllowVehicles = True;                 // Sets the value FoundGameInfo.bAllowVehicles to true
        }
 RotRelation  = Self;
 if (voc_booster!=none)
     VocalCounter=3;
 
 enable ('tick');
 super.postbeginplay();                                       // copys any function related code from parent class
}
 
function Timer()
{
 if ( bCounting)
    VocalCountdown();
 
 else
 if ((bPrimed)&&(bUseBoostvec==true) && (boosts!=-1))
     VecBoost();
 
 else
    if ((Bboosting) && ( ONSVehicle(child).bDriverCannotLeaveVehicle ))
       {
        ONSVehicle(child).bDriverCannotLeaveVehicle = false;
        if ( spawnedtagFX!=None)
             spawnedtagFX.Destroyed();
        }
 super.timer();
}
 
function VocalCountdown()
{
 VocalCounter -= 1;
 if (VocalCounter == 0)
    {
     child.playsound(Voc_booster);
     bcounting=false;
     bprimed=true;
    }
 
 else
 if (VocalCounter == 1)
     child.playsound(Voc_one);
 
 else
 if (VocalCounter == 2)
    child.playsound(Voc_two);
 
 else
 if (VocalCounter == 3)
    child.playsound(Voc_three);
 
 if (vocalcounter != -1)
    SetTimer (1,false);
 
}
 
Simulated function  VecBoost()
{
 local Vector PointBoostForce;
 boosts -= 1;
 if ( bDirectional == True)
     RotRelation  = child;
 
  if ((child.driver != None)  &&  ( child.IsHumanControlled()==false))
       ONSVehicle(child).bDriverCannotLeaveVehicle = true;
 
 child.KAddImpulse( ActualBoostForce >> RotRelation.Rotation, PointBoostForce >> RotRelation.Rotation ) ;
 bPrimed   = false;
 bBoosting = true;
 if (TagfxClass!=None)
    {
     spawnedtagFX=spawn(TagfxClass,child,,child.location,child.rotation);
     if (spawnedtagFX != None )
         spawnedtagFX.setbase(child);
    }
 
 if ((child.driver != None)  &&  ( child.IsHumanControlled()==false))
     settimer(BotCaptureTime,false);
 }
 
function VehicleSpawned()
{
 if ( bUseBoostvec== true )
    {
     boosts = 1;
     boosts += RepeatBoosts;
    }
 super.VehicleSpawned();
}
 
function Tick(float deltatime)
{
 if ( child != none )
    {
    if ((bBoosting)  && (vocalcounter!= -1) && (Voc_Booster!=none))
       vocalcountdown();
 
    if ((child.Driver == none ) && (currentdriver!=None))
       {
        lastdriver    = currentdriver;
        currentdriver = none;
        if ( bPrimed == true)
            bPrimed = false;
 
        if ( bboosting == true)
           {
            bboosting = false;
            if ( spawnedtagfx!= none)
                 spawnedtagFX.Destroy();
           }
        }
    if ((bBoosting)&& (onsvehicle(child).bVehicleOnGround))
       {
        bBoosting = false;
        if ( spawnedtagfx!= none)
            spawnedtagFX.Destroy();
 
        if (onsvehicle(child).bDriverCannotLeaveVehicle == true)
           onsvehicle(child).bDriverCannotLeaveVehicle = false;
      }
    }
super.tick(deltatime);
}
 
function vehicledestroyed(Vehicle V)
{
 lastdriver    = currentdriver;
 currentdriver = none;
 bboosting     = false;
 bPrimed       = false;
 
 if (spawnedtagfx != none)
     spawnedtagFX.Destroy();
 
Super.VehicleDestroyed(v);
}
 
event VehicleUnPossessed( Vehicle V )
{
 lastdriver    = currentdriver;
 currentdriver = none;
 
 if ( bBoosting == true)
    {
     bBoosting = false;
     if (spawnedtagFX!= none)
         spawnedtagFX.Destroyed();
 
     if ((bBoostsEmptyVecs != true)&&  (vocalcounter != -1))
         vocalcounter = -1;
     }
 else
 if  (( bPrimed == true )&&( bBoostsEmptyVecs != true ))
     {
     bprimed = false;
 
     if( VocalCounter > -1)
         VocalCounter = -1;
     }
super.VehicleUnPossessed(V);
}
 
event VehiclePossessed( Vehicle V )
{
CurrentDriver = V.Driver;
 
 if (((bUseBoostvec == true) && (boosts != -1))&& if (voc_booster != none))
    {
    VocalCounter = 4;
 
    if ((voc_booster != None) && (boostdelay > 3))
       {
        boostdelay -= 3;
        bCounting = true;
        }
 
    bPrimed = True;
    }
 super.VehiclePossessed(V);
}

RelatedTopics


Discussion