Fixed a bug thanks to Ikonn Giano
that prevented the text from being said on local chat.
The following script turns a primitive into a display for giving talks. The display allow you to scroll back and forward between the textures in the inventory as well as zoom into a part of the picture and drag it around to show a part of the current displayed texture. It also allows you to add an optional notecard containing lines which will be said on the local channel whenever a slide is displayed.
a
and a textures named b
, then a
will precede b
. Similarly, a_1
will be read before a_2
. The case is important as well, "A" gets read before "a".You are set.
By clicking the primitive you will get a menu with Next ⇒
, ⇐ Prev
and [ Point ]
. The Next ⇒
option will switch over to the next slide. The ⇐ Back
option will go back to the previous slide.
To use the [ Point ]
option, select it from the menu first. After that, left click and hold on any portion of the current slide that you would like to zoom in to. The texture will zoom on that point. If you left click, hold down and drag the mouse as well, the texture will zoom and move around following your cursor. Once you are done, release the left mouse button and the menu will pop-up again, or click the primitive again for the menu.
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// integer comChannel = 0; integer comHandle = 0; list slide = []; list text = []; string text_card = ""; key cQuery = NULL_KEY; integer dir = 0; integer init() { integer itra; for (itra = 0, slide = []; itra < llGetInventoryNumber(INVENTORY_TEXTURE); ++itra) { slide += llGetInventoryName(INVENTORY_TEXTURE, itra); } if (!llGetListLength(slide)) { llOwnerSay("The primitive contains no texture, please add a texture."); return 0; } llOwnerSay("Loaded textures in sequence: " + llDumpList2String(slide, ", ") + "."); if (llGetInventoryNumber(INVENTORY_NOTECARD)) { text_card = llGetInventoryName(INVENTORY_NOTECARD, 0); llOwnerSay("Text card found, reading..."); text = []; cQuery = llGetNotecardLine(text_card, (comChannel = 0)); return 0; } return 1; } list next() { string p; string w; @a_1; p = llList2String(slide, 0); slide = llDeleteSubList(slide, 0, 0); slide += p; w = llList2String(text, 0); text = llDeleteSubList(text, 0, 0); text += w; if (dir < 0) { dir = 1; jump a_1; } dir = 1; return [w, p]; } list prev() { string p; string w; @a_2; p = llList2String(slide, llGetListLength(slide) - 1); slide = llDeleteSubList(slide, llGetListLength(slide) - 1, llGetListLength(slide) - 1); slide = llListInsertList(slide, (list)p, 0); w = llList2String(text, llGetListLength(text) - 1); text = llDeleteSubList(text, llGetListLength(text) - 1, llGetListLength(text) - 1); text = llListInsertList(text, (list)w, 0); if (dir > 0) { dir = -1; jump a_2; } dir = -1; return [w, p]; } default { state_entry() { if (init()) state display; } on_rez(integer num) { if (init()) state display; } changed(integer change) { if (change & CHANGED_INVENTORY) if (init()) state display; } dataserver(key query_id, string data) { if (query_id != cQuery) return; if (data == EOF) { text = llDeleteSubList(text, llGetListLength(text) - 1, llGetListLength(text) - 1); llOwnerSay("Read: " + (string)(comChannel - 1) + " text lines."); state display; return; } text += (list)data; cQuery = llGetNotecardLine(text_card, ++comChannel); } } state display { state_entry() { if (cQuery == "p") { comChannel = ((integer)("0x" + llGetSubString((string)llGetKey(), -8, -1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; llListenRemove(comHandle); comHandle = llListen(comChannel, "", llGetOwner(), ""); llDialog(llGetOwner(), "Please select an option: ", ["Next =>", "[ END ]", "<= Prev", " ", "[ Point ]", " "], comChannel); return; } llOwnerSay("Ready for operation, click \"Next =>\" for the next slide."); } touch_start(integer num) { if (llDetectedKey(0) != llGetOwner()) return; comChannel = ((integer)("0x" + llGetSubString((string)llGetKey(), -8, -1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; llListenRemove(comHandle); comHandle = llListen(comChannel, "", llGetOwner(), ""); llDialog(llGetOwner(), "Please select an option: ", ["Next =>", "[ END ]", "<= Prev", " ", "[ Point ]", " "], comChannel); } listen(integer channel, string name, key id, string message) { if (message == "Next =>") { list res = next(); llSetTexture(llList2String(res, 1), 0); if (llGetListLength(text)) llSay(0, llList2String(res, 0)); } if (message == "<= Prev") { list res = prev(); llSetTexture(llList2String(res, 1), 0); if (llGetListLength(text)) llSay(0, llList2String(res, 0)); } if (message == "[ END ]") { llListenRemove(comHandle); return; } if (message == "[ Point ]") { state point; return; } llDialog(llGetOwner(), "Please select an option: ", ["Next =>", "[ END ]", "<= Prev", " ", "[ Point ]", " "], comChannel); llSetTimerEvent(3600); } changed(integer change) { if (change & CHANGED_INVENTORY) llResetScript(); } timer() { llListenRemove(comHandle); llSetTimerEvent(0); } } state point { touch(integer num) { vector tc = llDetectedTouchST(0); llOffsetTexture(tc.x - .5, tc.y - .5, 0); llScaleTexture(.2, .2, 0); } touch_end(integer num) { llScaleTexture(1, 1, 0); llOffsetTexture(0, 0, 0); cQuery = "p"; state display; } }