Wir bauen eine Fotokugel

Wer gern ein kleines Fotostudio hätte, muss dafür nichts bezahlen. Das bekommt man auch umsonst und mit ganz wenig Prims. Wie das geht zeig ich euch hier. Erzeugt zuerst eine Kugel und mach sie so groß wie ihr wollt. Stellt "Hohl" auf 95 und "Pfadschnitt Start" auf 0.5. Das ergibt eine hohle Halbkugel, so wie hier:

Erstellt nun ein paar Kugeln (maximal 8), die als Leuchten dienen sollen, und ordnet sie im Zentrum der Halbkugel an. Im Beispiel hier hab ich drei, das reicht völlig.

Die Objekte bekommen nun eine Leertextur. Die Leuchten werden umbenannt in "Light1", "Light2" usw. und die Halbkugel heißt "Light0". Nun kommt in jeder der Leuchten das Skript "light.lsl", in die Halbkugel das Skript "back.lsl".

Es fehlt noch sowas wie ein Bedienpult, wir erstellen also noch einen Kasten und legen das Skript "control.lsl" hinein. Wer will, kann auch gleich Texturen für den Hintergrund hineintun. Zum Schluss werden alle Teile verlinkt. Als letztes benötigen wir einen Posestand. Wir erzeugen einen Zylinder und drücken ihn zu einer Scheibe zusammen. Hinein kommt das skript "stand.lsl" und mindestens eine Animation. Nun positionieren wir den Posestand zwischen die Leuchten und schon ist die Fotokugel fertig, in meinem Fall hat sie nur 6 Prims. Sie sollte etwa so aussehen:

Mit dem "Bedienpult" (hier links im Bild) könnt ihr bei Klick jede Leuchte einzeln steuern: Lichtfarbe, Intensität, Radius, Lichtabfall oder auch abschalten bzw. unsichtbar machen. Für den Hintergrund könnt ihr eine Textur und/oder Farbe wählen. Ihr könnt auch später weitere Texturen hinzufügen. Wenn ihr euch auf den Posestand stellt, wird er unsichtbar und ihr könnt die Posen aus einem Menü auswählen. Mit den beiden Pfeilen oben dreht sich der Stand um jeweils 30 Grad. Selbstverständlich könnt ihr auch hier später weitere Posen hinzufügen. Der Stand muss gerezzt werden, damit er funktioniert.

(Auf den Bildern sind noch englische Bezeichnungen, ist aber deutsch jetzt.)
Wer sich das ganze nicht antun will, kann so eine Kugel samt Poseball mit ca. 150 Posen auch von mir bekommen, fullperm und kostenlos.

Als Extra gibts zum Schluss noch ein Skript für eine Leuchte zum Anklicken. Damit könnt ihr die Leuchten direkt steuern und auf das Bedienpult verzichten. Allerdings müssen die auch "Light1", "Light2" usw. heißen.

Hinweis: Bei mir gabs Schwierigkeiten, wenn im Posestand mehr als 200 Posen waren. Wenn ich dann noch welche hineintun wollte, bekam ich manchmal Skriptfehler. In solchen Fällen hilft, das Skript zurücksetzen, den Stand einzupacken und neu zu rezzen.

Update

Weil mich die ständigen Fehlermeldungen beim Füllen gestört haben, hab ich das Skript umgeschrieben. Es liest jetzt nicht mehr selbstständig die Animationen ein, sondern erst bei Berührung und "Reset". Außerdem stehen die Namen der Animationen nicht mehr auf den Tasten, sondern drüber, weil die meisten eh viel zu lange waren. Das alte Skript hab ich aber zum Vergleich auch noch drin gelassen.

Viel Spaß damit :))

Hier die Skripte:

control.lsl


// script copyright by Rebekka Revnik

integer MAXLIGHTS = 8;
integer COLOR = 1;
integer LIGHT = 2;
integer INTENS = 3;
integer CHOOSE = 4;
integer TEXTURE = 5;
integer BACKCOLOR = 6;

integer CHANNEL = 12345;
integer CHATCHANNEL = 55555;

list Textures;
list TexKeys;
list Intensity;
list Radius;
list Falloff;
list Color;
integer ActLight;

integer Menu;
integer Listener;
key User;

integer Page;

TextMenu()
{
	list l;
	//integer j;
	//Textures = [];
	//for(j = 0; j < 30; j++) Textures += [(string)j];
	integer x = llGetListLength(Textures);
	integer i = Page * 9 +1;
	if(x < 12) l = llList2List(Textures, 0, 0)+"Back"+llList2List(Textures, 1, 10);
	else if(Page == 0) l = llList2List(Textures, 0, 0) + ["Back","Next"] + llList2List(Textures, 1, 9);
	else if(x - i < 10) l = ["Prev","Back"] + llList2List(Textures, i, i + 9);
	else l = ["Prev","Back","Next"] + llList2List(Textures, i + 0, i + 8);
	llListenRemove(Listener);
	Listener = llListen(CHANNEL, "", User, "");
	Menu = TEXTURE;
	llDialog(User, "Choose a texture:", l, CHANNEL);
}

ColorMenu()
{
	vector v = llList2Vector(Color, ActLight);
	string s = "Light "+(string)ActLight+"\nRed: "+(string)v.x+"\nGreen: "+(string)v.y+"\nBlue: "+(string)v.z;
	llListenRemove(Listener);
	Listener = llListen(CHANNEL, "", User, "");
	llDialog(User, s, ["Blue+","Blue-","Back","Green+","Green-","Off","Red+","Red-","On"], CHANNEL);
}

IntensMenu()
{
	float i = llList2Float(Intensity, ActLight);
	integer r = llList2Integer(Radius, ActLight);
	float f = llList2Float(Falloff, ActLight);
	string s = "Light "+(string)ActLight+"\nIntensity: "+(string)i+"\nRadius: "+(string)r+"\nFalloff: "+(string)f;
	Menu = INTENS;
	llListenRemove(Listener);
	Listener = llListen(CHANNEL, "", User, "");
	llDialog(User, s, ["Falloff+","Falloff-","Back","Radius+","Radius-","Hide","Intensity+","Intensity-","Show","Color"], CHANNEL);
}

LightMenu()
{
	Menu = LIGHT;
	list l;
	integer i;
	for(i = 1; i <= MAXLIGHTS; i++) l += ["Light "+(string)i];
	l += ["Background","BackColor","Back"];
	llListenRemove(Listener);
	Listener = llListen(CHANNEL, "", User, "");
	llDialog(User, "Choose an option", l, CHANNEL);
}

float Bound(float x, float y)
{
	if(x < 0) return 0;
	if(x > y) return y;
	return x;
}

DoMenu(string msg)
{
	vector v = llList2Vector(Color, ActLight);
	float i = llList2Float(Intensity, ActLight);
	integer r = llList2Integer(Radius, ActLight);
	float f = llList2Float(Falloff, ActLight);
	integer Change = TRUE;
	if(msg == "Back")
	{
		if(Menu == LIGHT)
		{
			return;
		} else if(Menu == INTENS) LightMenu();
		else if(Menu == COLOR) IntensMenu();
		else if(Menu = BACKCOLOR) LightMenu();
		return;
	} else if(msg == " ")
	{
		if(Menu == LIGHT) LightMenu();
		else if(Menu == INTENS) IntensMenu();
		else if(Menu == COLOR) ColorMenu();
		return;
	} else if(llGetSubString(msg, 0, 4) == "Light")
	{
		ActLight = (integer)llGetSubString(msg, 6, 6);
		IntensMenu();
		return;
	} else if(msg == "On")
	{
		llSay(CHATCHANNEL, (string)ActLight+"|"+"On");
		ColorMenu();
		return;
	} else if(msg == "Off")
	{
		llSay(CHATCHANNEL, (string)ActLight+"|"+"Off");
		ColorMenu();
		return;
	} else if(msg == "Next")
	{
		Page++;
		TextMenu();
		return;
	} else if(msg == "Prev")
  {
		Page--;
		TextMenu();
		return;
	} else if(msg == "Background")
	{
		TextMenu();
		return;
	} else if(msg == "BackColor")
	{
		Menu = BACKCOLOR;
		ActLight = 0;
		ColorMenu();
		return;
	} else if(llListFindList(Textures, [msg]) != -1)
	{
		integer x = llListFindList(Textures, [msg]);
		llSay(CHATCHANNEL, "Back|"+llList2String(TexKeys, x));
		TextMenu();
		return;
	}
	else if(msg == "Color")
	{
		Menu = COLOR;
		ColorMenu();
		return;
	} if(msg == "Show") llSay(CHATCHANNEL, (string)ActLight+"|show");
	else if(msg == "Hide") llSay(CHATCHANNEL, (string)ActLight+"|hide");
	else if(msg == "Blue+") v.z += 0.05;
	else if(msg == "Blue-") v.z -= 0.05;
	else if(msg == "Red+") v.x += 0.05;
	else if(msg == "Red-") v.x -= 0.05;
	else if(msg == "Green+") v.y += 0.05;
	else if(msg == "Green-") v.y -= 0.05;
	else if(msg == "Intensity+") i += 0.05;
	else if(msg == "Intensity-") i -= 0.05;
	else if(msg == "Radius+") r += 1;
	else if(msg == "Radius-") r -= 1;
	else if(msg == "Falloff+") f += 0.05;
	else if(msg == "Falloff-") f -= 0.05;
	else Change = FALSE;
	if(Change)
	{
		v.x = Bound(v.x, 1);
		v.y = Bound(v.y, 1);
		v.z = Bound(v.z, 1);
		i = Bound(i, 1);
		r = (integer)Bound(r, 20);
		f = Bound(f, 1);
		Color = llListReplaceList(Color, [v], ActLight, ActLight);
		Intensity = llListReplaceList(Intensity, [i], ActLight, ActLight);
		Radius = llListReplaceList(Radius, [r], ActLight, ActLight);
		Falloff = llListReplaceList(Falloff, [f], ActLight, ActLight);
		llSay(CHATCHANNEL, (string)ActLight+"|"+(string)v+"|"+(string)i+"|"+(string)r+"|"+(string)f);
		if(Menu == INTENS) IntensMenu();
		else if(Menu == COLOR) ColorMenu();
		else if(Menu == BACKCOLOR) ColorMenu();
	}

Init()
{
	Color = [];
	Intensity = [];
	Radius = [];
	Falloff = [];
	integer i;
	for(i = 0; i <= MAXLIGHTS; i++)
	{
		Color += [<1,1,1>];
		Intensity += [0.75];
		Radius += [5];
		Falloff += [0.5];
	}
	GetTextures();
}

GetTextures()
{
	Textures = ["None"];
	TexKeys = ["5748decc-f629-461c-9a36-a35a221fe21f"];
	integer i;
	integer x = llGetInventoryNumber(INVENTORY_TEXTURE);
	for(i = 0; i < x; i++)
	{
		Textures += [llGetInventoryName(INVENTORY_TEXTURE, i)];
		TexKeys += [llGetInventoryKey(llGetInventoryName(INVENTORY_TEXTURE, i))];
	}
	Page = 0;
}

default
{
	state_entry()
	{
		Init();
	}
	changed(integer change)
	{
		if(change & CHANGED_INVENTORY) GetTextures();
	}
	touch_start(integer total_number)
	{
		User = llDetectedKey(0);
		llListenRemove(Listener);
		Listener = llListen(CHANNEL, "", User, "");
		LightMenu();
	}
	listen(integer channel, string name, key id, string message)
	{
		DoMenu(message);
	}
}
 

light.lsl


// script copyright by Rebekka Revnik

integer CHATCHANNEL = 55555;

vector v = <1,1,1>;
float i = 0.75;
integer r = 5;
float f = 0.75;

integer ON = TRUE;

default
{
	state_entry()
	{
		llListen(CHATCHANNEL, "", NULL_KEY, "");
	}
	listen(integer channel, string name, key id, string message)
	{
		list l = llParseString2List(message, ["|"], []);
		string s = "Light"+llList2String(l, 0);
		if(s != llGetObjectName()) return;
		if(llList2String(l, 1) == "hide") llSetAlpha(0, ALL_SIDES);
		else if(llList2String(l, 1) == "show") llSetAlpha(1, ALL_SIDES);
		else if(llList2String(l, 1) == "On")
		{
			llSetPrimitiveParams([PRIM_POINT_LIGHT, TRUE, v, i, r, f]);
			ON = TRUE;
		} else if(llList2String(l, 1) == "Off")
		{
			llSetPrimitiveParams([PRIM_POINT_LIGHT, FALSE, v, i, r, f]);
			ON = FALSE;
		} else
		{
			s = llList2String(l, 1);
			v = (vector)s;
			i = llList2Float(l, 2);
			r = llList2Integer(l, 3);
			f = llList2Float(l, 4);
			if(ON) llSetPrimitiveParams([PRIM_POINT_LIGHT, TRUE, v, i, r, f]);
			llSetColor(v, ALL_SIDES);
		}
	}
}

back.lsl


// script copyright by Rebekka Revnik

integer CHATCHANNEL = 55555;

vector v = <1,1,1>
float i = 0.75;
integer r = 5;
float f = 0.75;

integer ON = TRUE;

default
{
	state_entry()
	{
		llListen(CHATCHANNEL, "", NULL_KEY, "");
	}
	listen(integer channel, string name, key id, string message)
	{
		list l = llParseString2List(message, ["|"], []);
		string s = llList2String(l, 0);
		if(llList2String(l, 0) == "Back")
		{
			llSetTexture(llList2String(l, 1), 2);
			return;
		}
		if(s != "0") return;
		if(llList2String(l, 1) == "On")
		{
			llSetPrimitiveParams([PRIM_COLOR, 2, v, 1]);
			ON = TRUE;
		} else if(llList2String(l, 1) == "Off")
		{
			llSetPrimitiveParams([PRIM_COLOR, 2, <1,1,1>, 1]);
			ON = FALSE;
		} else
		{
			s = llList2String(l, 1);
			v = (vector)s;
			i = llList2Float(l, 2);
			r = llList2Integer(l, 3);
			f = llList2Float(l, 4);
			if(ON) llSetPrimitiveParams([PRIM_COLOR, 2, v, 1]);
		}
	}
}

stand new.lsl


// script copyright by Rebekka Revnik

// script copyright by Rebekka Revnik

vector SIT_POSITION = <0,0,1>;
rotation SIT_ROTATION = ZERO_ROTATION;

string TURNL = "<-";
string TURNR = "->";
list Anis;
integer Degree = 0;
vector Eul;
string CurAni;

string NEXT = ">>>";                        // Schaltflächen für vor und zurück
string PREV = "<<<";
integer DLGCHANNEL;                         // Chatkanal

integer DlgPage = 0;                        // aktuelle Seite - wird vom Skript verwendet
integer Listener;

key User;
key User1;

list DlgNice(list Dlg)
{
	list l = [];
	integer i;
	Dlg = [TURNL, TURNR] + Dlg;
	while(llGetListLength(Dlg) < 12) Dlg += [" "];
	integer ip = llListFindList(Dlg, [PREV]);
	integer in = llListFindList(Dlg, [NEXT]);
	if(in != -1)
	{
		Dlg = llDeleteSubList(Dlg, in, in);
		Dlg += [NEXT];
	}
	if(ip != -1)
	{
		Dlg = llDeleteSubList(Dlg, ip, ip);
		Dlg = llListInsertList(Dlg, [PREV], 9);
	}
	for(i = 0; i < 3; i++) l += llList2List(Dlg, i + 9, i + 9);
	for(i = 3; i < 6; i++) l += llList2List(Dlg, i + 3, i + 3);
	for(i = 6; i < 9; i++) l += llList2List(Dlg, i - 3, i - 3);
	for(i = 9; i < 12; i++) l += llList2List(Dlg, i - 9, i - 9);
	return l;
}

DlgShow(list DlgItems)
{
	list Dlg = [];
	integer Count = llGetListLength(DlgItems);
	integer Start = 0;
	if(DlgPage > 0) Start = (DlgPage - 1) * 8 + 9;
	integer End = Count - 1;
	if((End - Start) < 11) End = Start + 11;
	integer i;
	for(i = Start; i <= End; i++) Dlg += [(string)(i + 1)];
	string msg = "";
	if(DlgPage == 0)
	{
		if(Count Gt; 10) Dlg = llList2List(Dlg, 0, 1) + [NEXT] + llList2List(Dlg, 2, 8);
	} else
	{
		if(Count < Start + 9) Dlg = [PREV] + llList2List(Dlg, 0, 8);
		else Dlg = [PREV] + llList2List(Dlg, 0, 0) + [NEXT] + llList2List(Dlg, 1, 7);	
	}
	integer x = llGetListLength(Dlg);
	if(llListFindList(Dlg, [PREV]) != -1) x--;
	if(llListFindList(Dlg, [NEXT]) != -1) x--;
	for(Count = 0; Count < x; Count++)
	{
		msg += (string)(Start + Count + 1) + " - " + llList2String(DlgItems, Start + Count) + "\n";
	}
	llListenRemove(Listener);
	Listener = llListen(DLGCHANNEL, "", User1, "");
	llDialog(User1, msg, DlgNice(Dlg), DLGCHANNEL);
}

integer DlgMain(string msg)
{
	integer result = TRUE;
	if(msg == PREV)
	{
		DlgPage--;
		DlgShow(Anis);
		return result;
	} else if(msg == NEXT)
	{
		DlgPage++;
		DlgShow(Anis);
		return result;
	} else if(msg == " ")
	{
		DlgShow(Anis);
		return result;
	} else result = FALSE;
	return result;
}

Init()
{
	llSay(0, "Initialisiere..");
	Anis = [];
	CurAni = "";
	integer x = llGetInventoryNumber(INVENTORY_ANIMATION);
	integer i;
	for(i = 0; i < x; i++)
	{
		Anis += [llGetInventoryName(INVENTORY_ANIMATION, i)];
	}
	DLGCHANNEL = (integer) (-llFrand(1000) - 100);
	llSay(0, (string)llGetListLength(Anis) + " Posen geladen.");
}

default
{
	state_entry()
	{
		llSetSitText("Pose");
		llSitTarget(SIT_POSITION, SIT_ROTATION);
	}
	on_rez(integer start_param)
	{
		Init();
		rotation rot = llGetRot();
		Eul = llRot2Euler(rot);
		Eul *= RAD_TO_DEG;
		Eul.z = Degree;
		rot = llEuler2Rot(DEG_TO_RAD * Eul);
		llSetRot(rot);
	}
	touch_start(integer total_number)
	{
		User1 = llDetectedKey(0);
		llListenRemove(Listener);
		Listener = llListen(DLGCHANNEL, "", User1, "");
		llDialog(User1, "Was willst du tun", ["Reset", "Posen", "Ende"], DLGCHANNEL);
	}
	changed(integer change)
	{
		if(change & CHANGED_LINK)
		{
			User = llAvatarOnSitTarget();
			integer perm = llGetPermissions();
			if(User != NULL_KEY)
			{
				if(!(perm & PERMISSION_TRIGGER_ANIMATION))
				{
					llRequestPermissions(User, PERMISSION_TRIGGER_ANIMATION);
					return;
				}
				llSetAlpha(0, ALL_SIDES);
				CurAni = llList2String(Anis, 0);
				llStopAnimation("sit");
				llStartAnimation(CurAni);
				DlgPage = 0;
				DlgShow(Anis);
			} else
			{
				if (perm & PERMISSION_TRIGGER_ANIMATION) llStopAnimation(CurAni);
				llSetAlpha(1, ALL_SIDES);
			}
		}
	}
	listen(integer channel, string name, key id, string msg)
	{
		llListenRemove(Listener);
		if(DlgMain(msg)) return;
		if(msg == TURNL)
		{
			Degree = (Degree - 30) % 360;
			Eul.z = Degree;
			llSetRot(llEuler2Rot(DEG_TO_RAD * Eul));
			DlgShow(Anis);
			return;
		} else if(msg == TURNR)
		{
			Degree = (Degree + 30) % 360;
			Eul.z = Degree;
			llSetRot(llEuler2Rot(DEG_TO_RAD * Eul));
			DlgShow(Anis);
			return;
		} else if(msg == "Reset")
		{
			Init();
			return;
		} else if(msg == "Ende") return;
		else if(msg == "Posen")
		{
			DlgPage = 0;
			DlgShow(Anis);
		} else if((integer)msg > 0)
		{
			if(llAvatarOnSitTarget() != NULL_KEY)
			{
				integer x = (integer)msg;
				string s = llList2String(Anis, x-1);
				if(s != "")
				{
					if(CurAni != "") llStopAnimation(CurAni);
					llStartAnimation(s);
					CurAni = s;
				}
			}
			DlgShow(Anis);
			return;
		}
	}
	run_time_permissions(integer permissions)
	{
		if(permissions & PERMISSION_TRIGGER_ANIMATION)
		{
			llSetAlpha(0, ALL_SIDES);
			CurAni = llList2String(Anis, 0);
			llStopAnimation("sit");
			llStartAnimation(CurAni);
			DlgPage = 0;
			DlgShow(Anis);
		}
	}
}

stand old.lsl


// script copyright by Rebekka Revnik

vector SIT_POSITION = <0,0,1>;
rotation SIT_ROTATION = ZERO_ROTATION;

string TURNL = "<-";

string TURNR = "->";

list Anis;

list Anis1;

integer Degree = 0;

vector Eul;
string CurAni;

string NEXT = ">>>";						
string PREV = "<<<";
string DLGTITLE = "Drücke eine Taste..";	
integer DLGCHANNEL;							

list DlgItems = [];							
integer DlgPage = 0;						
integer Listener;

list DlgNice(list Dlg)
{
	list l = [];
	integer i;
	Dlg = [TURNL, TURNR] + Dlg;
	while(llGetListLength(Dlg) < 12) Dlg += [" "];
	integer ip = llListFindList(Dlg, [PREV]);
	integer in = llListFindList(Dlg, [NEXT]);
	if(in != -1)
	{
		Dlg = llDeleteSubList(Dlg, in, in);
		Dlg += [NEXT];
	}
	if(ip != -1)
	{
		Dlg = llDeleteSubList(Dlg, ip, ip);
		Dlg = llListInsertList(Dlg, [PREV], 9);
	}
	for(i = 0; i < 3; i++) l += llList2List(Dlg, i + 9, i + 9); 
	for(i = 3; i < 6; i++) l += llList2List(Dlg, i + 3, i + 3); 
	for(i = 6; i < 9; i++) l += llList2List(Dlg, i - 3, i - 3); 
	for(i = 9; i < 12; i++) l += llList2List(Dlg, i - 9, i - 9);
	return l;
}

DlgShow(string msg, integer channel)		
{
	list Dlg = [];
	integer Count = llGetListLength(DlgItems);
	integer Start = (DlgPage - 1) * 8 + 9;
	if(DlgPage == 0)
	{
		if(Count < 13) Dlg = DlgItems;
		else Dlg = llList2List(DlgItems, 0, 1) + [NEXT] + llList2List(DlgItems, 2, 8);
	} else
	{
		if(Count < Start + 10) Dlg = [PREV] + llList2List(DlgItems, Start, Start + 9);
		else Dlg = [PREV] + llList2List(DlgItems, Start, Start) + [NEXT] + llList2List(DlgItems, Start + 1, Start + 7);
	}
	llDialog(llGetOwner(), msg, DlgNice(Dlg), channel);
}

integer DlgMain(string msg)
{
	integer result = TRUE;
	if(msg == PREV)
	{
		DlgPage--;
		DlgShow(DLGTITLE, DLGCHANNEL);
		return result;
	} else if(msg == NEXT)
	{
		DlgPage++;
		DlgShow(DLGTITLE, DLGCHANNEL);
		return result;
	} else if(msg == " ")
	{
		DlgShow(DLGTITLE, DLGCHANNEL);
		return result;
	} else result = FALSE;
	return result;
}

Init()
{
	Anis = [];
	integer x = llGetInventoryNumber(INVENTORY_ANIMATION);
	integer i;
	for(i = 0; i < x; i++)
	{
		Anis += [llGetSubString(llGetInventoryName(INVENTORY_ANIMATION, i), 0, 23)];
		Anis1 += [llGetInventoryName(INVENTORY_ANIMATION, i)];
	}
	DLGCHANNEL = (integer) (-llFrand(1000) - 100);
	llOwnerSay((string)(llGetListLength(Anis) - 2) + " poses loaded.");
}

default
{
	state_entry()
	{
		llSetSitText("Pose");
		llSitTarget(SIT_POSITION, SIT_ROTATION);
	}
	on_rez(integer start_param)
	{
		Init();
		rotation rot = llGetRot();
		Eul = llRot2Euler(rot);
		Eul *= RAD_TO_DEG;
		Eul.z = Degree;
		rot = llEuler2Rot(DEG_TO_RAD * Eul);
		llSetRot(rot);
		integer perm = llGetPermissions();
		if (!(perm & PERMISSION_TRIGGER_ANIMATION)) llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
	}
	changed(integer change)
	{
		if(change & CHANGED_LINK)
		{
			integer perm = llGetPermissions();
			if(llAvatarOnSitTarget() != NULL_KEY)
			{
				llSetAlpha(0, ALL_SIDES);
				DlgItems = Anis;
				DLGTITLE = "Wähle eine Option";
				Listener = llListen(DLGCHANNEL, "", NULL_KEY, "");
				CurAni = llList2String(Anis1, 0);
				if (perm & PERMISSION_TRIGGER_ANIMATION)
				{
					llStopAnimation("sit");
					llStartAnimation(CurAni);
				}
				DlgPage = 0;
				DlgShow(DLGTITLE, DLGCHANNEL);
			} else
			{
				if (perm & PERMISSION_TRIGGER_ANIMATION) llStopAnimation(CurAni);
				llListenRemove(Listener);
				llSetAlpha(1, ALL_SIDES);
			}
		} else if(change & CHANGED_INVENTORY)
		{
			Init();
		}
	}
	listen(integer channel, string name, key id, string msg)
	{
		if(DlgMain(msg)) return;
		if(msg == TURNL)
		{
      Degree = (Degree - 30) % 360;
			Eul.z = Degree;
			llSetRot(llEuler2Rot(DEG_TO_RAD * Eul));
			DlgShow(DLGTITLE, DLGCHANNEL);
			return;
		} else if(msg == TURNR)
		{
			Degree = (Degree + 30) % 360;
			Eul.z = Degree;
			llSetRot(llEuler2Rot(DEG_TO_RAD * Eul));
			DlgShow(DLGTITLE, DLGCHANNEL);
			return;
		} else
		{
			integer i;
			integer x = llGetListLength(Anis1);
			string s = "";
			for(i = 0; i < x; i++)
			{
				if(llGetSubString(llList2String(Anis1, i), 0, 23) == msg) s = llList2String(Anis1, i);
			}
			if(s != "" && s != CurAni)
			{
				if(CurAni != "") llStopAnimation(CurAni);
				integer perm = llGetPermissions();
				if (perm & PERMISSION_TRIGGER_ANIMATION) llStartAnimation(s);
				CurAni = s;
			}
			DlgShow(DLGTITLE, DLGCHANNEL);
			return;
		}
	}
}