Heute stelle ich euch das letzte Script dieses Tutorials vor. Es dient dazu, die Zeitzone auszuwählen und an die Zeiger-Scripte zu übergeben. Darüber hinaus soll ein optionaler Hovertext mit einer Digitalanzeige der Zeit ein- und ausgeschaltet werden können.
Das ganze Script ist etwas länglich, aber ich will es euch in kleinen Dosen verabreichen und ein bisschen erklären, was die einzelnen Code-Stücke tun.
Ganz oben im Script fangen wir mit Konstanten und Variablen an. Im Gegensatz zu anderen Sprachen unterscheidet LSL nicht zwischen diesen beiden Sorten. Ich habe es mir dennoch angewöhnt, beide getrennt zu betrachten und Konstanten in Großbuchstaben zu benennen, wie es in Java üblich ist.
- Code: Alles auswählen
// constants
vector HOVERTEXT_COLOR = <1, 1, 1>;
list ZONES = ["-12", "-11", "-10", "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
"0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9", "+10", "+11", "+12"];
list ZONE_NAMES = ["UTC-12", "UTC-11", "UTC-10", "UTC-9", "SL Time (-8)", "MT (-7)",
"CT (-6)", "ET (-5)", "AT (-4)", "UTC-3", "UTC-2", "UTC-1",
"GMT (0)", "CET (+1)", "UTC+2", "UTC+3", "UTC+4", "UTC+5",
"UTC+6", "UTC+7", "UTC+8", "UTC+9", "UTC+10", "UTC+11", "UTC+12"];
list ZONE_TOWNS = ["Wellington", "Apia", "Honolulu", "Achorage", "Los Angeles", "Phoenix",
"Mexico City", "New York", "Santiago", "Sao Paulo", "Fernando de Noronha Island", "Cape Verde",
"London", "Berlin, Paris", "Cairo", "Moscow", "Dubai", "Karachi", "Dhaka", "Jakarta",
"Hong Kong", "Tokyo", "Sydney", "New Caledonia", "Wellington"];
string BUTT_NEXT = ">>";
string BUTT_PREV = "<<";
string BUTT_OK = "OK";
string BUTT_HT_OFF = "HT off";
string BUTT_HT_ON = "HT on";
// state
integer timezone_offset = 1;
integer selected = 12;
integer isHovertext = FALSE;
// for internal use
integer channel = 0;
integer listen_handle;
Es folgen eine Menge Funktionen, die an geeigeneter Stelle aufgerufen werden, darunter der Hauptteil des Scriptes, hier mit einem default State.
- Code: Alles auswählen
default
{
state_entry()
{
timezone_offset = llList2Integer(ZONES, selected);
channel = (integer)llFrand(99999)+99999;
listen_handle = llListen(channel, "", NULL_KEY, "");
llListenControl(listen_handle, FALSE);
llMessageLinked(LINK_ALL_OTHERS, 3600, (string) timezone_offset, NULL_KEY);
}
...
}
Zu Beginn der Scriptausführung initialisieren wir den Kanal für den Dialog und öffnen ein Handle. Dann bekommen über eine linked message alle Zeiger eine voreingestellte Zeitzone als Startwert übergeben.
Bis jetzt noch nichts wirklich interessantes. Nun soll das Script beim "touch" durch den Owner den Dialog öffnen. Richtig, wir benötigen ein touch() Event:
- Code: Alles auswählen
touch_start(integer total_number)
{
key avatar = llDetectedKey(0);
if(avatar == llGetOwner())
{
show_dialog(avatar);
}
}
show_dialog() ist eine der Funktionen, die ich vorhin übersprungen habe. Sie definiert den Dialog mit seiner Textmeldung und den Buttons.
- Code: Alles auswählen
show_dialog(key id)
{
string text = "";
text += "Current time: " + getTimeString(timezone_offset);
text += "\nTimezone: " + llList2String(ZONE_NAMES, selected);
text += " (" + llList2String(ZONE_TOWNS, selected) + ")";
text += "\nHovertext: " + getText(isHovertext);
list buttons = [BUTT_PREV, BUTT_OK, BUTT_NEXT];
if(isHovertext)
{
buttons += [BUTT_HT_OFF];
}
else
{
buttons += [BUTT_HT_ON];
}
llListenControl(listen_handle, TRUE);
llDialog(id, text, buttons, channel);
}
Der Dialog stellt vier Buttons dar: Einen OK-Button zum Beenden des Dialogs, je einen zum vorwärts und rückwärts blättern und einen zum ein- und ausschalten des Hovertexts.
Nun benötigen wir nur noch eine Implementierung des listen() Events, um auf die einzelnen Buttons zu reagieren.
- Code: Alles auswählen
listen(integer channel, string name, key id, string message)
{
if(message == BUTT_OK)
{
llListenControl(listen_handle, FALSE);
return;
}
if(message == BUTT_NEXT)
{
selected++;
if(selected > 24)
{
selected = 0;
}
timezone_offset = llList2Integer(ZONES, selected);
llMessageLinked(LINK_ALL_OTHERS, 3600, (string) timezone_offset, NULL_KEY);
}
if(message == BUTT_PREV)
{
selected--;
if(selected < 0)
{
selected = 24;
}
timezone_offset = llList2Integer(ZONES, selected);
llMessageLinked(LINK_ALL_OTHERS, 3600, (string) timezone_offset, NULL_KEY);
}
if(message == BUTT_HT_ON)
{
isHovertext = TRUE;
llSetTimerEvent(1.0);
}
if(message == BUTT_HT_OFF)
{
isHovertext = FALSE;
llSetTimerEvent(0.0);
llSetText("", HOVERTEXT_COLOR, 1.0);
}
show_dialog(id);
}
Der OK-Button deaktiviert den Listen Handler (um bisschen lag zu sparen). PREV und NEXT erniedrigen bzw. erhöhen den Wert der Variable selected und ermitteln daraus den in der Liste gespeicherten Wert für den Zeitunterschied. Diesen bekommen dann wieder unsere Zeiger.
BUTT_HT_ON und startet einen Timer, der aus der Zeit einen String errechnet und als Hovertext anzeigt:
- Code: Alles auswählen
timer()
{
if(isHovertext)
{
llSetText(getTimeString(timezone_offset), HOVERTEXT_COLOR, 1.0);
}
}
Die dafür benötigte Funktion getTimeString() funktioniert wie die Funktionen aus dem ersten Teil des Tutorials. Anstatt Stunden, Minuten und Sekunden einzeln zu ermitteln, werden sie hier in einer Funktion geholt und zu einem String zusammengebaut.
Das war's auch schon für heute. Hier nochmal das ganze Script:
- Code: Alles auswählen
// constants
list ZONES = ["-12", "-11", "-10", "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
"0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9", "+10", "+11", "+12"];
list ZONE_NAMES = ["UTC-12", "UTC-11", "UTC-10", "UTC-9", "SL Time (-8)", "MT (-7)",
"CT (-6)", "ET (-5)", "AT (-4)", "UTC-3", "UTC-2", "UTC-1",
"GMT (0)", "CET (+1)", "UTC+2", "UTC+3", "UTC+4", "UTC+5",
"UTC+6", "UTC+7", "UTC+8", "UTC+9", "UTC+10", "UTC+11", "UTC+12"];
list ZONE_TOWNS = ["Wellington", "Apia", "Honolulu", "Achorage", "Los Angeles", "Phoenix",
"Mexico City", "New York", "Santiago", "Sao Paulo", "Fernando de Noronha Island", "Cape Verde",
"London", "Berlin, Paris", "Cairo", "Moscow", "Dubai", "Karachi", "Dhaka", "Jakarta",
"Hong Kong", "Tokyo", "Sydney", "New Caledonia", "Wellington"];
string BUTT_NEXT = ">>";
string BUTT_PREV = "<<";
string BUTT_OK = "OK";
string BUTT_HT_OFF = "HT off";
string BUTT_HT_ON = "HT on";
vector HOVERTEXT_COLOR = <1, 1, 1>;
// state
integer timezone_offset = 1;
integer selected = 12;
integer isHovertext = FALSE;
// for internal use
integer channel = 0;
integer listen_handle;
string getTimeString(integer vIntLocalOffset) {
integer ft = ((integer) llGetGMTclock() + 86400 + vIntLocalOffset * 3600) % 86400;
integer hours = llFloor(ft / 3600);
integer minutes = llFloor((ft - (hours*3600)) / 60.0);
integer seconds = llFloor(ft) % 60;
string result = (string) hours + ":";
if(minutes < 10) result += "0";
result += (string)minutes + ":";
if(seconds < 10) result += "0";
result += (string)seconds;
return result;
}
string getText(integer boolean)
{
if(boolean)
{
return "ON";
}
else
{
return "OFF";
}
}
show_dialog(key id)
{
string text = "";
text += "Current time: " + getTimeString(timezone_offset);
text += "\nTimezone: " + llList2String(ZONE_NAMES, selected);
text += " (" + llList2String(ZONE_TOWNS, selected) + ")";
text += "\nHovertext: " + getText(isHovertext);
list buttons = [BUTT_PREV, BUTT_OK, BUTT_NEXT];
if(isHovertext)
{
buttons += [BUTT_HT_OFF];
}
else
{
buttons += [BUTT_HT_ON];
}
llListenControl(listen_handle, TRUE);
llDialog(id, text, buttons, channel);
}
default
{
state_entry()
{
timezone_offset = llList2Integer(ZONES, selected);
channel = (integer)llFrand(99999)+99999;
listen_handle = llListen(channel, "", NULL_KEY, "");
llListenControl(listen_handle, FALSE);
llMessageLinked(LINK_ALL_OTHERS, 3600, (string) timezone_offset, NULL_KEY);
}
timer()
{
if(isHovertext)
{
llSetText(getTimeString(timezone_offset), HOVERTEXT_COLOR, 1.0);
}
}
touch_start(integer total_number)
{
key avatar = llDetectedKey(0);
if(avatar == llGetOwner())
{
show_dialog(avatar);
}
}
listen(integer channel, string name, key id, string message)
{
if(message == BUTT_OK)
{
llListenControl(listen_handle, FALSE);
return;
}
if(message == BUTT_NEXT)
{
selected++;
if(selected > 24)
{
selected = 0;
}
timezone_offset = llList2Integer(ZONES, selected);
llMessageLinked(LINK_ALL_OTHERS, 3600, (string) timezone_offset, NULL_KEY);
}
if(message == BUTT_PREV)
{
selected--;
if(selected < 0)
{
selected = 24;
}
timezone_offset = llList2Integer(ZONES, selected);
llMessageLinked(LINK_ALL_OTHERS, 3600, (string) timezone_offset, NULL_KEY);
}
if(message == BUTT_HT_ON)
{
isHovertext = TRUE;
llSetTimerEvent(1.0);
}
if(message == BUTT_HT_OFF)
{
isHovertext = FALSE;
llSetTimerEvent(0.0);
llSetText("", HOVERTEXT_COLOR, 1.0);
}
show_dialog(id);
}
}
Viel Spaß beim analysieren und tüfteln,
eure Jenni