// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Pocket maze // Not compiled or tested in-world // Setup: Put in a prim and owner-touch to start a fresh maze. The dialog shows X for your location, # walls, and E for the exit. // Stop / restore: Stop responding and its listener closes after 60 seconds, or remove the script. // Notes: A private owner game using a fixed solvable map. Directions use the printed map, not world compass directions. No avatar is moved. // License: see LICENSE in this distribution. // Original Incoprea example. MIT. Not compiled or tested in-world. list rows = ["#######", "#S#..E#", "#.#.###", "#.....#", "#######"]; integer x = 1; integer y = 1; integer channel; integer handle; close() { if (handle) llListenRemove(handle); handle = 0; llSetTimerEvent(0.0); } show() { string map = ""; integer line; for (line = 0; line < llGetListLength(rows); ++line) { string row = llList2String(rows, line); if (line == y) row = llInsertString(llDeleteSubString(row, x, x), x, "X"); map += row + "\n"; } llDialog(llGetOwner(), map + "\nFind E. # is a wall.", ["North", "South", "East", "West"], channel); llSetTimerEvent(60.0); } default { touch_start(integer count) { if (llDetectedKey(0) != llGetOwner()) return; close(); x = 1; y = 1; channel = -1000 - (integer)llFrand(1000000.0); handle = llListen(channel, "", llGetOwner(), ""); show(); } listen(integer received, string name, key id, string message) { if (received != channel || id != llGetOwner()) return; integer nx = x; integer ny = y; if (message == "North") --ny; else if (message == "South") ++ny; else if (message == "East") ++nx; else if (message == "West") --nx; else return; if (nx < 0 || nx >= 7 || ny < 0 || ny >= 5) { show(); return; } string cell = llGetSubString(llList2String(rows, ny), nx, nx); if (cell != "#") { x = nx; y = ny; } if (cell == "E") { close(); llOwnerSay("Exit found! Touch for another walk."); } else show(); } timer() { close(); } changed(integer change) { if (change & CHANGED_OWNER) llResetScript(); } }