~Fiona's Script Library~

← Zurück zur Bibliothek

book-flipper-update.lsl | 3.73 KB
Herunterladen
// Copyright 2025 by Fiona Sweet
// Free to use for any purpose
// Two-Prim Flip Book (controller in Book_Right)
// Closed: Left hidden, Right shows FrontCover.
// Open:   Left=InsideFrontCover, Right=Page_01, then flip spreads.
// Click Right => NEXT / open; Click Left => PREV; 
// Prev from first or Next from last => close to FrontCover.

string TEX_COVER  = "FrontCover";
list   ORDER = [
    "InsideFrontCover","Page_01",
    "Page_02","Page_03",
    "Page_04","Page_05",
    "Page_06","Page_07",
    "Page_08","Page_09",
    "Page_10","Page_11",
    "Page_12","Page_13",
    "Page_14","InsideBackCover"
]; // left,right pairs (spreads)

string NAME_LEFT  = "Book_Left";
string NAME_RIGHT = "Notes From Saturn";

integer LINK_LEFT  = -1;
integer LINK_RIGHT = -1;

integer gOpen   = FALSE;
integer gSpread = 0;
integer gLastSpread = -1;

integer findLink(string pname){
    integer n = llGetNumberOfPrims();
    for (integer i = 1; i <= n; ++i) if (llGetLinkName(i) == pname) return i;
    return -1;
}
integer texExists(string name){ return (llGetInventoryType(name) == INVENTORY_TEXTURE); }

showCover(){
    // Left transparent (hidden), Right shows front cover
    llSetLinkPrimitiveParamsFast(LINK_LEFT,  [PRIM_COLOR,   ALL_SIDES, <1,1,1>, 0.0]);
    llSetLinkPrimitiveParamsFast(LINK_RIGHT, [PRIM_TEXTURE, ALL_SIDES, TEX_COVER, <1,1,0>, <0,0,0>, 0.0,
                                              PRIM_COLOR,   ALL_SIDES, <1,1,1>, 1.0]);
    gOpen = FALSE;
    gSpread = 0;
}

applySpread(integer spread){
    integer idx = spread * 2;
    string leftTex  = llList2String(ORDER, idx);
    string rightTex = llList2String(ORDER, idx + 1);

    llSetLinkPrimitiveParamsFast(LINK_LEFT,  [PRIM_TEXTURE, ALL_SIDES, leftTex,  <1,1,0>, <0,0,0>, 0.0,
                                              PRIM_COLOR,   ALL_SIDES, <1,1,1>, 1.0]);
    llSetLinkPrimitiveParamsFast(LINK_RIGHT, [PRIM_TEXTURE, ALL_SIDES, rightTex, <1,1,0>, <0,0,0>, 0.0,
                                              PRIM_COLOR,   ALL_SIDES, <1,1,1>, 1.0]);
}

openTo(integer spread){
    gOpen = TRUE;
    gSpread = spread;
    applySpread(gSpread);
}

default
{
    state_entry()
    {
        LINK_LEFT  = findLink(NAME_LEFT);
        LINK_RIGHT = findLink(NAME_RIGHT);

        if (LINK_LEFT < 0 || LINK_RIGHT < 0){
            llOwnerSay("Name your prims exactly: 'Book_Left' and 'Book_Right' (make Book_Right the ROOT).");
            return;
        }

        // sanity check textures (warn only)
        integer missing = FALSE;
        if (!texExists(TEX_COVER)) { llOwnerSay("Missing: " + TEX_COVER); missing = TRUE; }
        integer L = llGetListLength(ORDER);
        for (integer i = 0; i < L; ++i){
            string t = llList2String(ORDER,i);
            if (!texExists(t)) { llOwnerSay("Missing: " + t); missing = TRUE; }
        }
        if (missing) llOwnerSay("Some textures missing. the book will still try to run.");

        gLastSpread = (llGetListLength(ORDER) / 2) - 1; // 16 items -> 8 spreads -> last=7
        showCover();

        llOwnerSay("Ready: click RIGHT page to open/advance; click LEFT page to go back.");
    }

    // Clicks on Book_Right (this prim) open/advance
    touch_start(integer n)
    {
        if (!gOpen) { openTo(0); return; }          // open on first click
        if (gSpread < gLastSpread) { gSpread++; applySpread(gSpread); }
        else { showCover(); }                        // last spread -> close
    }

    // Left prim sends PREV here
    link_message(integer sender, integer num, string msg, key id)
    {
        if (msg == "PREV"){
            if (!gOpen) return;                      // ignore when closed
            if (gSpread > 0) { gSpread--; applySpread(gSpread); }
            else { showCover(); }                    // first spread -> close
        }
    }
}