DelayedTeleporter/UT Code
To use this actor, subclass Teleporter with the following code. This class has been tested offline only. See Create A Subclass and Embedding Code for how to use this script. Set bStatic to False and bNoDelete to True in the DelayedTeleporter's default properties.
class DelayedTeleporter extends Teleporter; /****************************************************************************** * DelayedTeleporter by Wormbo * * * * TeleporterEnterDelay specifies, how long the teleporter is disabled after * * someone entered it. * * bFixedExitRotation specifies, that the player's rotation after exiting this * * teleporter should be set to the teleporter's rotation. * * * * To make the delay work, set bStatic=False and bNoDelete=True in defaults. * ******************************************************************************/ var(Teleporter) float TeleportEnterDelay; var(Teleporter) bool bFixedExitRotation; var float Delay; var Actor LastIncoming; replication { reliable if ( Role == ROLE_Authority ) Delay; } simulated function Tick(float DeltaTime) { local int i; if ( Delay > 0 ) { Delay -= DeltaTime; if ( Delay <= 0 ) //teleport any pawns already in my radius for (i = 0; i < 4; i++) if ( Touching[i] != None ) Touch(Touching[i]); } } simulated function bool Accept(actor Incoming, Actor Source) { local rotator newRot, oldRot; local pawn P; // Move the actor here. Disable('Touch'); //log("Move Actor here "$tag); newRot = Incoming.Rotation; if ( bChangesYaw ) { oldRot = Incoming.Rotation; newRot.Yaw = Rotation.Yaw; if ( !bFixedExitRotation && Source != None ) newRot.Yaw += (32768 + Incoming.Rotation.Yaw - Source.Rotation.Yaw); } if ( Pawn(Incoming) != None ) { //tell enemies about teleport if ( Role == ROLE_Authority ) { P = Level.PawnList; While ( P != None ) { if ( P.Enemy == Incoming ) P.LastSeenPos = Incoming.Location; P = P.nextPawn; } } Pawn(Incoming).SetLocation(Location); if ( Role == ROLE_Authority || Level.TimeSeconds - LastFired > 0.5 ) { Pawn(Incoming).SetRotation(newRot); Pawn(Incoming).ViewRotation = newRot; LastFired = Level.TimeSeconds; } Pawn(Incoming).MoveTimer = -1.0; Pawn(Incoming).MoveTarget = self; PlayTeleportEffect( Incoming, false); } else { if ( !Incoming.SetLocation(Location) ) { Enable('Touch'); return false; } if ( bChangesYaw ) Incoming.SetRotation(newRot); } Enable('Touch'); if ( bChangesVelocity ) Incoming.Velocity = TargetVelocity; else { if ( bChangesYaw ) { if ( Incoming.Physics == PHYS_Walking ) OldRot.Pitch = 0; // adjust the actor's velocity Incoming.Velocity = Incoming.Velocity << OldRot; Incoming.Velocity = Incoming.Velocity >> NewRot; Incoming.Acceleration = Incoming.Acceleration << OldRot; Incoming.Acceleration = Incoming.Acceleration >> NewRot; } if ( bReversesX ) Incoming.Velocity.X *= -1.0; if ( bReversesY ) Incoming.Velocity.Y *= -1.0; if ( bReversesZ ) Incoming.Velocity.Z *= -1.0; } LastIncoming = Incoming; return true; } // Teleporter was touched by an actor. simulated function Touch(actor Other) { local Teleporter Dest; local int i; local Actor A; if ( !bEnabled || Delay > 0 || Other == LastIncoming ) return; if ( Other.bCanTeleport && Other.PreTeleport(Self) == false ) { if ( InStr(URL, "/") >= 0 || InStr(URL, "#") >= 0 ) { // Teleport to a level on the net. if ( Role == ROLE_Authority && PlayerPawn(Other) != None ) Level.Game.SendPlayer(PlayerPawn(Other), URL); } else { // Teleport to a random teleporter in this local level, if more than one pick random. foreach AllActors(class 'Teleporter', Dest) if ( string(Dest.Tag) ~= URL && Dest != Self ) i++; i = rand(i); foreach AllActors(class 'Teleporter', Dest) if ( string(Dest.Tag) ~= URL && Dest != Self && i-- == 0 ) break; if ( Dest != None ) { // Teleport the actor into the other teleporter. if ( Other.IsA('Pawn') ) PlayTeleportEffect(Pawn(Other), false); if ( Dest.Accept(Other, Self) ) Delay = TeleportEnterDelay; if ( Event != '' && Other.IsA('Pawn') ) foreach AllActors(class 'Actor', A, Event) A.Trigger(Other, Other.Instigator); } else if ( Role == ROLE_Authority ) Pawn(Other).ClientMessage("Teleport destination for "$self$" not found!"); } } } simulated function UnTouch(actor Other) { if ( Other == LastIncoming ) LastIncoming = None; Super.UnTouch(Other); }
Fyfe: Accept() can be reduced to:
simulated function bool Accept( Actor Incoming, Actor Source ) { if ( bFixedExitRotation ) Source = None; if ( Super.Accept( Incoming, Source ) ) { LastIncoming = Incoming; return true; } else return false; }