07/12/2008

Costruire un rezzer (la versione di Pyramid)

A dicembre Salahzar è sbarcato a Pyramid con lezioni tutti i Lunedì alle ore 22.00 circa.

Le lezioni avranno tutte come argomenti il rezzer come è presentato su Pyramid, i cui script originalmente creati da "JonnyBee Cioc" ed adattati da Salahzar, sono un ottimo esempio di come si possano fare rezzer interessanti e funzionali senza spendere migliaia di L$ per comprarli...

Nell'articolo le slide e gli script.


PyramidRezzer1x
 
Ecco gli scripts:
 
1. Tasto "-":
default
{
    touch_start(integer total_number){
        llMessageLinked(LINK_ALL_OTHERS,0,"MENO",llDetectedKey(0));
    }
}
2. Tasto "+":
 default
{
    touch_start(integer total_number){
        llMessageLinked(LINK_ALL_OTHERS,0,"PIU",llDetectedKey(0));
    }
}
3. Tasto "verde" REZZA:
// elenco canali usati
integer CHANNEL_CAMBIA=0;
integer CHANNEL_TEXT=1;
integer CHANNEL_REZZA=2;
integer CHANNEL_BLOCCA=3;

// stato unlock
integer UNLOCK=TRUE;

// scrive scritta fluttuante
scrivi(string s){
    llSetText(s,<1,1,1>,1);
}

default
{
    // se toccato ed è UNLOCK allora manda messaggio di rez
    touch_start(integer total_number){
        if(UNLOCK>0)
            llMessageLinked(LINK_ALL_OTHERS,CHANNEL_REZZA,"",NULL_KEY);
        else
            // altrimenti segnala che è bloccato
            llInstantMessage(llDetectedKey(0),"Una persona del guppo Pyramid Cafe' ha bloccato lo scorrimento degli scenari");
    }
   
    // se chiamato sul canale testo scrive il testo
    link_message(integer sender_num,integer num,string str,key id){
        if(num==CHANNEL_TEXT){
            scrivi(str);
        }
        else if(num==CHANNEL_BLOCCA){
            UNLOCK=~UNLOCK;
        }
    }   
}
4. Tasto nero "cancella": (aggiunto per comodità da Salahzar)
// elenco canali usati
integer CHANNEL_CAMBIA=0;
integer CHANNEL_TEXT=1;
integer CHANNEL_REZZA=2;
integer CHANNEL_BLOCCA=3;

// stato unlock
integer UNLOCK=TRUE;

// canale di cancellazione (da ricalcolarsi!!!)
integer cancella=-1010;


// funzione che torna un intero univoco per ogni avatar
integer OwnerKey()
{
    string ownerKey=(string)llGetOwner();
    string numbers="0123456789";
    integer i; integer result=0;
    for(i=0;i<llStringLength(ownerKey);i++) {
        string char=llGetSubString(ownerKey,i,i);
        integer index=llSubStringIndex(numbers,char);
        if(index>=0)
        {
            result+=result*10+index;
        }
    }
    return -result;
}
default
{
    state_entry()
    {
        cancella=OwnerKey();
        llSetText("Cancella",<0,1,1>,1);
    }
    // se toccato ed è UNLOCK allora manda messaggio di rez
    touch_start(integer total_number){
        if(UNLOCK>0)
        {
            llSay(0,"Saying CANCELLA on channel "+(string)cancella);
            llSay(cancella,"CANCELLA");
        }
        else
            // altrimenti segnala che è bloccato
            llInstantMessage(llDetectedKey(0),"Una persona del guppo Pyramid Cafe' ha bloccato la cancellazione degli scenari");
    }
   
    // se chiamato sul canale testo scrive il testo
    link_message(integer sender_num,integer num,string str,key id){
        if(num==CHANNEL_BLOCCA){
            UNLOCK=~UNLOCK;
        }
    }   
}
 
5. Tasto "blocca telecomando"

integer CHANNEL_CAMBIA=0;
integer CHANNEL_TEXT=1;
integer CHANNEL_REZZA=2;
integer CHANNEL_BLOCCA=3;

integer UNLOCK=TRUE;
string msg;

// scrive lo stato (locked/unlocked)
scrivi(){
    if(UNLOCK>0)
        msg="Unlocked";
    else
        msg="Locked";
    llSetText(msg,<1,1,0>,1);
}

default
{
    // non appena entrato scrive lo stato
    state_entry(){
        scrivi();
    }
   
    // se toccato ed è dello stesso gruppo allora inverte lo stato
    touch_start(integer total_number){
        key avatar=llDetectedKey(0);
        if(llSameGroup(avatar)){
        //if(~llListFindList(members,[llKey2Name(avatar)])){
            UNLOCK=~UNLOCK;
            scrivi();
            llMessageLinked(LINK_ALL_OTHERS,CHANNEL_BLOCCA,"",NULL_KEY);
        }
    }
}
 
6. Il "cuore" dello script dentro il telecomando, il rezzer appunto
// i 4 canali usati questi NON devono essere modificati solo CANCELLA
integer CHANNEL_CAMBIA=0; // risponde a "+" o "-"
integer CHANNEL_TEXT=1;
integer CHANNEL_REZZA=2;
integer CHANNEL_BLOCCA=3;

// stato di lock
integer UNLOCK=TRUE;

// quanti scenari sono contenuti
integer total_number=0;

// lista di tutti gli scenari
list nomi_scenari;

// indice attuale di scorrimento
integer index=0;

// canale di cancellazione (da ricalcolarsi!!!)
integer cancella=-1010;

// posizione di rez (da ricalcolarsi!!!!)
vector posizione=<107.715,181.310,724.853>;

// funzione che torna un intero univoco per ogni avatar
integer OwnerKey()
{
    string ownerKey=(string)llGetOwner();
    string numbers="0123456789";
    integer i; integer result=0;
    for(i=0;i<llStringLength(ownerKey);i++) {
        string char=llGetSubString(ownerKey,i,i);
        integer index=llSubStringIndex(numbers,char);
        if(index>=0)
        {
            result+=result*10+index;
        }
    }
    return -result;
}

aggiorna(){
   
    // cancella cambia a seconda dell'owner (non è perfetto, possono ancora comparire
    // sovrapposizioni
   
    cancella=OwnerKey();
   
    // aggiunto da salahzar, imposta la posizione corrente del linked set
    posizione=llGetPos();
   
    // trova tutti gli scenari
    nomi_scenari=[];
    total_number=llGetInventoryNumber(INVENTORY_OBJECT);
    integer i;
    for(i=0;i<total_number;i++)
        nomi_scenari+=llGetInventoryName(INVENTORY_OBJECT,i);
}

default
{   
    // alla partenza calcola i canali e carica la lista
    state_entry(){
        aggiorna();
    }
   
    // se aggiungo/tolgo dall'inventory ricalcola la lista
    // anche se cambia il proprietario
    changed(integer change){
        if(change==CHANGED_INVENTORY){
            aggiorna();
        }
    }
   
    // risponde ai canali interni (solo se ci sono scenari)
    link_message(integer sender_num,integer num,string str,key id){
        llSay(0,"received on chan "+(string)num+" string "+str);
        if(total_number>0 && num==CHANNEL_CAMBIA && UNLOCK>0){
           
            // risponde al canale CAMBIA solo se UNLOCK vale 1 (true)
            // se PIU' e siamo alla fine riparte da 0 altrimenti incrementa contatore
            if(str=="PIU"){
                if(index==total_number-1)
                    index=0;
                else   
                    index++;
                // manda sul canale di visualizzazione il nome della scena
                llMessageLinked(LINK_ALL_OTHERS,CHANNEL_TEXT,llList2String(nomi_scenari,index),NULL_KEY);
            }
            // se MENO e siamo all'inizio riparte dal fondo, altrimenti decrementa
            else if(str=="MENO"){
                if(index==0)
                    index=total_number-1;
                else
                    index--;
                // manda sul canale di visualizzazione il nome della scena
                llMessageLinked(LINK_ALL_OTHERS,CHANNEL_TEXT,llList2String(nomi_scenari,index),NULL_KEY);
            }
        }
        // risponde al canale REZZA
        else if(num==CHANNEL_REZZA){
           
            // prima cancella l'oggetto precedente
            llSay(0,"saying cancella on channel: "+(string)cancella);
            llSay(cancella,"CANCELLA");
           
            // rezza l'oggetto alla posizione specificata con velocità nulla e ruotato di 90 gradi
            llRezAtRoot(llList2String(nomi_scenari,index),posizione-<0-0.108,1.4-0.268,0.489>,ZERO_VECTOR,llEuler2Rot(<0,0,-PI/2>),0);
        }
        // risponde al canale blocca invertendo lo stato del
        else if(num==CHANNEL_BLOCCA){
            UNLOCK=~UNLOCK;
        }
    }
}
 
7. Lo script della base
// canale su cui ascolta (ownerkey()-1)
integer cancella;

// funzione che torna un intero univoco per ogni avatar
integer OwnerKey()
{
    string ownerKey=(string)llGetOwner();
    string numbers="0123456789";
    integer i; integer result=0;
    for(i=0;i<llStringLength(ownerKey);i++) {
        string char=llGetSubString(ownerKey,i,i);
        integer index=llSubStringIndex(numbers,char);
        if(index>=0)
        {
            result+=result*10+index;
        }
    }
    return -result;
}

default
{

    // al reset calcola il canale e ascolta
    state_entry(){
        cancella=OwnerKey();  
        llSay(0,"Ascolto sul canale "+(string)cancella);    
        llListen(cancella,"",NULL_KEY,"CANCELLA");
    }

    // al rez calcola il canale e ascolta
    on_rez(integer start_param){
        cancella=OwnerKey();
        llSay(0,"Ascolto sul canale "+(string)cancella); 
        llListen(cancella,"",NULL_KEY,"CANCELLA");
    }

    // ascolta e muore
    listen(integer channel,string name,key id,string message){
        if(channel==cancella)
        {
            llSay(0,"ricevuto comando di sparire");
            llDie();
        }
    }
}
 
 
 
 

Scrivi un commento