salahzar icon

SLVEC Intermedio 3 Giugno 2008: greeter

salahzar | PRO | 02/16/20 08:22:53 AM UTC | 0 ⭐ | 735 👁️ | Never ⏰ | []
text |

6 KB

|

None

|

0 👍

/

0 👎

Salahzar Stenvaag
SL Mentori Italiani
3 Giugno 2008
  Costruire un greeter. (uso di llSensorRepeat, llDialog elementari, llGiveInventory, funzioni di lista)
 Un greeter è una sorta di "maggiordomo" un robottino automatico che:
 - tiene nota delle persone che sono venute sulla tua land
- consegna ad ogni persona una notecard con le "istruzioni" della land
- evita di consegnare la notecard più di una volta alla stessa persona
- è in grado di dire al proprietario chi è venuto e di cancellare la lista
 E' molto utile nelle terre per dare le indicazioni delle condizioni di uso della terra etc.
 Può essere qualunque cosa, nel nostro esempio sarà una sfera. Ne metterò una all'inizio che consegna la notecard con il contenuto di questo corso.
 Per costruire un greeter faremo vari oggetti intermedi:
 1. greeter stupido che sente le persone e dà la notecard
2. aggiungiamo il vincolo della NON ripetizione
3. aggiungiamo istruzioni per interrogare il greeter e resettarlo.
  Parte 1. Greeter elementare.
 fate una sfera e metteteci dentro questo script:
 float range =40.0; // in metri
float rate = 30.0; // ogni quanti secondi fare la scansione
string GREETINGS="Benvenuto su questa terra\n Leggi la notecard per dettagli"; // può anche essere più lunga
default
{
    state_entry()
    {                
        llSensorRepeat( "", "", AGENT, range, TWO_PI, rate );      //   
    }
      sensor( integer number_detected )
    {
        integer i;
         for( i = 0; i < number_detected; i++ )
        {
            // (1) non da la notecard al proprietario!!!
            if( llDetectedKey( i ) != llGetOwner() )
            {
                string detected_name = llDetectedName( i );
                  llDialog(llDetectedKey(i), GREETINGS, ["Ok"], -1);
                 llGiveInventory(llDetectedKey(i),"Benvenuti a XXXXX"); // mettere il nome della notecard da dare
             }
            // (1) end
        }    
    }
}
 Per ogni persona che tocca l'oggetto se NON è l'owner dell'oggetto viene fatto un dialogo blu con il benvenuto e di conseguenza giveInventory della notecard.
Questo script funziona benissimo ma ha il difetto di dare ripetutamente gli oggetti agli avatar che ritornano o semplicemente che si muovono all'interno della land. E' molto intrusivo e può generare spam e disagio agli avatar circostanti.
Fate take il più presto possibile altrimenti darete un sacco di fastidio agli altri!!!
O rendete inoffensivo l'oggetto mettendolo not running!!!
  2. Facciamo un primo miglioramento tenendo una lista degli avatar evitando di dare più di una volta la notecard e il messaggio se l'avatar l'abbiamo già visto.
 aggiungiamo le seguenti:
 list visitor_list; // per tenere nota dei visitatori
 integer isNameOnList( string name )
{
    integer len = llGetListLength( visitor_list );
    integer i;
    for( i = 0; i < len; i++ )
    {
        if( llList2String(visitor_list, i) == name )
        {
            return TRUE;
        }
    }
    return FALSE;
}
 Questa funzione è importante. Prende il numero di elementi nella lista e scorre la lista per vedere se l'elemento i-esicom coincide con il nome fornito. Se almeno uno coincide torna TRUE (vero) altrimenti FALSE.
 La funzione sensor viene modificata nel punto (1):
             if( llDetectedKey( i ) != llGetOwner() )
            {
                string detected_name = llDetectedName( i );
                 if( isNameOnList( detected_name ) == FALSE )
                {
                    visitor_list += detected_name;
                      llDialog(llDetectedKey(i), GREETINGS, ["Ok"], -1);
                 llGiveInventory(llDetectedKey(i),"Benvenuti a XXXXX");
                 }
            }
        }    
 Come vedete la llDialog e la llGiveInventory vengono eseguite SOLO se isNameOnList torna FALSE. In questo modo siamo meno intrusivi!!!
Adesso vedete che va molto meglio se volete potete anche ridurre l'intervallo di tempo prima di fare una nuova scansione mettendola ad 1 al secondo. Tenete conto che produce un po' di lag.
 3. Se vogliamo anche aggiungere un modo di controllare il greeter da parte dell'owner, permettendogli di fare
- mostra lista (per l'elenco delle persone)
- riparti (per ripulire l'oggetto e ripartire dacapo)
- aiuto per un help
 dobbiamo aggiungere le seguenti parti:
 a) in state_entry()
         llSay(0, "Il greeter sta partendo...");
        llSay(0, "Il proprietario può dire 'aiuto' per istruzioni"); 
          llListen(0, "", llGetOwner(), ""); // per ascoltare SOLO il proprietario
 b) aggiungere la listen per eseguire i comandi:
     listen( integer channel, string name, key id, string message )
    {
        if( id != llGetOwner() ) // ignora i comandi non del proprietario
        {
            return;
        }
         if( message == "aiuto" )
        {
            llSay( 0, "Questo oggetto registra i nomi di chiunque " );
            llSay( 0, "si avvicina entro "+ (string)range + " metri." );
            llSay( 0, "Comandi che il proprietario può dire nella chat:" );
            llSay( 0, "'aiuto'  - mostra queste istruzioni." );
            llSay( 0, "'mostra lista'   - Verifica i nomi nella lista.");
            llSay( 0, "'cancella lista' - Cancella tutti i nomi dalla lista." );
        }
        else
        if( message == "mostra lista" )
        {
            llSay( 0, "Visitatori:" );
            integer len = llGetListLength( visitor_list );
            integer i;
            for( i = 0; i < len; i++ )
            {
                llSay( 0, llList2String(visitor_list, i) );
            }
            llSay( 0, "Numero Totale = " + (string)len ); 
        }
        else
        if( message == "cancella lista" )
        {
            visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
            llSay( 0, "Lista cancellata.");
        }
    }

Comments