My program doesn't have bugs. It just develops random features.
Legacy:VitalOverdose/BotLock
Contents
Overview[edit]
This actor is designed to be attacked to a vehicle. When its attached it also locks in the xbots for the total length of time the emitter fx is alive. This was needed for the ONSVehicleBooster to stop the xbot from bailing the moment they got the boost and later the more advanced SFXUltralight emitter system. This emitter not only make nice fx it acts a sort of Vehicle controller to any vehicle it is HardAttached to.
I wanted only to have the trail fx while the vehicle was airborne so the timer function has been overwritten and will scan the vehicle its attached to to see if all four wheels are touching the ground or not.
The scan rate or TimerFrequency can be set by the mapper in unrealEd.
The is also a safe time for the doors to stay locked after the vehicle has made contact with the ground again. This is quite simply because most landings still manage to freak the bots out enough to bail. So the solution is to hold them captive for about 2 seconds until the vehicle has decelerated to a speed they can cope with.
bScanningTargetVec[edit]
Is a flag to help us use the timer function for 2 different jobs.
Note:[edit]
This use internally and cannot be set by the mapper as it has not got () after the var statement.
bLockAllPawns[edit]
Can Be true or false. set by the mapper in unrealed. If set to true all players will be locked in not just the bots.
BeginScanVec[edit]
Is the delaytime for the scanning that checks if the vehicle has been grounded or not as the whole scanning process is a bit CPU intensive and should be kept to an absolute minimum if possible. IE boosting off a high cliff you are not going to have to begin checking for maybe a few seconds. It doesn't seem much but in a game which is highly Dependant of bandwidth speed like ut2004 we have to optimize anywhere we can.
LandedLockTime[edit]
The amount of time to keep the driver locked in after the vehicle has landed.
TimerFrequency[edit]
The Scan Rate. The timer function get called repeatedly and the TimerFrequency specifies the amount of time between each scan.
Var bool bScanningTargetVec; Var () Bool bLockAllPawns; Var () Float BeginScanVec; Var () Float LandedLockTime; Var () Float TimerFrequency;
PostBeginPlay()[edit]
The function PostBeginPlay gets called directly after the emitter is spawned and is a good place to check a few of the values the mapper may or may not have set in Unrealed.
First argument reads;[edit]
- If our base is not a vehicle & our owner IS a vehicle.
- If the argument is true then the emitter hard attaches itself to its owner.
The next argument reads;-[edit]
- If our owner (typecasted to vehicle) doesn't have xbot for driver and BlockAllPawns = True
- call function ToggleLock().
- Set timer to go of every TimerFrequency Seconds.
- Any code related to this function from the parent class is copied in here by using the .super function.
Function PostBeginPlay() { if (( !base.IsA('onsvehicle' ) && (owner.IsA('onsvehicle') ) setbase(owner); if ((OnsVehicle(Owner).Driver.IsA('xBot')) && (bLockAllPawns)) { Togglelock(); SetTimer(BeginScanVec,False ); } Super.PostBeginPlay(); }
Timer()[edit]
Here the timer() function is being used for two different jobs.
Its first job is to call checkGrounded() every timerfrequency seconds then after the scanning has stopped it acts as the Safe time for the bots to be kept locked in the vehicle after it has landed.
First argument[edit]
- is bScanningTargetVec set to true?
- true:
- is the result sent back by the function checkgrounded() equal to true?
- True:
- Timerfrequency is set to 0 as a flag as its no longer needed.
- The timer() is reset to go off just once in LandedLockTime seconds.
- The code quits the function at this point.
Next argument;-[edit]
- Is bScanningTargetVec equal to false;-
- True:
- set BscanningtargetVec to true;
- Set the timer to be called repeatedly every TimerFrequency Seconds.
- Lock the bots it.
- The code exits the function here.
So at this from now on as bScanningTargetVec is set to true wee will only get as far as the first argument before hitting a return function and we wont be using the second argument again in this actors lifetime.
function Timer() { if ( bScanningTargetVec == true ) { if ( checkGrounded() == True ) { TimerFrequency = 0; SetTimer(LandedLockTime,False ); } Return; } If ( bScanningTargetVec == False ) { bScanningTargetVec = True; SetTimer(TimerFrequency,True); ToggleLock(); Return; } }
Togglelock()[edit]
This is a very simple function to toggle the property bDriverCannotLeaveVehicle on the vehicle the emitter is attached to.As there are only to arguments involved ant they both include the same Boolean variable then we raly only have to ask 1 question as if the first is not true then we know the second will be. so by putting a return in After the bDriverCannotLeaveVehicle variable has been set to true we don have to worry about the focus of the code dropping through into the next lot of code.
So the next line which simply set bDriverCannotLeaveVehicle to false will always be run by default if the first argument is false.
Function Togglelock() { If ( ONSVehicle(Owner).bDriverCannotLeaveVehicle == False ) { OnsVehicle(Owner).bDriverCannotLeaveVehicle = True; Return; } OnsVehicle(Owner).bDriverCannotLeaveVehicle = False; }
CheckGrounded()[edit]
The function Checkgrounded() gets called from timer every timerFrequency seconds to check if all 4 wheels are in contact with the ground or not. The BOOL after the word function means that a Boolean variable will be passed back to the point the function was called when a return Boolean Variableis called.
The way we check all 4 wheels is with a 'for-loop' and for this we need to set up a local integer variable to do the counting of the wheels.
Quite simply we don't need to check all four wheels if 1 of them is not touching the ground. so as soon as on is found that isn't we exit the function by returning FALSE.
So by default if the focus of the code hasn't exited by the end of the for next loop all 4 wheels have to be on the ground so we return a TRUE instead.
Function Bool checkGrounded() { Local Int i; for ( i=0 ; i<OnsVehicle(Owner).wheels.Length ; I++ ) If ( OnsVehicle(Owner).Wheels[I].bWheelOnGround == false ) return False; Return True; }
Full Script[edit]
The completed script looks like this;-
class BotLock extends class Emitter placeable; Var bool bScanningTargetVec; Var () Bool bLockAllPawns; Var () Float BeginScanVec; Var () Float LandedLockTime; Var () Float TimerFrequency; Function PostBeginPlay() { super.postbeginplay(); if ( !base.IsA('onsvehicle' ) && (owner.IsA('onsvehicle') ) ) setbase(owner); if ((OnsVehicle(Owner).Driver.IsA('xBot')) && (bLockAllPawns)) { Togglelock(); SetTimer(BeginScanVec,False ); } } function Timer() { Super.timer(); if ( bScanningTargetVec == true ) { if ( checkGrounded() == True ) { TimerFrequency = 0; SetTimer(LandedLockTime,False ); } Return; } If ( bScanningTargetVec == False ) { bScanningTargetVec = True; SetTimer(TimerFrequency,True); ToggleLock(); } } Function Togglelock() { If ( ONSVehicle(Owner).bDriverCannotLeaveVehicle == false ) OnsVehicle(Owner).bDriverCannotLeaveVehicle = True; else OnsVehicle(Owner).bDriverCannotLeaveVehicle = False; } Function Bool checkGrounded() { Local Int i; for ( i=0 ; i<OnsVehicle(Owner).wheels.Length ; I++ ) If ( OnsVehicle(Owner).Wheels[I].bWheelOnGround == false ) return False; Return True; }