////////////////////////////////////////////////////////// // (c) Wizardry and Steamworks - 2012, License GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html // // for legal details, rights of fair usage and // // the disclaimer and warranty conditions. // ////////////////////////////////////////////////////////// vector sPos = ZERO_VECTOR; vector fPos = ZERO_VECTOR; // Calculate next jump gate vector nextJump(vector iPos, vector dPos, integer jumpDistance) { // We move 1/jumpDistance from the initial position // towards the final destination in the description. float dist = llVecDist(iPos, dPos); if(dist > jumpDistance) return iPos + jumpDistance * (dPos-iPos) / dist; return nextJump(iPos, dPos, --jumpDistance); } integer gItra = 0; key ncKey = NULL_KEY; list dNames = []; list dCoord = []; key avSit = NULL_KEY; default { state_entry() { llSetClickAction(CLICK_ACTION_NONE); // Grab local position. sPos = llGetPos(); llSitTarget(ZERO_VECTOR,ZERO_ROTATION); // Read notecard. if(llGetInventoryType("Destinations") == INVENTORY_NOTECARD) jump found_notecard; llOwnerSay("Failed to find notecard."); return; @found_notecard; gItra = 0; ncKey = llGetNotecardLine("Destinations", gItra); } changed(integer change) { if(change & CHANGED_INVENTORY) { llResetScript(); } } dataserver(key id, string data) { if(id != ncKey) return; if(data == EOF) { llSay(0, "Teleporter ready."); state sit; return; } if(data == "") jump next_line; list dc = llParseString2List(data, ["#"], []); dNames += llList2String(dc, 0); dCoord += llList2String(dc, 1); @next_line; ncKey = llGetNotecardLine("Destinations", ++gItra); } } state sit { touch_start(integer total_numer) { avSit = llDetectedKey(0); integer comChannel = ((integer)("0x"+llGetSubString((string)avSit,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; llListen(comChannel, "", avSit, ""); llDialog(avSit, "Please chose a destination:\n", dNames, comChannel); llSetTimerEvent(30); } listen(integer channel, string name, key id, string message) { llInstantMessage(avSit, "Please sit on the teleporter for transport."); llSetClickAction(CLICK_ACTION_SIT); llSitTarget(<0,0,1>,ZERO_ROTATION); dCoord = (list)llList2String(dCoord, llListFindList(dNames, (list)message)); } changed(integer change) { if(change & CHANGED_LINK) { key av = llAvatarOnSitTarget(); if(av) if(av == avSit) { state move; } llUnSit(av); } } timer() { llInstantMessage(avSit, "Teleporter timeout. Please touch the teleporter again for destinations."); llResetScript(); } } state move { state_entry() { // Grab local position again. sPos = llGetPos(); // Grab distance from description fPos = ZERO_VECTOR; list oDesc = llParseString2List(llGetObjectDesc(), ["<", ">", ","], []); fPos.x = llList2Float(oDesc, 0); fPos.y = llList2Float(oDesc, 1); fPos.z = llList2Float(oDesc, 2); // 1.175494351E-38 is the smallest float. llSetTimerEvent(1.175494351E-38); } timer() { if(llVecDist(llGetPos(), fPos) < 1) { llSetTimerEvent(0); key a = llAvatarOnSitTarget(); if(a) llUnSit(llAvatarOnSitTarget()); state recall; } llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, nextJump(llGetPos(), fPos, 10)]); } } state recall { state_entry() { // 1.175494351E-38 is the smallest float. llSetTimerEvent(1.175494351E-38); } timer() { if(llVecDist(llGetPos(), sPos) < 1) { llSetTimerEvent(0); state default; } llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, nextJump(llGetPos(), sPos, 10)]); } }