// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Read a short notecard safely // Not compiled or tested in-world // Setup: Add a saved plain-text notecard named Notes to this prim. Touch as owner to read it. // Stop / restore: Remove or disable the script. Editing Contents cancels the current read; touch to begin again. // Notes: Outputs only to owner chat. Lines may be truncated by the simulator; use short plain-text lines and no embedded inventory. It stops at forty lines to avoid runaway output. // License: see LICENSE in this distribution. // Original Incoprea example. MIT. string CARD = "Notes"; integer lineNumber; integer MAX_LINES = 40; key pending = NULL_KEY; finish(string message) { pending = NULL_KEY; llSetTimerEvent(0.0); llOwnerSay(message); } requestLine() { pending = llGetNotecardLine(CARD, lineNumber); llSetTimerEvent(20.0); } default { touch_start(integer count) { if (llDetectedKey(0) != llGetOwner()) return; if (pending != NULL_KEY) { llOwnerSay("A read is already in progress."); return; } if (llGetInventoryType(CARD) != INVENTORY_NOTECARD) { llOwnerSay("Add a saved notecard named " + CARD); return; } lineNumber = 0; requestLine(); } dataserver(key query, string data) { if (query != pending || pending == NULL_KEY) return; if (data == EOF) { finish("End of notecard."); return; } llOwnerSay((string)(lineNumber + 1) + ": " + data); ++lineNumber; if (lineNumber >= MAX_LINES) { finish("Stopped at the 40-line limit."); return; } requestLine(); } timer() { finish("Read timed out. Check the card and touch to retry."); } changed(integer flags) { if (flags & (CHANGED_INVENTORY | CHANGED_OWNER)) llResetScript(); } }