Difference between revisions of "Teleport HUD"

From Second Life Wiki
Jump to: navigation, search
(Correct syntax error. Avoid misrepresentative (float)TRUE / (float)FALSE)
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
{{LSL Header}}
 
{{LSL Header}}
 +
== Gridwide Teleport HUD (works in no-script areas) ==
  
<lsl>
+
# Link 9 prims.
//Teleport HUD
+
# Drop this script.
//Jesse Barnett
+
# Add up to 8 landmarks.
//1/16/08
+
# Attach to HUD and enjoy!
  
//One of my first "real" scripts from waaaaaay back when.
+
<source lang="lsl2">
//Hopefully users will do more then just use this script. Strided lists and
+
key owner;
//manipulating lists are the closest we get to arrays in LSL presently.
+
integer gotTPperms;
//Even with all of the list juggling here, you will be surprised just how many
+
integer isShowing;
//destinations you can add.
+
  
//A lot of code but this is the only teleporter I have been using for over a year now.
+
toggle(integer inputInteger)
//No notecards or lists to fill out. Very user freindly.
+
{
//Wherever you are, just touch the button, hit ""Add" and it will prompt you for the name
+
    if (inputInteger)
//Type what you want to name it in open chat, hit enter and you are done
+
    {
//It will store the sim name, the name you gave it for the menu buttons and the location
+
        integer numOfPrims = llGetNumberOfPrims();
//automatically
+
        rotation currentRot = llGetRot();
//It will only show the destinations for the simulator you are in.
+
//Pick the destination from the menu, touch the bubble that is rezzed in front of
+
//you and you will instantly teleport to that spot.
+
//You can also easily remove destinations by picking ""Remove" in the menu and then
+
//touching the button name you wish to remove.
+
//In case you are worried about loosing your destinations, you can also use the
+
//"List" button to output the list of all destinations from all sims.
+
//I have never lost the destinations because of sim resets etc.
+
//Have lost them twice tweaking the script. But adding destinations again is so easy
+
//it is no problem.
+
  
//To use, create a button and attach it to the desired position on your HUD.
+
        vector white = <1.0, 1.0, 1.0>;
//Place this script inside, Put the warp pos script into another object you want
+
        vector orange = <1.0, 0.4, 0.0>;
//to rez as the bubble, edit it so that when you left click, you will sit.
+
//Take the "bubble" back into inventory and then place it in the HUD also.
+
  
 +
        integer index = 1;//  root of linkset
 +
        do
 +
        {
 +
            string linkName = llGetLinkName(index);
  
string sim;
+
            if (linkName == "TP HUD for landmarks")
list sims;
+
            {
list dest;
+
                llSetLinkPrimitiveParamsFast(index,
list main_menu;
+
                    [PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 1,
list menu_options =["Add", "Remove", "Back", "List"];
+
                    PRIM_COLOR, 3, <0.0, 1.0, 0.0>, 1,
integer rez_chan;
+
                    //  green and opaque floattext
integer rez_chan_handle;
+
                    PRIM_TEXT, "click green button to close\n"
integer menu_chan;
+
                        + "or select TP destination", <0.0, 1.0, 0.0>, 1]);
integer menu_chan_handle;
+
            }
integer edit_chan = 0;// Could change this to another channel if you want for privacy
+
            else if (linkName == "tp1")
//It is only used to enter the destination name when you use "Add"
+
            {
integer edit_chan_handle;
+
                llSetLinkPrimitiveParamsFast(index, [
integer edit_test = FALSE;
+
                    PRIM_COLOR, ALL_SIDES, white, 1,
vector target;
+
                    PRIM_POSITION, <0.0, 0.0, -0.0475>*currentRot,
string tp_object = "bubble";
+
                    PRIM_SIZE, <0.025, 0.025, 0.010>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 0), white, 1]);
 +
            }
 +
            else if (linkName == "tp2")
 +
            {
 +
                llSetLinkPrimitiveParamsFast(index, [
 +
                    PRIM_COLOR, ALL_SIDES, orange, 1,
 +
                    PRIM_POSITION, <0.0, 0.0, -0.0875>*currentRot,
 +
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 1), orange, 1]);
 +
            }
 +
            else if (linkName == "tp3")
 +
            {
 +
                llSetLinkPrimitiveParamsFast(index, [
 +
                    PRIM_COLOR, ALL_SIDES, white, 1,
 +
                    PRIM_POSITION, <0.0, 0.0, -0.1275>*currentRot,
 +
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 2), white, 1]);
 +
            }
 +
            else if (linkName == "tp4")
 +
            {
 +
                llSetLinkPrimitiveParamsFast(index, [
 +
                    PRIM_COLOR, ALL_SIDES, orange, 1,
 +
                    PRIM_POSITION, <0.0, 0.0, -0.1675>*currentRot,
 +
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 3), orange, 1]);
 +
            }
 +
            else if (linkName == "tp5")
 +
            {
 +
                llSetLinkPrimitiveParamsFast(index, [
 +
                    PRIM_COLOR, ALL_SIDES, white, 1,
 +
                    PRIM_POSITION, <0.0, 0.0, -0.2075>*currentRot,
 +
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 4), white, 1]);
 +
            }
 +
            else if (linkName == "tp6")
 +
            {
 +
                llSetLinkPrimitiveParamsFast(index, [
 +
                    PRIM_COLOR, ALL_SIDES, orange, 1,
 +
                    PRIM_POSITION, <0.0, 0.0, -0.2475>*currentRot,
 +
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 5), orange, 1]);
 +
            }
 +
            else if (linkName == "tp7")
 +
            {
 +
                llSetLinkPrimitiveParamsFast(index, [
 +
                    PRIM_COLOR, ALL_SIDES, white, 1,
 +
                    PRIM_POSITION, <0.0, 0.0, -0.2875>*currentRot,
 +
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 6), white, 1]);
 +
            }
 +
            else if (linkName == "tp8")
 +
            {
 +
                llSetLinkPrimitiveParamsFast(index, [
 +
                    PRIM_COLOR, ALL_SIDES, orange, 1,
 +
                    PRIM_POSITION, <0.0, 0.0, -0.3275>*currentRot,
 +
                    PRIM_SIZE,<0.025, 0.025, 0.01>,
 +
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 7), orange, 1]);
 +
            }
 +
        }
 +
        while (++index <= numOfPrims);
 +
    }
 +
    else
 +
    {
 +
        rotation currentRot = llGetRot();
 +
        integer numOfPrims = llGetNumberOfPrims();
  
default {
+
        integer index = 1;// root of linkset
touch_start(integer num_detected) {
+
        do
menu_chan = (integer) llFrand(-100000 - 99999999) - 100000;
+
        {
if (sim != llGetRegionName() || edit_test) {
+
            string linkName = llGetLinkName(index);
//Don't recalculate if no change to region or an edit
+
sim = llGetRegionName();
+
edit_test = FALSE;
+
main_menu =[];
+
dest = llListSort(dest, 3, TRUE);//Sorts the list in Strides according to sim
+
sims = llListSort(sims, 1, TRUE);
+
integer dest_list_sim_loc = llListFindList(dest,[sim]);
+
//1st entry in list with the current sim
+
integer sim_list_sim_loc = llListFindList(sims,[sim]);
+
string next_sim_name = llList2String(sims, (sim_list_sim_loc + 1));
+
integer next_sim_loc = (integer) llListFindList(dest,[next_sim_name]) - 1;
+
//Calculates the last entry in the current sim
+
main_menu = llList2ListStrided(llDeleteSubList(dest, 0, 0), dest_list_sim_loc, next_sim_loc, 3);
+
//Now menu list is built only showing destinations that are in the current sim
+
main_menu = llListSort(main_menu, 1, TRUE);
+
main_menu = (main_menu =[]) + ["Options"] + main_menu;
+
}
+
menu_chan_handle = llListen(menu_chan, "", llGetOwner(), "");
+
llSetTimerEvent(20);
+
llDialog(llDetectedKey(0), "Choose destination or Options to add/remove destinations", main_menu, menu_chan);
+
}
+
listen(integer channel, string lm, key id, string message) {
+
if (llListFindList(main_menu + menu_options,[message]) != -1) {
+
if (message == "Options") {
+
llDialog(id, "Pick an option!", menu_options, menu_chan);
+
}
+
else if (message == "Back") {
+
llDialog(id, "Where do you want to go?", main_menu, menu_chan);
+
}
+
else if (message == "Add") {
+
integer b = TRUE;
+
integer m = TRUE;
+
b = ((llGetListLength(main_menu)) <= 11);
+
//Only allows 11 entries per simulator
+
m = (llGetFreeMemory() >= 1000);
+
//Make usre we have enough memory to manipulate the lists
+
if (!b || !m) {
+
llOwnerSay("You can not add any more destinations");
+
}
+
else {
+
llOwnerSay("What do you want to name this destination?");
+
llListenRemove(menu_chan_handle);
+
state add_dest;
+
}
+
}
+
else if (message == "Remove") {
+
llDialog(id, "Which desination do you want to remove?", main_menu, menu_chan);
+
state rem_dest;
+
}
+
else if (message == "List") {
+
integer i;
+
if (llGetListLength(dest) > 0) {
+
for (i = 0; i < llGetListLength(dest); i += 3) {
+
string sim_name = llList2String(dest, i);
+
string name = llList2String(dest, i + 1);
+
string location = llList2String(dest, i + 2);
+
llOwnerSay(sim_name + " , " + name + " = " + location);
+
}
+
}
+
else {
+
llOwnerSay("No Destinations Available.");
+
}
+
}
+
else if (llListFindList(dest,[message]) != -1) {
+
integer index = llListFindList(dest,[message]);
+
if (index != -1) {
+
vector pos = llGetPos();
+
if (pos.z <= 4095) {
+
target = (vector) llList2String(dest, index + 1);
+
rez_chan = (integer) llFrand(100000 - 1000000) - 100000;
+
llSay(0, "Touch the pumpkin to teleport");
+
llRezObject(tp_object, llGetPos() + (<1, 0, 1> * llGetRot()), ZERO_VECTOR,
+
ZERO_ROTATION, rez_chan);
+
}
+
else {
+
llOwnerSay("Too high to teleport. You must be lower then 4096 meters");
+
}
+
}
+
}
+
}
+
}
+
object_rez(key id)
+
{
+
llWhisper(rez_chan, (string) target);
+
}
+
timer() {
+
llSetTimerEvent(0);
+
llListenRemove(menu_chan_handle);
+
llListenRemove(rez_chan_handle);
+
return;
+
}
+
}
+
  
state add_dest {
+
            if (linkName == "TP HUD for landmarks")
state_entry() {
+
            {
edit_test = TRUE;
+
                llSetLinkPrimitiveParamsFast(index,
llSetTimerEvent(20);
+
                    [PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 1,
edit_chan_handle = llListen(edit_chan, "", llGetOwner(), "");
+
                    PRIM_COLOR, 3, <1.0, 0.0, 0.0>, 1,
}
+
                    //  red and opaque floattext
listen(integer chan, string name, key id, string msg) {
+
                    PRIM_TEXT, "<~!~ TP HUD ~!~>", <1.0, 0.0, 0.0>, 1]);
integer e = llListFindList(sims,[sim]);
+
            }
if (e == -1) {
+
            else if (linkName == "tp1" || linkName == "tp2"
sims = (sims =[]) + sims +[sim];
+
                || linkName == "tp3" || linkName == "tp4"
}
+
                || linkName == "tp5" || linkName == "tp6"
vector pos = llGetPos();
+
                || linkName == "tp7" || linkName == "tp8")
dest = (dest =[]) + dest +[sim, msg, pos];
+
            {
llOwnerSay("Added : " + sim + " , " + msg + " = " + (string) pos);
+
                llSetLinkPrimitiveParamsFast(index, [
llListenRemove(edit_chan_handle);
+
                    PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 0,
state default;
+
                    PRIM_POSITION, ZERO_VECTOR*currentRot,
}
+
                    PRIM_SIZE, <0.01, 0.01, 0.01>,
timer() {
+
                    //  black and transparent floattext
llSetTimerEvent(0);
+
                    PRIM_TEXT, "", ZERO_VECTOR, 0]);
llListenRemove(edit_chan_handle);
+
            }
llOwnerSay("Timeout. Click TP HUD to start again");
+
        }
state default;
+
        while (++index <= numOfPrims);
}
+
    }
 
}
 
}
  
state rem_dest {
+
default
state_entry() {
+
{
edit_test = TRUE;
+
    changed(integer change)
llSetTimerEvent(20);
+
    {
menu_chan_handle = llListen(menu_chan, "", llGetOwner(), "");
+
        if (change & (CHANGED_OWNER | CHANGED_INVENTORY))
}
+
            llResetScript();
listen(integer chan, string name, key id, string msg) {
+
    }
integer d = llListFindList(dest,[msg]);
+
if (d != -1) {
+
dest = llDeleteSubList(dest, d - 1, d + 1);
+
llOwnerSay("Removed : " + msg);
+
integer f = llListFindList(dest,[sim]);
+
if (f == -1) {
+
sims = llDeleteSubList(sims, f, f);
+
llListenRemove(menu_chan_handle);
+
state default;
+
}
+
llListenRemove(menu_chan_handle);
+
state default;
+
}
+
}
+
timer() {
+
llSetTimerEvent(0);
+
llListenRemove(menu_chan_handle);
+
llOwnerSay("Timeout. Click TP HUD to start again");
+
state default;
+
}
+
}
+
</lsl>
+
<lsl>
+
vector target;    // The location the av will be teleported to.
+
integer listenId;    // Listener ID
+
key gAvatarID;
+
integer start_param;
+
  
warpPos(vector target)
+
    attach(key attached)
{   //R&D by Keknehv Psaltery, 05/25/2006
+
    {
//with a little pokeing by Strife, and a bit more
+
        if (attached != NULL_KEY)
//some more munging by Talarus Luan
+
            llResetScript();
//Final cleanup by Keknehv Psaltery
+
    }
// Compute the number of jumps necessary
+
 
integer jumps = (integer) (llVecDist(target, llGetPos()) / 10.0) + 1;
+
    state_entry()
// Try and avoid stack/heap collisions
+
    {
if (jumps > 100)
+
        llSetLinkPrimitiveParamsFast(LINK_ROOT,
jumps = 100;   //  1km should be plenty
+
            [PRIM_NAME, "TP HUD for landmarks",
list rules =[PRIM_POSITION, target];   //The start for the rules list
+
            PRIM_LINK_TARGET, 2,
integer count = 1;
+
            PRIM_NAME, "tp1",
while ((count = count << 1) < jumps)
+
            PRIM_LINK_TARGET, 3,
rules = (rules =[]) + rules + rules;   //should tighten memory use.
+
            PRIM_NAME, "tp2",
llSetPrimitiveParams(rules + llList2List(rules, (count - jumps) << 1, count));
+
            PRIM_LINK_TARGET, 4,
}
+
            PRIM_NAME, "tp3",
 +
            PRIM_LINK_TARGET, 5,
 +
            PRIM_NAME, "tp4",
 +
            PRIM_LINK_TARGET, 6,
 +
            PRIM_NAME, "tp5",
 +
            PRIM_LINK_TARGET, 7,
 +
            PRIM_NAME, "tp6",
 +
            PRIM_LINK_TARGET, 8,
 +
            PRIM_NAME, "tp7",
 +
            PRIM_LINK_TARGET, 9,
 +
            PRIM_NAME, "tp8" ]);
 +
 
 +
        owner = llGetOwner();
 +
        gotTPperms = FALSE;
 +
 
 +
        isShowing = FALSE;
 +
        toggle(isShowing);
 +
 
 +
        // request teleport perms and controls perms for no-script area hack
 +
        llRequestPermissions(owner, (PERMISSION_TELEPORT | PERMISSION_TAKE_CONTROLS));
 +
    }
 +
 
 +
    touch_start(integer num_detected)
 +
    {
 +
        key id = llDetectedKey(0);
 +
        string linkName = llGetLinkName(llDetectedLinkNumber(0));
 +
        string tpDestination;
 +
 
 +
        if (id != owner)
 +
            return;
  
default {
+
        if (gotTPperms && linkName == "TP HUD for landmarks")
state_entry() {
+
        {
llSetObjectName("bubble");
+
            isShowing = !isShowing;
}
+
            toggle(isShowing);
 +
        }
 +
        else if (linkName == "tp1")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 0);
 +
        else if (linkName == "tp2")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 1);
 +
        else if (linkName == "tp3")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 2);
 +
        else if (linkName == "tp4")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 3);
 +
        else if (linkName == "tp5")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 4);
 +
        else if (linkName == "tp6")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 5);
 +
        else if (linkName == "tp7")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 6);
 +
        else if (linkName == "tp8")
 +
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 7);
  
listen(integer channel, string name, key id, string message) {
+
        if (tpDestination == "")
target = (vector) message;
+
            llOwnerSay("Invalid destination!");
llListenRemove(listenId);
+
        else
llSetText("Touch to teleport", <1, 1, 1 >, 1);
+
            llTeleportAgent(owner, tpDestination, ZERO_VECTOR, ZERO_VECTOR);
llSitTarget(<0, 0, 0.5 >, ZERO_ROTATION);
+
    }
}
+
  
on_rez(integer start_param) {
+
    // no-script area hack
// When this object rezzes setup a listener to get the target
+
    control(key id,integer held, integer change)
listenId = llListen(start_param, "", "", "");
+
    {
}
+
        return;
 +
    }
  
changed(integer change) {
+
    run_time_permissions(integer perm)
if (change & CHANGED_LINK) {
+
    {
gAvatarID = llAvatarOnSitTarget();
+
        if (perm & PERMISSION_TAKE_CONTROLS)
if (gAvatarID != NULL_KEY) {
+
            llTakeControls(CONTROL_UP,TRUE,TRUE);
warpPos(target);
+
        if (perm & PERMISSION_TELEPORT)
llDie();
+
            gotTPperms = TRUE;
}
+
    }
}
+
}
+
 
}
 
}
</lsl>
+
</source>
 
{{LSLC|Library|Teleport HUD}}
 
{{LSLC|Library|Teleport HUD}}

Latest revision as of 07:51, 21 January 2016

Gridwide Teleport HUD (works in no-script areas)

  1. Link 9 prims.
  2. Drop this script.
  3. Add up to 8 landmarks.
  4. Attach to HUD and enjoy!
key owner;
integer gotTPperms;
integer isShowing;
 
toggle(integer inputInteger)
{
    if (inputInteger)
    {
        integer numOfPrims = llGetNumberOfPrims();
        rotation currentRot = llGetRot();
 
        vector white = <1.0, 1.0, 1.0>;
        vector orange = <1.0, 0.4, 0.0>;
 
        integer index = 1;//  root of linkset
        do
        {
            string linkName = llGetLinkName(index);
 
            if (linkName == "TP HUD for landmarks")
            {
                llSetLinkPrimitiveParamsFast(index,
                    [PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 1,
                    PRIM_COLOR, 3, <0.0, 1.0, 0.0>, 1,
                    //  green and opaque floattext
                    PRIM_TEXT, "click green button to close\n"
                        + "or select TP destination", <0.0, 1.0, 0.0>, 1]);
            }
            else if (linkName == "tp1")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, white, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.0475>*currentRot,
                    PRIM_SIZE, <0.025, 0.025, 0.010>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 0), white, 1]);
            }
            else if (linkName == "tp2")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, orange, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.0875>*currentRot,
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 1), orange, 1]);
            }
            else if (linkName == "tp3")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, white, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.1275>*currentRot,
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 2), white, 1]);
            }
            else if (linkName == "tp4")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, orange, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.1675>*currentRot,
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 3), orange, 1]);
            }
            else if (linkName == "tp5")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, white, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.2075>*currentRot,
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 4), white, 1]);
            }
            else if (linkName == "tp6")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, orange, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.2475>*currentRot,
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 5), orange, 1]);
            }
            else if (linkName == "tp7")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, white, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.2875>*currentRot,
                    PRIM_SIZE, <0.025, 0.025, 0.01>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 6), white, 1]);
            }
            else if (linkName == "tp8")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, orange, 1,
                    PRIM_POSITION, <0.0, 0.0, -0.3275>*currentRot,
                    PRIM_SIZE,<0.025, 0.025, 0.01>,
                    PRIM_TEXT, llGetInventoryName(INVENTORY_LANDMARK, 7), orange, 1]);
            }
        }
        while (++index <= numOfPrims);
    }
    else
    {
        rotation currentRot = llGetRot();
        integer numOfPrims = llGetNumberOfPrims();
 
        integer index = 1;//  root of linkset
        do
        {
            string linkName = llGetLinkName(index);
 
            if (linkName == "TP HUD for landmarks")
            {
                llSetLinkPrimitiveParamsFast(index,
                    [PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 1,
                    PRIM_COLOR, 3, <1.0, 0.0, 0.0>, 1,
                    //  red and opaque floattext
                    PRIM_TEXT, "<~!~ TP HUD ~!~>", <1.0, 0.0, 0.0>, 1]);
            }
            else if (linkName == "tp1" || linkName == "tp2"
                || linkName == "tp3" || linkName == "tp4"
                || linkName == "tp5" || linkName == "tp6"
                || linkName == "tp7" || linkName == "tp8")
            {
                llSetLinkPrimitiveParamsFast(index, [
                    PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 0,
                    PRIM_POSITION, ZERO_VECTOR*currentRot,
                    PRIM_SIZE, <0.01, 0.01, 0.01>,
                    //  black and transparent floattext
                    PRIM_TEXT, "", ZERO_VECTOR, 0]);
            }
        }
        while (++index <= numOfPrims);
    }
}
 
default
{
    changed(integer change)
    {
        if (change & (CHANGED_OWNER | CHANGED_INVENTORY))
            llResetScript();
    }
 
    attach(key attached)
    {
        if (attached != NULL_KEY)
            llResetScript();
    }
 
    state_entry()
    {
        llSetLinkPrimitiveParamsFast(LINK_ROOT,
            [PRIM_NAME, "TP HUD for landmarks",
            PRIM_LINK_TARGET, 2,
            PRIM_NAME, "tp1",
            PRIM_LINK_TARGET, 3,
            PRIM_NAME, "tp2",
            PRIM_LINK_TARGET, 4,
            PRIM_NAME, "tp3",
            PRIM_LINK_TARGET, 5,
            PRIM_NAME, "tp4",
            PRIM_LINK_TARGET, 6,
            PRIM_NAME, "tp5",
            PRIM_LINK_TARGET, 7,
            PRIM_NAME, "tp6",
            PRIM_LINK_TARGET, 8,
            PRIM_NAME, "tp7",
            PRIM_LINK_TARGET, 9,
            PRIM_NAME, "tp8" ]);
 
        owner = llGetOwner();
        gotTPperms = FALSE;
 
        isShowing = FALSE;
        toggle(isShowing);
 
        //  request teleport perms and controls perms for no-script area hack
        llRequestPermissions(owner, (PERMISSION_TELEPORT | PERMISSION_TAKE_CONTROLS));
    }
 
    touch_start(integer num_detected)
    {
        key id = llDetectedKey(0);
        string linkName = llGetLinkName(llDetectedLinkNumber(0));
        string tpDestination;
 
        if (id != owner)
            return;
 
        if (gotTPperms && linkName == "TP HUD for landmarks")
        {
            isShowing = !isShowing;
            toggle(isShowing);
        }
        else if (linkName == "tp1")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 0);
        else if (linkName == "tp2")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 1);
        else if (linkName == "tp3")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 2);
        else if (linkName == "tp4")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 3);
        else if (linkName == "tp5")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 4);
        else if (linkName == "tp6")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 5);
        else if (linkName == "tp7")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 6);
        else if (linkName == "tp8")
            tpDestination = llGetInventoryName(INVENTORY_LANDMARK, 7);
 
        if (tpDestination == "")
            llOwnerSay("Invalid destination!");
        else
            llTeleportAgent(owner, tpDestination, ZERO_VECTOR, ZERO_VECTOR);
    }
 
    //  no-script area hack
    control(key id,integer held, integer change)
    {
        return;
    }
 
    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TAKE_CONTROLS)
            llTakeControls(CONTROL_UP,TRUE,TRUE);
        if (perm & PERMISSION_TELEPORT)
            gotTPperms = TRUE;
    }
}