Trying to make it so that only requiring minimal change within all current warpPos() scripts. You may just replace the entire warpPos() function and leave all of your other codes remain.

The function could go anywhere in the sim (excluding underground, object entry banned etc.). Even if they increased the building height to 10,000m in the future, there is no need to amend.
There is a full working open source TP maker sample attached. To see how it works, follow these steps:
1) Make a prim (or use any object if you like)
2) Drop the script in its content
3) Open and edit the script:
> destination - where to
> text - optional floating text
> text_color - the text's color
> touch2sit - set left click for touch to sit and TP at once
4) Save the script and done~
5) To use, sit (or left click if touch2sit is set) on the object and TP. Once it arrives, it will unsit the user and the object itself goes back to where it came from.
Enjoy~
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
For those of you who interested in how it works:
There is a safety range in this warpPos(). This range is used to check if the distance is within then to use a normal warpPos - to create a list then move. Default is 1000m.
If the distance is out of this range, a bi-section method is used. For example, if you are TP from <25,25,100> to <25,25,3900>, the distance will be 3800 which is out of range. And if using the normal warpPos() and taking out the 1km limit if-condition, it would occur the stack-heap error (out of script memory coz of the list is too long).
In the bi-section method, it take the 3800 into half -> 1900 into account to see if it's in range. When it is not, then take another half 950 which is within range. Now move using the normal warpPos(). The new distance left now is 2850 (3800 - 950), and taking another half to check 1425 etc. Until the last distance gets small enough within range and no more checking is needed.
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/ The script begins _/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
vector destination = <128,128,3800>; // the destination coordinate
string text = "Touch To Teleport"; // optional floating text on the teleporter, input a space if not used
vector text_color = <1.0,1.0,1.0>; // the floating text's color
integer touch2sit = TRUE; // TRUE - left click to sit; FALSE - left click to touch
//=================================================
warpPos( vector destpos )
{ //R&D by Keknehv Psaltery, 05/25/2006; unlimited modified by Klug Kuhn 10/01/2008
// Change this safety range depends on your script memory
// The larger the range, the quicker (and less "flashes"
to get to the destination, however, the more to eat up script memory.float safety_range = 1000.0;
integer arrived = FALSE;
integer within_range = FALSE;
vector inter_pos = ZERO_VECTOR;
vector current_pos = llGetPos();
vector checking_pos = destpos;
integer jumps = 0;
list rules = [];
integer count = 0;
if (llVecDist(destpos, current_pos) <= safety_range)
{
jumps = (integer)(llVecDist(destpos, current_pos) / 10.0) + 1;
rules = [ PRIM_POSITION, destpos ]; //The start for the rules list
count = 1;
while ( ( count = count << 1 ) < jumps)
rules = (rules=[]) + rules + rules; //should tighten memory use.
llSetPrimitiveParams( rules + llList2List( rules, (count - jumps) << 1, count) );
}
else
{
while (!arrived)
{
current_pos = llGetPos();
checking_pos = destpos;
within_range = FALSE;
while (!within_range)
{
if (llVecDist(checking_pos,current_pos) > safety_range)
{
checking_pos = <
current_pos.x + checking_pos.x) / 2.0,(current_pos.y + checking_pos.y) / 2.0,(current_pos.z + checking_pos.z) / 2.0>;}
else
{
within_range = TRUE;
if (llVecDist(destpos, current_pos) <= safety_range)
{
jumps = (integer)(llVecDist(destpos, current_pos) / 10.0) + 1;
rules = [ PRIM_POSITION, destpos ]; //The start for the rules list
count = 1;
while ( ( count = count << 1 ) < jumps)
rules = (rules=[]) + rules + rules; //should tighten memory use.
llSetPrimitiveParams( rules + llList2List( rules, (count - jumps) << 1, count) );
arrived = TRUE;
}
}
}
if (!arrived)
{
jumps = (integer)(llVecDist(checking_pos, current_pos) / 10.0) + 1;
rules = [ PRIM_POSITION, checking_pos ]; //The start for the rules list
count = 1;
while ( ( count = count << 1 ) < jumps)
rules = (rules=[]) + rules + rules; //should tighten memory use.
llSetPrimitiveParams( rules + llList2List( rules, (count - jumps) << 1, count) );
}
}
}
}
//=================================================
default
{
state_entry()
{
llSitTarget(<0.0, 0.0, 0.01>, ZERO_ROTATION);
llSetText(text,text_color,1.0);
if (touch2sit)
llSetClickAction(CLICK_ACTION_SIT);
else
llSetClickAction(CLICK_ACTION_NONE);
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
key user = llAvatarOnSitTarget();
if (llGetAgentSize(user) != ZERO_VECTOR)
{
vector init_pos = llGetPos();
warpPos(destination);
llUnSit(user);
llSleep(0.2);
warpPos(init_pos);
}
}
}
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/ The script ends _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/


