User:Daemonika Nightfire/Scripts/Dynamic Menu
Dynamisches Menue
Ein dynamisches Menue ist ein Menue, das sich anhand der verfuegbaren Daten aus einer Liste selbst generiert. In diesem Basis-Beispiel haben wir ein Menue mit einer vordefinierten Liste, in der lediglich schriftlich auf Englisch von 1 bis 10 gezaehlt wird. Wenn wir nun im Menue einen stellvertretenden Button druecken, wird das entsprechende Wort im Chat ausgegeben.
// Liste mit Eintraegen
integer qty = 0;
list entrys = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"];
// Generiert ein menue aus der Liste
list menubutton = [];
list navigation = [];
string menudesc = "";
integer index_start = 0;
integer index_end = 5;
integer selection = 6;
BuildMenu()
{
menubutton = [];
navigation = [];
menudesc = "";
// Startpunkt befindet sich unter 0.
if(index_start < 0)
{
// Der Startpunkt ist das Maximum abzueglich des unteilbaren Rests von Maximum/selection.
index_start = qty - (qty%selection);
if(index_start == qty)
{
index_start = qty - selection;
}
}
// The Startpunkt liegt ueber dem Maximum
if(index_start > qty-1)
{
// Damit fangen wir dann einfach wieder bei 0 an.
index_start = 0;
}
// Das anzuzeigende Ende wird vom endgueltigen Startpunkt aus bestimmt.
index_end = index_start + selection-1;
if(index_end >= qty)
{
index_end = qty-1;
}
navigation = ["<<<", "Close", ">>>"];
if(qty <= selection)
{
index_end = qty-1;
navigation = [] + ["...", "Close", "..."];
}
menudesc = "\nChoose your options.\n\n";
integer i = index_start;
do
{
string number = (string)(i+1);
menudesc += number + ") " + llGetSubString(llList2String(entrys, i), 0, 39) + "\n";
menubutton += number;
}
while(++i <= index_end);
}
// Generiert einen zufaelligen Menue-Channel
integer menu_handler;
integer menu_channel;
OpenMenu(key user, string title, list buttons)
{
llListenRemove(menu_handler);
menu_channel = (integer)(llFrand(1) * -DEBUG_CHANNEL);
menu_handler = llListen(menu_channel, "", "", "");
llDialog(user, title, buttons, menu_channel);
llSetTimerEvent(60.0);
}
default
{
state_entry()
{
qty = llGetListLength(entrys);
llSay(0, "\n" + (string)qty + " entrys loaded.\n" + (string)llGetUsedMemory() + " bytes memory in use.");
}
touch_start(integer total_number)
{
key agent = llDetectedKey(0);
index_start = 0;
index_end = selection-1;
BuildMenu();
OpenMenu(agent, menudesc, navigation + menubutton);
}
listen(integer chan, string name, key id, string msg)
{
list parsed = llParseString2List(msg, [" "], []);
string cmd = llList2String(parsed, 0);
//string data = llList2String(parsed, 1); // Falls wir zweiteilige Commandos nutzen
if(chan == menu_channel)
{
if(cmd == "Close" || cmd == "...")
{
llListenRemove(menu_handler);
llSetTimerEvent(0.0);
}
else if(cmd == ">>>")
{
index_start += selection;
BuildMenu();
OpenMenu(id, menudesc, navigation + menubutton);
}
else if(cmd == "<<<")
{
index_start -= selection;
BuildMenu();
OpenMenu(id, menudesc, navigation + menubutton);
}
else if(~llListFindList(menubutton, [cmd]))
{
string choice = llList2String(entrys, (integer)cmd-1);
llOwnerSay("entry: " + choice);
BuildMenu();
OpenMenu(id, menudesc, navigation + menubutton);
}
}
}
timer()
{
llListenRemove(menu_handler);
llSetTimerEvent(0.0);
}
changed(integer ch)
{
if(ch & CHANGED_INVENTORY)
{
llResetScript();
}
}
on_rez(integer Dae)
{
llResetScript();
}
}
Automatisch generiertes Menue
Ich werde hier nicht fuer alle moeglichen Varianten das gesamte Menue wiederholen. Stattdessen beschreibe ich, wie die Liste gefuellt werden kann. Beachte in welchen Events sich die entsprechenden Befehle befinden.
Inhalt
In diesem Beispiel siehst du, wie der Inhalt eines Objekts ausgelesen, durchgezaehlt und die Namen in der Liste gespeichert werden. Denke daran, wenn du Animationen auflisten und per Knopfdruck abspielen moechtest, das du zusaetzlich noch entsprechende Berechtigungen schaffen musst. (siehe LlRequestPermissions).
integer qty = 0;
list entrys = [];
default
{
state_entry()
{
qty = llGetInventoryNumber(INVENTORY_OBJECT);
if(qty > 0)
{
integer i = 0;
do
{
string qty_name = llGetInventoryName(INVENTORY_OBJECT, i);
entrys += qty_name;
if(llGetFreeMemory() < 10000)
{
llOwnerSay("/me Memory Control: Unable to add more entrys.");
i = qty;
}
}
while(++i < qty);
qty = llGetListLength(entrys);
}
llSay(0, "\n" + (string)qty + " entrys loaded.\n" + (string)llGetUsedMemory() + " bytes memory in use.");
}
}
Notecard
Dieses Beispiel liest eine Notecard aus, dabei werden die einzelnen Zeilen gezaehlt und die Texte der Zeilen in der Liste gespeichert. Hierfuer ist eine Notecard erforderlich, aehnlich wie folgendes Beispiel.
New Note
text01 text02 text03 text04 text05 text06 text07 text08 text09 text10
integer qty = 0;
list entrys = [];
string nc_name = "";
key read_nc;
default
{
state_entry()
{
nc_name = llGetInventoryName(INVENTORY_NOTECARD, 0);
read_nc = llGetNumberOfNotecardLines(nc_name);
}
dataserver(key request, string data)
{
if(request == read_nc)
{
integer count = (integer)data;
integer i;
do
{
string line = llGetNotecardLineSync(nc_name, i);
if(line == NAK)
{
llSay(0, "---NAK---\nNotecard are missing or not readable.");
}
else if(line == EOF)
{
qty = llGetListLength(entrys);
llSay(0,"---EOF---\n" + (string)qty + " entrys loaded.\n" + (string)llGetUsedMemory() + " bytes memory in use.");
}
else
{
if(line != "")
{
if(llGetFreeMemory() >= 10000)
{
entrys += line;
}
}
}
}
while(++i <= count);
}
}
}
Agentlist (Radar)
Aehnlich wie die New Age Radar, wird auch hier lediglich die Agentlist auf der Region abgefragt und in die Liste eingepflegt.
integer qty = 0;
list entrys = [];
default
{
state_entry()
{
entrys = llGetAgentList(AGENT_LIST_REGION, []); // AGENT_LIST_PARCEL
qty = llGetListLength(entrys);
llSay(0, "\n" + (string)qty + " entrys loaded.\n" + (string)llGetUsedMemory() + " bytes memory in use.");
}
}