///============================================================================= // Teleports actors either between different teleporters within a level // or to matching teleporters on other levels, or to general Internet URLs. //============================================================================= class Teleporter extends SmallNavigationPoint placeable native; #exec Texture Import File=Textures\Teleport.pcx Name=S_Teleport Mips=Off MASKED=1 //----------------------------------------------------------------------------- // Teleporter URL can be one of the following forms: // // TeleporterName // Teleports to a named teleporter in this level. // if none, acts only as a teleporter destination // // LevelName/TeleporterName // Teleports to a different level on this server. // // Unreal://Server.domain.com/LevelName/TeleporterName // Teleports to a different server on the net. // var() string URL; //----------------------------------------------------------------------------- // Product the user must have installed in order to enter the teleporter. var() name ProductRequired; //----------------------------------------------------------------------------- // Teleporter destination flags. var() bool bChangesVelocity; // Set velocity to TargetVelocity. var() bool bChangesYaw; // Sets yaw to teleporter's Rotation.Yaw var() bool bReversesX; // Reverses X-component of velocity. var() bool bReversesY; // Reverses Y-component of velocity. var() bool bReversesZ; // Reverses Z-component of velocity. // Teleporter flags var() bool bEnabled; // Teleporter is turned on; //----------------------------------------------------------------------------- // Teleporter destination directions. var() vector TargetVelocity; // If bChangesVelocity, set target's velocity to this. // AI related var Actor TriggerActor; //used to tell AI how to trigger me var Actor TriggerActor2; var float LastFired; //----------------------------------------------------------------------------- // Teleporter destination functions. replication { reliable if( Role==ROLE_Authority ) bEnabled, URL; reliable if ( bNetInitial && (Role == ROLE_Authority) ) bChangesVelocity, bChangesYaw, bReversesX, bReversesY, bReversesZ, TargetVelocity; } function PostBeginPlay() { local int i; if (URL ~= "") SetCollision(false, false, false); //destination only if ( !bEnabled ) FindTriggerActor(); // retrofit hack for keeping bots in vehicles from trying to use teleporters // by making reachspecs between teleporters forced so the SpecialCost() event will be called for them for ( i=0; i 0.5) ) { newRot.Roll = 0; Pawn(Incoming).SetRotation(newRot); Pawn(Incoming).SetViewRotation(newRot); Pawn(Incoming).ClientSetRotation(newRot); LastFired = Level.TimeSeconds; } if ( Pawn(Incoming).Controller != None ) { Pawn(Incoming).Controller.MoveTimer = -1.0; Pawn(Incoming).Anchor = self; Pawn(Incoming).SetMoveTarget(self); } Incoming.PlayTeleportEffect(false, true); } 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; oldDir = vector(OldRot); mag = Incoming.Velocity Dot oldDir; Incoming.Velocity = Incoming.Velocity - mag * oldDir + mag * vector(Incoming.Rotation); } if ( bReversesX ) Incoming.Velocity.X *= -1.0; if ( bReversesY ) Incoming.Velocity.Y *= -1.0; if ( bReversesZ ) Incoming.Velocity.Z *= -1.0; } return true; } //----------------------------------------------------------------------------- // Teleporter functions. function Trigger( actor Other, pawn EventInstigator ) { local Actor A; bEnabled = !bEnabled; if ( bEnabled ) //teleport any pawns already in my radius ForEach TouchingActors(class'Actor', A) PostTouch(A); } event Touch(Actor Other) { if ( !bEnabled || (Other == None) ) return; if( Other.bCanTeleport && Other.PreTeleport(Self)==false ) { PendingTouch = Other.PendingTouch; Other.PendingTouch = self; } } // Teleporter was touched by an actor. simulated function PostTouch( actor Other ) { local Teleporter D,Dest[16]; local int i; if( (InStr( URL, "/" ) >= 0) || (InStr( URL, "#" ) >= 0) ) { // Teleport to a level on the net. if( (Role == ROLE_Authority) && (Pawn(Other) != None) && Pawn(Other).IsHumanControlled() ) Level.Game.SendPlayer(PlayerController(Pawn(Other).Controller), URL); } else { // Teleport to a random teleporter in this local level, if more than one pick random. foreach AllActors( class 'Teleporter', D ) if( string(D.tag)~=URL && D!=Self ) { Dest[i] = D; i++; if ( i > arraycount(Dest) ) break; } i = rand(i); if( Dest[i] != None ) { // Teleport the actor into the other teleporter. if ( Other.IsA('Pawn') ) Other.PlayTeleportEffect(false, true); Dest[i].Accept( Other, self ); if ( Pawn(Other) != None ) TriggerEvent(Event, self, Pawn(Other)); } } } /* SpecialHandling is called by the navigation code when the next path has been found. It gives that path an opportunity to modify the result based on any special considerations */ function Actor SpecialHandling(Pawn Other) { local vector Dist2D; if ( bEnabled && (Teleporter(Other.Controller.RouteCache[1]) != None) && (string(Other.Controller.RouteCache[1].tag)~=URL) ) { if ( Abs(Location.Z - Other.Location.Z) < CollisionHeight + Other.CollisionHeight ) { Dist2D = Location - Other.Location; Dist2D.Z = 0; if ( VSize(Dist2D) < CollisionRadius + Other.CollisionRadius ) PostTouch(Other); } return self; } if (TriggerActor == None) { FindTriggerActor(); if (TriggerActor == None) return None; } if ( (TriggerActor2 != None) && (VSize(TriggerActor2.Location - Other.Location) < VSize(TriggerActor.Location - Other.Location)) ) return TriggerActor2; return TriggerActor; } event int SpecialCost(Pawn Other, ReachSpec Path) { // is this a teleport path? if ( (Teleporter(Path.Start) == None) || ((Path.reachFlags & 32) == 0) ) return 0; // vehicles can't teleport if ( Vehicle(Other) != None ) return 10000000; return 0; } defaultproperties { RemoteRole=ROLE_SimulatedProxy bChangesYaw=true bEnabled=True bDirectional=True SoundVolume=128 bCollideActors=True Texture=S_Teleport bSpecialForced=true }