264 lines
6.8 KiB
Ucode
264 lines
6.8 KiB
Ucode
///=============================================================================
|
|
// Teleports actors either between different teleporters within a level
|
|
// or to matching teleporters on other levels, or to general Internet URLs.
|
|
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
|
|
//=============================================================================
|
|
class Teleporter extends NavigationPoint
|
|
placeable
|
|
native;
|
|
|
|
cpptext
|
|
{
|
|
#if WITH_EDITOR
|
|
void addReachSpecs(AScout *Scout, UBOOL bOnlyChanged=0);
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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;
|
|
/** whether this Teleporter works on vehicles */
|
|
var() bool bCanTeleportVehicles;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Teleporter destination directions.
|
|
var() vector TargetVelocity; // If bChangesVelocity, set target's velocity to this.
|
|
|
|
var float LastFired;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Teleporter destination functions.
|
|
|
|
replication
|
|
{
|
|
if( Role==ROLE_Authority )
|
|
bEnabled, URL;
|
|
if ( bNetInitial && (Role == ROLE_Authority) )
|
|
bChangesVelocity, bChangesYaw, bReversesX, bReversesY, bReversesZ, TargetVelocity;
|
|
}
|
|
|
|
/** returns whether this NavigationPoint is a teleporter that can teleport the given Actor */
|
|
native function bool CanTeleport(Actor A);
|
|
|
|
event PostBeginPlay()
|
|
{
|
|
if (URL ~= "")
|
|
SetCollision(false, false); //destination only
|
|
|
|
Super.PostBeginPlay();
|
|
}
|
|
|
|
// Accept an actor that has teleported in.
|
|
simulated event bool Accept( actor Incoming, Actor Source )
|
|
{
|
|
local rotator NewRot, oldRot;
|
|
local float mag;
|
|
local vector oldDir;
|
|
local Controller C;
|
|
|
|
if ( Incoming == None )
|
|
return false;
|
|
|
|
// Move the actor here.
|
|
Disable('Touch');
|
|
NewRot = Incoming.Rotation;
|
|
if (bChangesYaw)
|
|
{
|
|
oldRot = Incoming.Rotation;
|
|
NewRot.Yaw = Rotation.Yaw;
|
|
if ( Source != None )
|
|
{
|
|
NewRot.Yaw += (32768 + Incoming.Rotation.Yaw - Source.Rotation.Yaw);
|
|
}
|
|
}
|
|
|
|
if ( Pawn(Incoming) != None )
|
|
{
|
|
//tell enemies about teleport
|
|
if ( Role == ROLE_Authority )
|
|
{
|
|
foreach WorldInfo.AllControllers(class'Controller', C)
|
|
{
|
|
if ( C.Enemy == Incoming )
|
|
{
|
|
C.EnemyJustTeleported();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !Pawn(Incoming).SetLocation(Location) )
|
|
{
|
|
`log(self$" Teleport failed for "$Incoming);
|
|
return false;
|
|
}
|
|
if ( (Role == ROLE_Authority)
|
|
|| (WorldInfo.TimeSeconds - LastFired > 0.5) )
|
|
{
|
|
NewRot.Roll = 0;
|
|
Pawn(Incoming).SetRotation(NewRot);
|
|
Pawn(Incoming).SetViewRotation(NewRot);
|
|
Pawn(Incoming).ClientSetRotation(NewRot);
|
|
LastFired = WorldInfo.TimeSeconds;
|
|
}
|
|
if ( Pawn(Incoming).Controller != None )
|
|
{
|
|
Pawn(Incoming).Controller.MoveTimer = -1.0;
|
|
Pawn(Incoming).SetAnchor(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;
|
|
}
|
|
Incoming.PostTeleport(self);
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Teleporter functions.
|
|
|
|
event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
|
|
{
|
|
if ( !bEnabled || (Other == None) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (CanTeleport(Other) && !Other.PreTeleport(self))
|
|
{
|
|
PendingTouch = Other.PendingTouch;
|
|
Other.PendingTouch = self;
|
|
}
|
|
}
|
|
|
|
// Teleporter was touched by an actor.
|
|
simulated event 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() )
|
|
WorldInfo.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(true, true);
|
|
}
|
|
Dest[i].Accept( Other, self );
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 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
|
|
*/
|
|
event Actor SpecialHandling(Pawn Other)
|
|
{
|
|
if ( bEnabled && (Other.Controller.RouteCache.Length > 1) && (Teleporter(Other.Controller.RouteCache[1]) != None)
|
|
&& (string(Other.Controller.RouteCache[1].tag)~=URL) )
|
|
{
|
|
if(IsOverlapping(Other))
|
|
{
|
|
PostTouch(Other);
|
|
}
|
|
|
|
return self;
|
|
}
|
|
return None;
|
|
}
|
|
|
|
|
|
defaultproperties
|
|
{
|
|
Begin Object NAME=CollisionCylinder
|
|
CollisionRadius=+00040.000000
|
|
CollisionHeight=+00080.000000
|
|
CollideActors=true
|
|
End Object
|
|
|
|
Begin Object NAME=Sprite
|
|
Sprite=Texture2D'EditorResources.S_Teleport'
|
|
End Object
|
|
|
|
RemoteRole=ROLE_SimulatedProxy
|
|
bChangesYaw=true
|
|
bEnabled=true
|
|
bCollideActors=true
|
|
}
|