Questo è un “semplice” script uno dei primi che avevo fatto che consente di navigare delle diapositive “Multiple”, leggendole dall’inventory del “proiettore di diapositive”.
Le immagini devono terminare con xxxxx-3×3 per indicare che sono una matrice di 3 righe per 3 colonne. Lo script è molto sofisticato e consente anche di lasciare a vista le ultime diapositive viste. Inoltre consente anche di fare una ricerca e di visualizzare dei commenti sulle diapositive.

Lo script computa i parametri
integer iM=4;
integer iN=4;
float fSCALX=1;
float fSCALY=1;
float fSPANX=.5;
float fSPANY=.5;
e poi fa evolvere con la funzione next() verso l’elemento successivo. Si può semplificare per adempiere al suo scopo su una singola texture
//
// Pakkio Jan 2008, V3.0
// PowerPoint projector
//
// Textures must be made MXN and have it in their name as in <name>-MxN
// example: my texture-4x4 (multiple images can be mixed)
// for each must find <name>-MxN.txt to have one line for each slide with "|" representing newlines
// if we find a <name>-MxN-i.give this will be given to people if required
//
// script will be able to select next texture, prev texture, and will keep last 5 slides, comments, inventory for retrieving them
//
integer iDELAY=10;
integer iLISTENHANDLER=0;
integer iMENUCHANNEL;
integer iCHANNEL=100;
integer iDEBUG=0;
integer iHOVERTEXT=1;
vector vHOVERCOLOR=<1,1,1>;
integer iMENULISTENER=0;
vector vSTARTPOS;
string sTELEPORT="";
vector vTELEPORT;
string sINVENTORY;
string sSEARCH="";
// will be set up during reset looking at the names of each link
integer eCONTROLLER;
integer eBOARD=1;
integer iPLAY=0;
// to loop over all the textures in the inventory
integer iTEXTURE;
string sTEXTURE;
integer bENDTEXTURE;
// to loop over the comments in notecards (
string sCOMMENT;
key kCOMMENT;
integer iCOMMENT;
integer iM=4;
integer iN=4;
float fSCALX=1;
float fSCALY=1;
float fSPANX=.5;
float fSPANY=.5;
string sME="MAIN";
list lHISTORYLINK=[];
list lHISTORY=[ "","","","","" ];
list lTEXT=[ "","","","","" ];
push(string texture, vector scale, vector offset)
{
lHISTORY=llDeleteSubList(lHISTORY,0,0)+llDumpList2String([ texture, scale, offset ],"|");
integer i;
for(i=0;i<5;i++)
{
list data=peek(i);
llSetLinkPrimitiveParams(llList2Integer(data,0),
[ PRIM_TEXTURE, ALL_SIDES,
llList2String(data,1), // texture
(vector)llList2String(data,2), // scale
(vector)llList2String(data,3), // offset
0.0 ]);
}
}
push_text(string text)
{
lTEXT=llDeleteSubList(lTEXT,0,0)+text;
}
// return [linknum, texture, scale, offset]
list peek(integer offset)
{
return [ llList2Integer(lHISTORYLINK,2*offset+1)] + llParseStringKeepNulls(llList2String(lHISTORY,offset),["|"],[]);
}
string str_replace(string src, string from, string to)
{//replaces all occurrences of 'from' with 'to' in 'src'.
integer len = (~-(llStringLength(from)));
if(~len)
{
string buffer = src;
integer b_pos = -1;
integer to_len = (~-(llStringLength(to)));
@loop;//instead of a while loop, saves 5 bytes (and run faster).
integer to_pos = ~llSubStringIndex(buffer, from);
if(to_pos)
{
buffer = llGetSubString(src = llInsertString(llDeleteSubString(src, b_pos -= to_pos, b_pos + len), b_pos, to), (-~(b_pos += to_len)), 0x8000);
jump loop;
}
}
return src;
}
// use channel 10 to debug (no cluttering of 0 channel, easy to listen with mystitool)
debug(string str)
{
if(iDEBUG==1) llSay(10,str);
}
string dumpList(list lst)
{
return llDumpList2String(lst,"|");
}
list parseString(string str)
{
return llParseStringKeepNulls(str,["|"],[]);
}
//
// Will display the xxx|yyyy|zzz text loading <> color and @ for giving inventory
//
info(string str)
{
sINVENTORY=""; string vcolor="<1,1,1>";
list lst=llParseStringKeepNulls(str,["|"],[]);
integer goon=1;
while(goon==1)
{
string piece=llList2String(lst,0); string first=llGetSubString(piece,0,0);
if(first=="@" || first=="<")
{
string rest=llGetSubString(piece,1,-1);
if(first=="@")
{
sINVENTORY=rest; debug("Inventory: "+sINVENTORY);
lst+="==>"+sINVENTORY;
}
if(first=="<")
{
vcolor=piece;
debug("Color changed to. "+vcolor);
}
lst=llDeleteSubList(lst,0,0);
}
else goon=0;
}
str=llDumpList2String(lst,"n");
llMessageLinked(LINK_SET,1,dumpList( [ sME, "TEXT", "SHOW", str, vcolor ]),"");
}
// utility variables
vector vPOS; // starting point is the last one so that next will go on the first 😉
integer iENABLED=1; // autoslideshow enabled
integer iDIRECTION=1; // direction on next
integer iCNT=0; // counting from 1
integer iPOKE = FALSE; // no dblclick
setBoard()
{
list parms=[ PRIM_TEXTURE,0 , sTEXTURE, <fSCALX, fSCALY,0.0>, vPOS, 0.0 ];
debug("SetPrimitiveParams: "+llList2CSV(parms));
llSetPrimitiveParams(parms);
}
//
// go to next images in the grid
//
// order is from left to right and from top to bottom (like reading)
// Quite intuitive
//
next ()
{
debug("doing next");
iDIRECTION=1;
vPOS.x=vPOS.x+fSCALX;
if(vPOS.x>fSPANX){
debug("vPOS.x over fSPANX");
vPOS.x=-fSPANX;
vPOS.y=vPOS.y-fSCALY;
if(vPOS.y<-fSPANY)
{
debug("vPOS.y over fSPANY");
vPOS.y=fSPANY;
}
}
iCNT++;
if(iCNT>(iM*iN))
{
debug("iCNT over "+(string)(iM*iN));
iTEXTURE++;
changeTexture(); // will go on next texture
return;
}
if(sSEARCH=="")
{
setBoard();
push( sTEXTURE, <fSCALX, fSCALY, 0>, vPOS);
}
//info((string)iCNT +"/"+(string)(iM*iN)+"/"+(string)(iTEXTURE+1));
//llSetText((string)cnt +"/"+(string)NUM+"nx="+(string)pos.x+"-y="+(string)pos.y,<1,0,0>,1);
if(bENDTEXTURE==0)
{
iCOMMENT++; sTELEPORT="";
if(llGetInventoryType(sCOMMENT)!=INVENTORY_NOTECARD)
{
// check if this is a teleport URL xxxxxx,sim (x,y,z)
// find "("
integer i=llSubStringIndex(sTEXTURE,"(");
if(i>=0)
{
integer j=llSubStringIndex(sTEXTURE,")");
if(j>=0)
{
// look for first ","
integer k=llSubStringIndex(sTEXTURE,",");
sTELEPORT=llStringTrim(llGetSubString(sTEXTURE,k+1,i-1),STRING_TRIM);
string position=llStringTrim(llGetSubString(sTEXTURE,i+1,j-1),STRING_TRIM);;
vTELEPORT=(vector)("<"+position+">");
llMessageLinked(LINK_SET,1,dumpList( [ sME, "TEXT", "SHOW", "Teleport==>"+sTELEPORT+(string)vTELEPORT, "<1,1,1>" ]),"");
return;
}
}
llMessageLinked(LINK_SET,1,dumpList( [ sME, "TEXT", "SHOW", " ", "<1,1,1>" ]),"");
} else {
kCOMMENT=llGetNotecardLine(sCOMMENT,iCOMMENT);
}
}
}
changeTexture()
{
debug("changing texture to "+(string)iTEXTURE);
sTEXTURE=llGetInventoryName(INVENTORY_TEXTURE,iTEXTURE);
if(sTEXTURE=="")
{
if(sSEARCH!="")
{
sSEARCH="";
return;
}
// if textures finished then go back to first
iTEXTURE=0;
changeTexture();
return;
}
// use only textures beginning with _
//if(llGetSubString(sTEXTURE,0,0)=="_")
{
list pieces=llParseStringKeepNulls(sTEXTURE,["-"],[]);
string lastpiece=llList2String(pieces,-1);
pieces=llParseStringKeepNulls(lastpiece,["x"],[]);
iM=(integer)llList2String(pieces,0);
iN=(integer)llList2String(pieces,1);
if(iM==0)iM=1;
if(iN==0)iN=1;
debug("read iM="+(string)iM+" iN="+(string)iN);
// look for a comment notecard
sCOMMENT=sTEXTURE+".txt";
iCOMMENT=-1;
fSPANY=((float)iM-1)/(2*(float)iM);
fSCALY=1/(float)iM;
fSPANX=((float)iN-1)/(2*(float)iN);
fSCALX=1/(float)iN;
vSTARTPOS=<fSPANX,-fSPANY,0>;
vPOS=vSTARTPOS;
iCNT=0;
bENDTEXTURE=0;
// show first image/subimage while notecardline will setText their content
next();
}
//else
//{
// iTEXTURE++;
// changeTexture();
//}
}
default
{
state_entry()
{
debug("Starting...");
// read notecard, at end will start viewer
//iSETUP=0;
//kSETUP=llGetNotecardLine(sSETUP,iSETUP);
// find LINKNUM of History-0 until History-4
integer i;
for(i=2;i<llGetNumberOfPrims();i++)
{
string name=llGetLinkName(i);
debug("Found name: "+name+" linknum: "+(string)i);
list pieces=llParseStringKeepNulls(name,["-"],[]);
if(llList2String(pieces,0)=="History")
{
// it is an history
debug("marking history piece");
lHISTORYLINK+=[ llList2String(pieces,1), i ];
}
}
// have history links ordered by History-x parm
lHISTORYLINK=llListSort(lHISTORYLINK,2,TRUE);
debug("lHISTORYLINK: "+llList2CSV(lHISTORYLINK));
// reset play button to play and not pause if needed
llMessageLinked(LINK_SET,1,dumpList( [ sME, "PLAY", "OFFSET", "<.333,.333,0>"]),"");
// look for first image in the inventory
iTEXTURE=0;
changeTexture();
//llListen(0,"",NULL_KEY,""); // for searching
}
changed(integer change)
{
if(change==CHANGED_INVENTORY)
{
//llResetScript();
return;
}
}
// notecard reader
dataserver(key id, string data)
{
if(id==kCOMMENT)
if(data!=EOF)
{
debug("Reading comment line #"+(string)iCOMMENT);
if(llGetSubString(data,0,0)!="#")
{
if(sSEARCH!="")
{
// either find uppercase or with no casing (numbers)
if(llSubStringIndex(llToUpper(data),llToUpper(sSEARCH))<0)
{
llMessageLinked(LINK_SET,1,dumpList( [ sME, "TEXT", "SHOW", "searching for "+sSEARCH+"...", "<1,1,1>" ]),"");
// if not found go next
next();
return;
}
else
{
// found!!
sSEARCH="";
setBoard();
push( sTEXTURE, <fSCALX, fSCALY, 0>, vPOS);
}
}
//string replaced=str_replace(data,"|","n");
push_text(data);
// only first line | replaced by n
info(data);
return;
}
iCOMMENT++;
kCOMMENT=llGetNotecardLine(sCOMMENT, iCOMMENT);
}
else
{
debug("End of comments");
bENDTEXTURE=1;
}
}
touch_start(integer total_number)
{
key avatar=llDetectedKey(0);
if(iLISTENHANDLER!=0)llListenRemove(iLISTENHANDLER);
integer touched=llDetectedLinkNumber(0);
debug("touched: "+(string)touched);
if(touched==1){
if(sTELEPORT!="")
{
llMapDestination(sTELEPORT,vTELEPORT,ZERO_VECTOR);
return;
}
if(sINVENTORY=="") next();
else
{
llGiveInventory(avatar,sINVENTORY);
return;
}
}
string linkname=llGetLinkName(touched);
if(linkname=="Search")
{
iLISTENHANDLER=llListen(0,"",avatar,"");
llSetTimerEvent(60);
llDialog(avatar,"Say on normal chat FIND xxx or SEARCH xxx. You have 60 seconds for doing it.",[],-1);
return;
}
if(linkname=="Stop")
{
llResetScript();
return;
}
if(linkname=="Next")
{
next();
return;
}
if(linkname=="FastNext")
{
iTEXTURE++;
changeTexture();
return;
}
if(linkname=="FastPrev" && iTEXTURE>0)
{
iTEXTURE-=1;
changeTexture();
return;
}
if(linkname=="Play")
{
if(iLISTENHANDLER!=0)
{
llListenRemove(iLISTENHANDLER);
iLISTENHANDLER=0;
}
if(iPLAY==0)
{
iPLAY=1;
llSetTimerEvent(0.1);
llMessageLinked(LINK_SET,1,dumpList( [ sME, "PLAY", "OFFSET", "<.333,-.333,0>"]),"");
return;
}
else
{
iPLAY=0;
llMessageLinked(LINK_SET,1,dumpList( [ sME, "PLAY", "OFFSET", "<.333,.333,0>"]),"");
llSetTimerEvent(0);
return;
}
}
list pieces=llParseStringKeepNulls(linkname,["-"],[]);
if(llList2String(pieces,0)=="History")
{
// touched history, will display its content
integer index=(integer)llList2String(pieces,1);
debug("Trying to reinstate image");
list data=peek(index);
llSetLinkPrimitiveParams(eBOARD,
[ PRIM_TEXTURE, ALL_SIDES,
llList2String(data,1), // texture
(vector)llList2String(data,2), // scale
(vector)llList2String(data,3), // offset
0.0 ]);
info(llList2String(lTEXT,index));
return;
}
}
timer()
{
if(iLISTENHANDLER!=0)
{
llListenRemove(iLISTENHANDLER);
iLISTENHANDLER=0;
llSetTimerEvent(0);
return;
}
next();
llSetTimerEvent(iDELAY);
}
listen(integer channel,string name,key id,string message)
{
// SEARCH?
if(llToUpper(llGetSubString(message,0,5))=="SEARCH")
{
sSEARCH=llGetSubString(message,7,-1);
llSay(0,"Starting search for "+sSEARCH);
// go on until found it
next();
return;
}
if(llToUpper(llGetSubString(message,0,3))=="FIND")
{
debug("FIND command");
string sfind=llGetSubString(message,5,-1);
llSay(0,"Starting find for "+sfind);
for(iTEXTURE=iTEXTURE;iTEXTURE<llGetInventoryNumber(INVENTORY_TEXTURE);iTEXTURE++)
{
sTEXTURE=llGetInventoryName(INVENTORY_TEXTURE,iTEXTURE);
debug("Scanning texture "+sTEXTURE);
if(llGetSubString(sTEXTURE,0,0)=="_")
{
string src=llToUpper(sTEXTURE);
string find=llToUpper(sfind);
debug("Checking if '"+src+"' contains '"+find+"' "+(string)llSubStringIndex(src,find));
if(llSubStringIndex(src,find)>=0)
{
debug("Found");
changeTexture();
return;
}
}
}
return;
}
}
}
Leave a comment