Cogito, ergo sum

Legacy:VitalOverdose/ONSVehicleTeleporter

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

by VitalOverdose

Overview[edit]

This class will teleport a vehicle without it exploding when it pops out on the other side.

There is only 1 actor to this teleport system as any actor that has it collision switched off can be a teleport exit point as long as its tagname matches the one specified by the mapper in the vehicle teleporters properties. Vehicle nodes and path nodes are ideal for teleport exits.

If you link more than one actor to the the vehicle teleporter then one will be picked at random at the time of teleportation.This is so you can add a vehicle teleporter to existing maps very quickly as most maps have pathnodes/vehiclePathnodes already set out in roughly the right places.

  • Remember you don't HAVE to use multiple spawn locations If you use 1 teleporter and 1 spawn location its no more difficult to visualize than using a standard teleporter system.

Skeleton script[edit]

This is the basic script need to teleport vehicles

class ONSVehicleTeleporter extends Triggers
placeable;
 
var Array<Actor> TeleportExitList;
 
Simulated function postbeginplay()
{
scanTeleportExitList();
}
 
Simulated function Touch(Actor Other)
{
if (Other.IsA('ONSVehicle'))
    VehicleTeleport(ONSVehicle(Other));
super.Touch(Other);
}
 
Simulated function scanTeleportExitList()
{
 local Actor FoundTeleportExit;
 if (TeleportExitList.Length > 0 )
     TeleportExitList.Remove( 0 , TeleportExitList.Length );
 
 foreach AllActors( Class'Actor' , FoundTeleportExit,'TeleportExit' )
                  {
                   TeleportExitList.Insert( 0 , 1 );
                   TeleportExitList[0] = FoundTeleportExit;
                  }
}
 
Simulated function VehicleTeleport(ONSVehicle Teleporting)
{
local Rotator  NewRotation;
local Vector   BoostForce;
local EPhysics VehiclePhysicsOnEntry;
Local int      PickedTeleportExit;
 
NewRotation           = Teleporting.Rotation;
VehiclePhysicsOnEntry = Teleporting.Physics;
BoostForce            = Teleporting.Velocity * 500;
PickedTeleportExit    = rand(TeleportExitList.Length-1)+1;
Teleporting.SetPhysics(PHYS_None);
Teleporting.setLocation(TeleportExitList[PickedTeleportExit].Location);
NewRotation.Yaw       = TeleportExitList[PickedTeleportExit].Rotation.Yaw + Teleporting.Rotation.Yaw - Self.Rotation.Yaw;
PostVehicleTeleport(Teleporting,PickedTeleportExit,NewRotation,VehiclePhysicsOnEntry,BoostForce);
}
 
Simulated function PostVehicleTeleport( ONSVehicle Teleporting,int TeleportExitnumb,Rotator NewRotation,EPhysics VehiclePhysicsOnEntry,Vector BoostForce,optional Vector PointOfBoostForce)
{
Teleporting.SetPhysics(VehiclePhysicsOnEntry);
Teleporting.Controller.moveTimer = -1.0;
Teleporting.SetmoveTarget(Self);
Teleporting.Controller.SetRotation(NewRotation);
Teleporting.SetRotation(NewRotation);
 
if ( Teleporting.IsA('ONSChopperCraft') ||
     Teleporting.IsA('ONSHoverCraft')    ||
     Teleporting.IsA('ONSPlaneCraft'))
     Teleporting.KSetStayUpright( True,True);
 
Teleporting.KAddImpulse(BoostForce >> Rotation, PointOfBoostForce >> Rotation);
}

A single function[edit]

Here the whole thing is squashed down into a single function. The teleporting itself is very smooth (blink and you'll miss it) and the system is calibrated to give you the same exit speed as you entered with.

  • Any actor can be used as a 'teleport exit' as long as it has its collision turned off
  • If VecTel is called without having a valid ONS Vehicle ref passed to it then the function will scan the level for

TeleportExits with a name tag that matches the name specified by the mapper and record them in a dynamic array.

  • If VecTel() is called and a valid vehicle reference is passed to it then the function will teleport the vehicle to

the teleportexit.

  • If more than 1 actor has the same tagname that the vehicle teleporter is looking for then an exit will be picked at random from those actors at the time of teleporting.

Note[edit]

  • Bots are likley to bail out of the vec after teleporting.
class ONSVehicleTeleporter extends Trigger
 
placeable;
 
var name          TeleportingToName;
 
var array <Actor> TeleportExitList;
 
Simulated function Vectel(Vehicle VehicleToTeleport)
 
{
 
local Actor    FoundTeleportExitActor;
 
local EPhysics VehiclePhysicsOnEntry;
 
local Rotator  NewRotation;
 
local Vector   BoostForce;
 
local Vector   PointOfBoostForce;
 
Local int      ChosenTeleportExitPoint;
 
if (VehicleToTeleport == none)
    {
    // this clears out the array if it has anything in it
    if ( TeleportExitList.Length > 0 )
         TeleportExitList.Remove(0,TeleportExitList.Length);
 
    // this scans for any dynamic actor  with the tag name TeleportExitPoint;
 
    foreach AllActors(Class'actor',FoundTeleportExitActor,TeleportingToName)
            {
             TeleportExitList.insert(0,1);
             TeleportExitList[0]=FoundTeleportExitActor;
            }
    }
 
// grabs some properties from the vehicle and stores them
 
NewRotation             = VehicleToTeleport.Rotation;
 
VehiclePhysicsOnEntry   = VehicleToTeleport.Physics;
 
BoostForce              = VehicleToTeleport.Velocity * 500;
 
//Picks a random number based on the length of the array holding the teleport exit points
 
ChosenTeleportExitPoint = rand(TeleportExitList.Length-1)+1;
 
// Switches off the physics for the vehicle while it is teleported
 
VehicleToTeleport.SetPhysics(PHYS_None);
 
VehicleToTeleport.setLocation(TeleportExitList[ChosenTeleportExitPoint].Location);
 
// The vehicles original physics is now returned to the way it was on entry
 
VehicleToTeleport.SetPhysics(VehiclePhysicsOnEntry);
 
VehicleToTeleport.Controller.moveTimer = -1.0;
 
VehicleToTeleport.SetmoveTarget(Self);
 
// Now the vehicle has been teleported it has to rotated to the direction it was facing
 
// when it entered the vehicle teleporter.
 
NewRotation.Yaw     = TeleportExitList[ChosenTeleportExitPoint].Rotation.Yaw + VehicleToTeleport.Rotation.Yaw - Self.Rotation.Yaw;
 
VehicleToTeleport.Controller.SetRotation(NewRotation);
 
VehicleToTeleport.SetRotation(NewRotation);
 
// if its a flying vehicle that just got teleported then we have to make sure it stays upright
 
if ( VehicleToTeleport.IsA('ONSChopperCraft') || VehicleToTeleport.IsA('ONSHoverCraft')   ||  VehicleToTeleport.IsA('ONSPlaneCraft'))
     VehicleToTeleport.KSetStayUpright( True,True);
 
// To make sure the vehicle pops out the other side at the same speed it went into the
 
// teleporter we have to give it a bit of a nudge
 
VehicleToTeleport.KAddImpulse(BoostForce >> Rotation, PointOfBoostForce >> Rotation);
 
}

Latest Version[edit]

New in this version:

   * Options to destroy vehicles blocking teleport exits
   * Options to Boost Vehicles blocking teleport exits out the way.
   * vehicles blocking the teleporter exit can be boosted in the direction the teleporter exit is facing (recomended) or in the direction they are facing , controled by property bUseExitRotationWhenClearing.
   * The teleport exit points can be rescaned for thier locations so you could have a moving object as a teleporter exit if you wanted.
   * Theres a global value bEnabled with can be use to switch the teleporter exit on/off which can be toggled by triggering the vehicle teleport.
//=============================================================================
 
// VehicleTeleporter By vitaloverdose, Updated sept 2007
 
// http://www.Vitaloverdose.com
 
// This is part of the 'Vitals Pro Mapping Tools' Mod
 
// Download
 
//=============================================================================
 
class ONSVehicleTeleporter  extends Triggers
 
placeable;
 
var() bool             bEnabled;            // Teleporter is turned on;
 
var(TeleportExit) class<DamageType> BlockingVehicle_DamageType;
 
var(TeleportExit) float             ReScan_TeleportExitLocations;
 
var(TeleportExit) bool              bUseExitRotationWhenClearing;
 
var(TeleportExit) bool              bDestroyVehiclesBlockingExits;
 
var(TeleportExit) bool              bBoostVehiclesBlockingExits;
 
var(TeleportExit) vector            ClearTeleportExitBoostForce;
 
var(TeleportExit) name              TeleportExitTag;              //The tag name for the teleport exits
 
var (BotLock)     float             BotCaptureTime;
 
var (BotLock)     float             ScanRate;
 
var float                ReScan_Counter;       // keeps track of time till next rescan
 
//Creating a custom variable type to store some details about each vehicle we are tracking
 
struct VRefArray
 
{
 
var OnsVehicle             ONSVehicleRef;
 
var float                  CaptureTime;
 
};
 
// the dynamic array of the custom VRefArray variable type.
 
// This will be a list of all Vehicles being tracked by the teleporter
 
var array <VRefArray>      VehicleRefArray< SEMI >
 
var array <Actor>          TeleportExitList;
 
// Generic function -Overwriting
 
function Postbeginplay()
 
{
 
ScanForTeleportExitList();
 
if (ReScan_TeleportExitLocations > 0 )
    ReScan_Counter = ReScan_TeleportExitLocations;
 
super.Postbeginplay();
 
}
 
// Generic function -Overwriting
 
function Touch( Actor Other )
 
{
 
super.Touch(Other);                   // adds all the contained code from the parent function to this point.
 
if ((bEnabled==true) && ( Other.isa('ONSVehicle')))         // first checks if its been touched by an onsvehicle
     TeleportVehicle(ONSVehicle(Other));
 
}
 
// Generic function -Overwriting
 
function Trigger( actor Other, pawn EventInstigator )
 
{
 
if (bEnabled)
    bEnabled = false;
 else
    bEnabled = true;
 
super.Trigger(other,EventInstigator);
 
}
 
// New custom function
 
// This function scans all the actor in the level to find a tag name that matches the one
 
// set by the mapper in unrealed.
 
Simulated function ScanForTeleportExitList()
 
{
 local Actor FoundTeleportExit;
 
 // the array is emptied
 if (TeleportExitList.Length > 0 )
     TeleportExitList.Remove( 0 , TeleportExitList.Length );
 
 foreach AllActors( Class'Actor' , FoundTeleportExit,TeleportExitTag )
                  {
                   TeleportExitList.Insert( 0 , 1 );    // makes a space in the array
                   TeleportExitList[0] = FoundTeleportExit; // inserts the valid actor ref of any actor found
                  }
 
//log("------------------TeleportExitList.Length"$TeleportExitList.Length);
 
}
 
// New custom function
 
// this checks the array with the vehcile refs to find a match with a valid vehicle
 
// ref that gets passed to it. The function will return -1 if there is no match or
 
// the position in the array of any matching valid onsvehicle reference
 
function int Already_Tracking( ONSVehicle A_Vehicle )
 
{
 
local int I;
 
for ( i = 0 ; i < VehicleRefArray.length ; I++ )
      if ( VehicleRefArray[i].ONSVehicleRef == A_Vehicle )
           return i;
 
return -1;          // if no match is found a flag of -1 is returned
 
}
 
// Generic function - Overwriting
 
// the timer has to functions here
 
// checks if a rescan is needed
 
// checks each bot being tracked to see if they have been locked in fot the time specified
 
// by the mapper in unrealed.
 
function Timer()
 
{
 local int        I;
 local float      VehicleTime;
 local ONSVehicle VehicleRef;
 local bool       bVehicleDead;
 
 //take care of the rescan
 if (ReScan_TeleportExitLocations > 0 )
     if ( ReScan_Counter < 0 )
          ScanForTeleportExitList();
      else
          ReScan_Counter -= ScanRate;
 
 // checks the bots capture times
 if  (VehicleRefArray.length > 0)
    {
    for (i = 0 ; i < VehicleRefArray.length ; I++ )
         {
         VehicleRef                 = VehicleRefArray[i].ONSVehicleRef;      // retrieves the Vehicle ref
         bVehicleDead               = VehicleRef.bVehicleDestroyed;  // Assigns status of the Vehicle to bDead
         VehicleTime                    = VehicleRefArray[i].CaptureTime;    // asigns the capture time rom the array to a variable
         VehicleTime                    = VehicleTime - ScanRate;            // takes off the scan rate time
         VehicleRefArray[i].CaptureTime = VehicleTime;                       // assigns value back to the array
 
         if (VehicleRef == None || bVehicleDead )      // removes any invalid records (records with no VehicleRef)
            {
             VehicleRefArray.remove(i , 1);                // removes the record from the array
             i -= 1;                                   // adjusts the counter to move back 1 place
            }
      else
         if ( VehicleTime < 0 )
            {                                                            // release velocity
             VehicleRefArray[i].ONSVehicleRef.bDriverCannotLeaveVehicle = false; // unlocks the Vehicle
             VehicleRefArray.remove(i , 1);                                  // removes the record from the array
             i -= 1;                                                     // adjusts the counter to move back 1 place
            }
         }
      }
 
// the timer isnt set to repeate:- This is to help optimization by only having it
 
// running if there is anything being tracked
 
if ( VehicleRefArray.length > 0 )
    SetTimer( ScanRate , false );           // will only call the timer() once ,if its tracking
 
else
  if ( ReScan_TeleportExitLocations > 0 )          // if theres no bots to track set the timer to the
       SetTimer( ReScan_TeleportExitLocations - ReScan_Counter , false );  // next rescan rime ..if any
 
super.Timer();
 
}
 
// New custom function
 
// this takes care of the teleporting of the vehicle.
 
// the vehicles physics are switched of until it reaches the teleport Destination
 
// the vehicle has to be kicked to get it moving at the same speed as it entered
 
// the vehicle teleporter , this is done using KaddImpulse()
 
// the direction of the vehicle is the same on exit as when it entered the teleporter
 
// Bots are captured by locking the vehicle to stop them from jumping out after teleporting
 
Simulated function TeleportVehicle(ONSVehicle Teleporting)
 
{
 
local Vector   TeleportExit_Location;   // the vector location of the picked teleport exit
 
local Rotator  NewRotation;             // the rotion to set the vehicle after teleporting
 
local Vector   BoostForce;              // the power and direction of the kick on exit
 
local EPhysics VehiclePhysicsOnEntry;   // the vehicle cant be teleported with its physics on
 
local actor    TeleportExit;            // so the physics are backed up prior to the teleport
 
if  (!Teleporting.IsPlayerPawn() && Already_Tracking(Teleporting) == -1)
    {
    VehicleRefArray.insert(0,1);                                    // Inserts a new blank slot into the array.
    Teleporting.bDriverCannotLeaveVehicle    = true;            // locks the vehicle
    VehicleRefArray[0].ONSVehicleRef                 = Teleporting;     // assigns the valid onsvehicle ref to the array
    VehicleRefArray[0].CaptureTime               = BotCaptureTime;  // assigns the botcapturetime
 
    // this switchs on the timer function to keep track of the boosted vehicles when there
    // are any vehicle to track
    if ( VehicleRefArray.length > 0 )
         SetTimer( ScanRate , false );
    }
 
// backs up the current vehcile rotation and physics
 
NewRotation           = Teleporting.Rotation;
 
VehiclePhysicsOnEntry = Teleporting.Physics;
 
// calculates the amount of 'kick' to give the vehicle so its travleing the same speed on
 
// exit as it was when it touched the vehicle teleporter.
 
BoostForce            = Teleporting.Velocity * 500;
 
// the vector location of the teleport exit is used to teleport the vehicle to
 
TeleportExit = PickAVehicleTeleportExit() ;
 
// switches of the vehicle physics ready to teleport
 
Teleporting.SetPhysics(PHYS_None);
 
// gets the vector location of the teleport exit actor
 
TeleportExit_Location = TeleportExit.Location;
 
// uses the vector location of the picked teleport point to set the new position of the vehicle
 
Teleporting.setLocation(TeleportExit_Location);
 
//calculates new rotation for the vehicle in relation to the vehicle exit
 
NewRotation.Yaw = TeleportExit.Rotation.Yaw + TeleportExit.Rotation.Yaw - Self.Rotation.Yaw;
 
// sets the vehicles physics back the way it was before the teleport
 
Teleporting.SetPhysics(VehiclePhysicsOnEntry);
 
Teleporting.Controller.moveTimer = -1.0;
 
Teleporting.SetmoveTarget(Self);
 
// The new rotation is applied to the vehicle
 
Teleporting.Controller.SetRotation(NewRotation);
 
Teleporting.SetRotation(NewRotation);
 
// this makes sure all none ground based vehicle are the right way up on exit
 
if ( Teleporting.IsA('ONSChopperCraft') ||
     Teleporting.IsA('ONSHoverCraft')   ||
     Teleporting.IsA('ONSPlaneCraft'))
     Teleporting.KSetStayUpright( True,True);
 
// the vehicle wont exit moving unless its given a kick
 
VehicleBoost(Teleporting,BoostForce,NewRotation);
 
}
 
// New custom function
 
// used to get the vehicles moving again when they pop out of the vehicle exit
 
// used to clear the vehicleteleporter exits.
 
function VehicleBoost(ONSVehicle AVehicle,optional vector BForce,optional rotator NewRotation)
 
{
 
local rotator BoostRotation;
 
local vector  PointOfBoostForce;
 
if (NewRotation == BoostRotation)
    BoostRotation = AVehicle.rotation;
 
else
    BoostRotation = NewRotation;
 
AVehicle.KAddImpulse( BForce >> BoostRotation , PointOfBoostForce >> BoostRotation );
 
}
 
// New custom function
 
// a short function for picking an actor/random actor from the list of available
 
// teleporter exit list
 
function actor PickAVehicleTeleportExit()
 
{
 
local int PickedTeleport_ExitNunb;
 
if (TeleportExitList.Length>1)
    rand(TeleportExitList.Length);
  else
    PickedTeleport_ExitNunb = 1;
 
if (PickedTeleport_ExitNunb != 0 )
    PickedTeleport_ExitNunb&ndash;;
 
return TeleportExitList[PickedTeleport_ExitNunb];
 
}
 
// New custom function
 
function ClearTeleportExitOfVehicles(Actor TeleportExit)
 
{
 local array<ONSVehicle>  FoundVehicles;
 local int                inc;
 local rotator            BoostRotation;
 
 if (TeleportExit == none)
    {
    log ("ClearTeleportExitOfVehicles(Actor TeleportExit) : passed no exit");
    return;
    }
 
FoundVehicles = ScanTeleportExitForBlockage(TeleportExit);
 
if (FoundVehicles.length < 1 )
    return;
 
 for (inc=0;inc < FoundVehicles.length;inc++)
      {
       if (bUseExitRotationWhenClearing)
           {
            BoostRotation = TeleportExit.rotation;
            VehicleBoost(FoundVehicles[inc],ClearTeleportExitBoostForce,BoostRotation);
           }
       else
           if (bDestroyVehiclesBlockingExits)
               FoundVehicles[inc].TakeDamage(10000, None, FoundVehicles[inc].Location, vect(0,0,0), BlockingVehicle_DamageType);
      }
 
}
 
// New custom function
 
function array<ONSVehicle> ScanTeleportExitForBlockage(actor TeleportExit)
 
{
 local ONSVehicle         FoundVehicle;
 local array<ONSVehicle>  FoundVehicles;
 local array<VRefArray>   TrackingVehiclesCopy;
 local int                inc;
 TrackingVehiclesCopy = VehicleRefArray< SEMI >
 foreach TouchingActors(class'ONSVehicle',FoundVehicle)
         {
          for (inc = 0 ;inc < TrackingVehiclesCopy.length;inc ++)
              {
               if (TrackingVehiclesCopy[inc].CaptureTime < (BotCaptureTime-1.00))
                  {
                   FoundVehicles.insert(0,1);
                   FoundVehicles[0] = FoundVehicle;
                  }
               else
                   TrackingVehiclesCopy.remove(inc,1);
              }
         }
 
return FoundVehicles;
 
}
 
defaultproperties
 
{
     bEnabled=True
     BlockingVehicle_DamageType=Class'Engine.Crushed'
     ReScan_TeleportExitLocations=-1.000000
     bUseExitRotationWhenClearing=True
     bBoostVehiclesBlockingExits=True
     ClearTeleportExitBoostForce=(X=2000000.000000,Z=500000.000000)
     TeleportExitTag="TeleportExit"
     ScanRate=0.500000
     RemoteRole=ROLE_SimulatedProxy
     Texture=Texture'XEffectMat.Shock.Shock_ring_a'
     CollisionRadius=150.000000
     CollisionHeight=150.000000
 
}

Related Topics[edit]

Discussion[edit]