////////////////////////////////////////////////////////// // (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. // ////////////////////////////////////////////////////////// // Calculate jump gates list jumpGates(vector iPos, vector dPos, integer jumpDistance) { list gates = []; if(jumpDistance == 0) return gates; float dist = llVecDist(iPos, dPos); if(dist > jumpDistance) { // We move 1/jumpDistance from the initial position // towards the final destination in the description. iPos = iPos + jumpDistance * (dPos-iPos) / dist; gates += iPos; return gates + jumpGates(iPos, dPos, jumpDistance); } return gates + jumpGates(iPos, dPos, --jumpDistance); } list dNames = []; list dCoord = []; list jumps = []; vector sPos = ZERO_VECTOR; key avSit = NULL_KEY; key ncKey = NULL_KEY; integer gItra = 0; 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 vector oPos = ZERO_VECTOR; list oDesc = llParseString2List(llList2String(dCoord, 0), ["<", ">", ","], []); oPos.x = llList2Float(oDesc, 0); oPos.y = llList2Float(oDesc, 1); oPos.z = llList2Float(oDesc, 2); // Calculate list of intermediary jump gates. jumps = jumpGates(llGetPos(), oPos, 10); // 1.175494351E-38 is the smallest float. llSetTimerEvent(1.175494351E-38); } timer() { if(llGetListLength(jumps) == 0) { llSetTimerEvent(0); key a = llAvatarOnSitTarget(); if(a) llUnSit(llAvatarOnSitTarget()); state recall; } vector nPos = llList2Vector(jumps, 0); jumps = llDeleteSubList(jumps, 0, 0); llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, nPos]); } } state recall { state_entry() { jumps = jumpGates(llGetPos(), sPos, 10); // 1.175494351E-38 is the smallest float. llSetTimerEvent(1.175494351E-38); } timer() { if(llGetListLength(jumps) == 0) { llSetTimerEvent(0); llResetScript(); } vector nPos = llList2Vector(jumps, 0); jumps = llDeleteSubList(jumps, 0, 0); llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, nPos]); } }