Je me suis un peu attardé sur les limitations des listes. Je me suis dit qu'il serait bien de faire quelque chose de générique, facilement réutilisable. Le principe est simple : plusieurs scripts (Liste) contenant chacun une liste, un script pour gérer tout ça (Master) et évidemment une application qui utilise les listes, ici le cas d'un vote. Donc trois scripts, le premier est celui qui gère une liste unitaire :
//------------------------------------------------
//
// Liste V 1.1
//
// by bestmomo Lagan
//
// -----------------------------------------------
// Messages communs
// -----------------------------------------------
string messageInit = "INITIALISATION";
// -----------------------------------------------
// Messages avec master
// -----------------------------------------------
string messagePresent = "PRESENT";
string messageAjoute = "AJOUTE";
string reponseNon = "NON";
string reponseOui = "OUI";
// -----------------------------------------------
// Variables
// -----------------------------------------------
string nomBase = "Liste";
integer indexMaster = 300;
integer index;
list liste;
// -----------------------------------------------
// Initialisations
// -----------------------------------------------
init() {
index = llList2Integer(llParseString2List(llGetScriptName(),[nomBase],[]),0);
llWhisper(PUBLIC_CHANNEL, (string)index);
liste = [];
}
// -----------------------------------------------
// Etat par défaut
// -----------------------------------------------
default
{
state_entry(){init();}
on_rez(integer start_param){init();}
// Ecoute et traitement des messages
link_message(integer sender_number, integer number, string message, key id) {
if (message == messageInit)
init();
else if (message == messagePresent){
if (llListFindList(liste, [id]) == -1)
llMessageLinked(LINK_THIS, indexMaster, reponseNon, NULL_KEY);
else
llMessageLinked(LINK_THIS, indexMaster, reponseOui, NULL_KEY);
}
else if (message == messageAjoute && number == index)
liste += id;
}
}
Comme le principe est d'avoir plusieurs de ces listes chacune détermine son index à partir du nom du script. Le premier script Liste déposé s'appelle "Liste", le second "Liste1"... du coup les index sont 0, 1....
Le second script est le Master qui gère les listes individuelles :
//------------------------------------------------
//
// Master V 1.0
//
// -----------------------------------------------
// Messages communs
// -----------------------------------------------
string messageInit = "INITIALISATION";
// -----------------------------------------------
// Messages avec listes
// -----------------------------------------------
string messagePresent = "PRESENT";
string messageAjoute = "AJOUTE";
string reponseNon = "NON";
string reponseOui = "OUI";
// -----------------------------------------------
// Messages avec appelant
// -----------------------------------------------
string reponsePresent = "DEJAPRESENT";
string reponseOK = "OK";
string reponseOverflow = "OVERFLOW";
// -----------------------------------------------
// Variables
// -----------------------------------------------
string nomBase = "Liste";
integer indexMaster = 300;
integer indexAppellant = 400;
integer maxListe = 100;
integer indexScript;
integer compteScript;
integer nombreListes;
integer nombreReponses;
integer overflow;
string nom;
// -----------------------------------------------
// Initialisations
// -----------------------------------------------
init() {
indexScript = 0;
nombreReponses = 0;
compteScript = 0;
overflow = FALSE;
calculNombreListes();
}
// -----------------------------------------------
// Calcul nombre de listes disponibles
// -----------------------------------------------
calculNombreListes() {
integer n = llGetInventoryNumber(INVENTORY_SCRIPT);
integer longueurNomBase = llStringLength(nomBase);
integer c;
nombreListes = 0;
for(c = 0; c < n; ++c) {
string nomScript = llGetInventoryName(INVENTORY_SCRIPT, c);
if (llGetSubString(nomScript, 0, longueurNomBase - 1) == nomBase)
nombreListes++;
}
}
// -----------------------------------------------
// Etat par défaut
// -----------------------------------------------
default
{
state_entry(){init();}
on_rez(integer start_param){init();}
// Ecoute et traitement des messages
link_message(integer sender_number, integer number, string message, key id) {
if (message == messageInit)
init();
else if (number == indexMaster && !overflow) {
if (message == messageAjoute) {
nom = (string)id;
nombreReponses = 0;
llMessageLinked(LINK_THIS, 0, messagePresent, nom);
}
else if(message == reponseOui) {
llMessageLinked(LINK_THIS, indexAppellant, reponsePresent, NULL_KEY);
}
else if(message == reponseNon) {
nombreReponses++;
if (nombreReponses == nombreListes) {
llMessageLinked(LINK_THIS, indexScript, messageAjoute, nom);
llMessageLinked(LINK_THIS, indexAppellant, reponseOK, NULL_KEY);
compteScript++;
if (compteScript == maxListe) {
compteScript = 0;
indexScript++;
if (indexScript == nombreListes) {
overflow = TRUE;
llMessageLinked(LINK_THIS, indexAppellant, reponseOverflow, NULL_KEY);
}}}}}}}
Maintenant le script pour le vote proprement dit qui n'a plus qu'à exploiter les listes liées à travers le master :
//------------------------------------------------
//
// Vote V 1.0
//
// -----------------------------------------------
// Messages
// -----------------------------------------------
string messageInit = "INITIALISATION";
string messageAjoute = "AJOUTE";
string reponsePresent = "DEJAPRESENT";
string reponseOK = "OK";
string reponseOverflow = "OVERFLOW";
// -----------------------------------------------
// Variables
// -----------------------------------------------
integer compteur;
integer indexMaster = 300;
integer indexAppellant = 400;
integer canal;
integer ecoute;
integer overflow;
integer go;
string nomVotant;
// -----------------------------------------------
// Initialisations
// -----------------------------------------------
init() {
go = FALSE;
compteur = 0;
overflow = FALSE;
canal = llFloor(llFrand(2000000.0));
initListes();
affichagetexte("Votes : 0");
}
// -----------------------------------------------
// Initialisation des listes
// -----------------------------------------------
initListes() {
llMessageLinked(LINK_THIS, 0, messageInit, NULL_KEY);
}
// -----------------------------------------------
// Ajout d'un nom
// -----------------------------------------------
ajoutNom(string nom) {
llMessageLinked(LINK_THIS, indexMaster, messageAjoute, nom);
}
// -----------------------------------------------
// Activation de l'écoute
// -----------------------------------------------
UpdateListen(key id) {
CancelListen();
ecoute = llListen(canal,"",id,"");
llSetTimerEvent(30.0);
}
// -----------------------------------------------
// Désactivation de l'écoute
// -----------------------------------------------
CancelListen() {
if(ecoute > 0) llListenRemove(ecoute);
ecoute = 0;
llSetTimerEvent(.0);
}
// -----------------------------------------------
// Affichage texte
// -----------------------------------------------
affichagetexte(string texte) {
llSetText(texte, <1.0,1.0,1.0>, 1.0);
}
// -----------------------------------------------
// Etat par défaut
// -----------------------------------------------
default
{
state_entry(){init();}
on_rez(integer start_param){init();}
// Clic sur l'objet
touch_start(integer total_number) {
key owner = llGetOwner();
if (llDetectedKey(0) == owner) {
UpdateListen(owner);
llDialog(owner, "Intialisation", ["GO", "CANCEL"], canal);
}
else if (!overflow && go) {
go = FALSE;
nomVotant = llDetectedName(0);
ajoutNom(nomVotant);
}
}
// Ecoute et traitement des messages
link_message(integer sender_number, integer number, string message, key id) {
if (number == indexAppellant) {
if(message == reponsePresent)
llWhisper(PUBLIC_CHANNEL, nomVotant + " has already voted !!!");
else if (message == reponseOK) {
llWhisper(PUBLIC_CHANNEL, nomVotant + " thank you for your vote.");
compteur++;
affichagetexte("Votes : " + (string)compteur);
}
else if (message == reponseOverflow)
overflow = TRUE;
go = TRUE;
}
}
// Ecoute du Chat
listen(integer channel, string name, key id, string message) {
if (channel == canal) {
if (message == "GO") {
init();
go = TRUE;
}
else if (message == "CANCEL")
go = FALSE;
CancelListen();
}
}
timer() {CancelListen();}
}
Je n'ai pas cherché à optimiser ce dernier script, son intérêt premier étant de montrer une utilisation des listes liées. Je ne garantis pas l'absence de bug parce que j'ai codé ça rapidement et j'étais tout seul pour tester tout ça et c'est pas vraiment l'idéal
Pour résumé l'utilisation vous prenez un objet, vous glissez dedans autant de script Liste que vous voulez (j'ai calibré à 100 enregistrement par liste), vous glissez ensuite le master et le Vote. Cliquez sur l'objet et sélectionnez "GO" pour initialiser le système.