GridTalk.de

Normale Version: AO für OpenSim
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Neulich hatte ich nach einem AO gesucht und auch von Freunden welche bekommen. Die haben auch funktioniert, nur waren die eben entweder no Mod oder es war nicht alles drin was ich mir gewünscht hätte. Also hab ich kurzerhand einen eigenen AO geskriptet (was ich eigentlich vermeiden wollte). Dabei ist auch gleich noch ein Tanzball- und ein Poledance-Skript rausgekommen, aber das später. Hier ist nun der Extrakt.

Kurzbeschreibung: Der AO überschreibt die Animationen in 26 Kategorien inklusive Typing. Ausserdem sind auch Tänze als 27. Kategorie vorhanden. Es gibt keine Beschränkung in der Anzahl der Animationen, allerdings sind mehrere nur in einigen Kategorien sinnvoll. Zudem sollte es auch in No-Script-Zonen funktionieren, aber beim Test auf Wright Plaza gings trotzdem nicht. Das control Event verhält sich wohl im OS anders als in SL.
Achja das Skript ist nur für OpenSim geeignet, aber mit kleinen Änderungen geht es auch in SL. Ich habs ins Skript geschrieben wo.

Bei Reset liest das Skript eine Notecard namens config ein. Dort müssen die Animationen in der Form

AnimType = Typ der Animation (zB Walking)
Animation 1
Animation 2
...

eingetragen werden (Beispiel weiter unten). Es können pro Animationstyp so viele Animationen eingetragen werden wie gewünscht (keine Beschränkung auf 12 pro Typ), allerdings kann man nur bei Walks, Stands, Sits, Groundsits und Tänzen auswählen, bei allen anderen wird einfach die letzte genommen. Natürlich müssen die Animationen auch im Objekt sein, sonst gibts eine Meldung. Wenn in einer Kategorie nichts steht passiert auch nichts.
Für den AO selber hab ich einfach zwei Prims zusammengelinkt und Texturen für Ein/Aus bzw. das Menü aufgebracht bzw. hineingelegt. Die Texturen hab ich von Marg's AO, dort liegen sie Full Perm drin.
Im Hauptmenü kann man in die einzelnen Untermenüs verzweigen sowie sich auf den Boden setzen oder wieder aufstehen. Im Optionsmenü wird die Zeit für die Stands eingestellt und Art der Wechsel der Stands (nur einen Stand, der Reihe nach oder zufällig). Ausserdem kann man das Sitzen ein- bzw ausschalten. In allen anderen Menüs wählt man die entsprechende Animation.
Der AO wird ans HUD an Bottom Right angehängt und verschiebt sich in den sichtbaren Bereich. Bei anderen Punkten muss man ihn verschieben oder den Wert von LocalPos im Skript ändern.
Leider kann ich mein eigenes AO nicht weitergeben, weil die Animationen No Trans sind (ok ein leeres vielleicht). Dafür gibts das Skript umsonst :-)
Viel Spass

Code:
string CAT = "AnimType";                    // Kennzeichnugn für Kategorie in der NC
integer LinkOn = 1;                            // Linknummer zum Ein/Ausschalten
integer LinkMenu = 2;                        // LinkNummer fürs Menü
string TextureOff = "Button.Off";            // Textur wenn der AO aus ist
string TextureOn = "Button.On";                // Textur wenn der AO an ist
vector LocalPos = <0.000000,0.058893,0.126620>;    // Verschiebung bei Anhängen an Bottom Right

list AnimTypes = ["Sitting on Ground", "Sitting", "Striding", "Crouching", "CrouchWalking",
"Soft Landing", "Standing Up", "Falling Down", "Hovering Down", "Hovering Up",
"FlyingSlow", "Flying", "Hovering", "Jumping", "PreJumping", "Running",
"Turning Right", "Turning Left", "Walking", "Landing", "Standing",
"Swimming Down", "Swimming Up", "Swimming Forward", "Floating", "Typing",
"Dance"];

// Variablen und Konstanten für die NC
string NCNAME = "config";                    // Name der Notecard
integer NCLine;                                // die aktuelle Zeile der NC
key NCid;                                    // Kennung der NC
integer State;                                // Abschnitt beim Einlesen
integer Count;                                // Anzahl der gelesenen Anis

// Variablen und Konstanten fürs Animieren
list Stands;                                // Liste der Stand-Anis
list Sits;                                    // Liste der Sitz-Anis
list Walks;                                    // Liste der Walk-Anis
list GroundSits;                            // Liste der Groundsits
list Dances;                                // Liste der Tänze
list Anims;                                    // Liste der Animationen (einer pro Typ)

integer StandTime = 40;                        // Dauer bis zur nächsten Stand-Ani
integer StandType = 2;                        // 0 = fest, 1 = nacheinander, 2 = zufällig
integer CurAnimType;                        // der Typ der aktuellen Animation
string CurAni;                                // der Name der aktuellen Animation
integer SitAlways = FALSE;                    // Sitzen überschreiben
integer TempType;                            // zum Wiederherstellen nach Tippseln
string TempAni;                                // zum Wiederherstellen anch Tippseln

integer On;                                    // HUD ein oder aus
float TIME = 0.25;                            // Zeit für Timer

// Variablen und Konstanten fürs Menü
string NEXT = ">>>";                        // Schaltflächen für vor und zurück
string PREV = "<<<";
string DlgTitle;                            // Dialog-Text
integer DlgChannel;                             // Chatkanal
list DlgItems = [];                             // die Schaltflächen des Dialogs
integer DlgPage = 0;                        // aktuelle Seite - wird vom Skript verwendet
integer DlgType = -1;                        // das aktuelle Menü
integer Listener;                            // ID für den Kanal
integer DlgNo = FALSE;                        // wenn TRUE, Anzeige mit Zahlen auf den Tasten

// allgemeines Menü
Menu()
{
    list l = ["Ende"];
    if(DlgType > 1) l += ["Zurück"];
    if(DlgType == 7) l += ["Stop"];
    list l1;
    list l2;
    integer x = llGetListLength(DlgItems);
    integer len1 = 12 - llGetListLength(l);
    integer len2 = len1 - 1;
    integer len3 = len2 - 1;
    integer start = (DlgPage - 1) * len3 + len2;
    if(DlgPage == 0)
    {
        start = 0;
        if(x <= len1) l2 = l + llList2List(DlgItems, 0, len2);
        else
        {
            l2 = l + llList2List(DlgItems, 0, len3);
            l2 = llListInsertList(l2, [NEXT], 2);
        }
    } else
    {
        llSay(0, (string)(x - start + llGetListLength(l)));
        if((x - start + llGetListLength(l)) < 12)
        {
            l2 = l + llList2List(DlgItems, start, start + len3);
            l2 = llListInsertList(l2, [PREV], 0);
        } else
        {
            l2 = l + llList2List(DlgItems, start, start + len3 - 1);
            l2 = llListInsertList(l2, [NEXT], 2);
            l2 = llListInsertList(l2, [PREV], 0);
        }
    }
    l1 = [];
    x = 0;
    string s;
    string s1 = "";
    integer i;
    if(DlgNo)
    {
        for(i = 0; i < llGetListLength(l2); i++)
        {
            s = llList2String(l2, i);
            if(llListFindList(l, [s]) != -1 || s == NEXT || s == PREV) l1 += [s];
            else
            {
                l1 += [++start];
                s1 += (string)start + " - " + s +"\n";
            }
        }
    } else l1 = l2;
    llListenRemove(Listener);
    Listener = llListen(DlgChannel, "", llGetOwner(), "");
    llDialog(llGetOwner(), DlgTitle + "\n" + s1, l1, DlgChannel);
}

// allgemeine Menüprozedur
integer DlgMain(string msg)
{
    llListenRemove(Listener);
    if(msg == PREV)
    {
        DlgPage--;
        Menu();
        return TRUE;
    } else if(msg == NEXT)
    {
        DlgPage++;
        Menu();
        return TRUE;
    } else if(msg == " ")
    {
        Menu();
        return TRUE;
    }
    else return FALSE;
}

// Hauptmenü
Menu1()
{
    DlgItems = ["Reset", "Optionen", "Hinsetzen", "Dance", "Stands", "Walks", "Sits", "Groundsits"];
    if(CurAnimType == 0) DlgItems = llListReplaceList(DlgItems, ["Aufstehen"], 2, 2);
    DlgTitle = "Wähle eine Kategorie:";
    DlgType = 1;
    DlgPage = 0;
    DlgNo = FALSE;
    Menu();
}

// Optionsmenü
Menu2()
{
    DlgItems = ["Stand 20s", "Stand 40s", "Stand 60s", "Stand 80s", "Stand 100s"];
    DlgItems += ["Zufällig", "Reihe", "Fest"];
    if(SitAlways) DlgItems += ["Sitzen aus"]; else DlgItems += ["Sitzen an"];
    DlgTitle = "Standzeit: " + (string)StandTime + " s\nWiederholung: ";
    if(StandType == 0) DlgTitle += "Fest";
    else if(StandType == 1) DlgTitle += "Nacheinander";
    else if(StandType == 2) DlgTitle += "Zufällig";
    DlgTitle += "\nImmer Sitzen: ";
    if(SitAlways) DlgTitle += "an\n"; else DlgTitle += "aus\n";
    DlgTitle += "Wähle eine Option:";
    DlgType = 2;
    DlgPage = 0;
    DlgNo = FALSE;
    Menu();
}

// Menü für Stands
Menu3()
{
    DlgItems = Stands;
    DlgTitle = "Wähle einen Stand\nAktueller Stand: " + llList2String(Anims, 20);
    DlgType = 3;
    DlgPage = 0;
    DlgNo = TRUE;
    Menu();
}

// Menü für Walks
Menu4()
{
    DlgItems = Walks;
    DlgTitle = "Wähle einen Walk:\nAktueller Walk: " + llList2String(Anims, 18);
    DlgType = 4;
    DlgPage = 0;
    DlgNo = TRUE;
    Menu();
}

// Menü für Sits
Menu5()
{
    DlgItems = Sits;
    DlgTitle = "Wähle einen Sit:\nAktueller Sit: " + llList2String(Anims, 1);
    DlgType = 5;
    DlgPage = 0;
    DlgNo = TRUE;
    Menu();
}

// Menü für Groundsits
Menu6()
{
    DlgItems = GroundSits;
    DlgTitle = "Wähle einen Groundsit:\nAktueller Groundsit: " + llList2String(Anims, 0);
    DlgType = 6;
    DlgPage = 0;
    DlgNo = TRUE;
    Menu();
}

// Menü für Tänze
Menu7()
{
    DlgItems = Dances;
    DlgTitle = "Wähle einen Tanz:";
    DlgType = 7;
    DlgPage = 0;
    DlgNo = TRUE;
    Menu();
}

// Verarbeitung einer Zeile aus der config
ReadNCLine(string s)
{
    list l = llParseString2List(s, ["="], []);
    s = llStringTrim(llList2String(l, 0), STRING_TRIM);
    if(llToLower(s) == llToLower(CAT))
    {
        s = llStringTrim(llList2String(l, 1), STRING_TRIM);
        integer x = llListFindList(AnimTypes, [s]);
        if(x != -1) State = x;
    } else if(State != -1)
    {
        if(s != "")
        {
            Count++;
            if(State == 0) GroundSits += [s];
            else if(State == 1) Sits += [s];
            else if(State == 18) Walks += [s];
            else if(State == 20) Stands += [s];
            else if(State == 26) Dances += [s];
            Anims = llListReplaceList(Anims, [s], State, State);
            if(llGetInventoryType(s) != INVENTORY_ANIMATION) llOwnerSay("Warnung: Animation " + s + " nicht gefunden.");
        }
    }
    NCid = llGetNotecardLine(NCNAME, NCLine++);
}

//Initialisierung
Init()
{
    integer i;
    SetOff();
    Anims = [];
    GroundSits = [];
    Sits = [];
    Walks = [];
    Stands = [];
    Dances = [];
    CurAnimType = -1;
    CurAni = "";
    State = -1;
    for(i = 0; i < llGetListLength(AnimTypes); i++) Anims += [""];
    DlgChannel = -((integer)llFrand(9999999) - 99999);
}

// startet eine Animation
StartAni(integer Type, string Name)
{
    string s = CurAni;
    CurAni = "";
    if(Type == 1 && !SitAlways)
    {
        CurAnimType = 1;
        return;
    }
    if((Type == 16 || Type == 17) && Name == "") Name = llList2String(Anims, 20);
    else if(Type == 2 && Name == "") Name = llList2String(Anims, 18);        // Striding = Walking
    else if(Type == 5 && Name == "") Name = llList2String(Anims, 19);        // Soft Landing = Landing
    else if(Type == 4 && Name == "") Name = llList2String(Anims, 3);        // Crouch Walking = Crouching
    if(Name != "")
    {
        if(s != "")
        {
            llStopAnimation(s);
            llSleep(0.1);
        }
        llStartAnimation(Name);
        CurAni = Name;
    }
    CurAnimType = Type;
    if(Type == 20 && StandType != 0) llResetTime();
}

// startet den nächsten Stand
NextStand()
{
    string s = llList2String(Anims, 20);
    integer x = llListFindList(Stands, [s]);
    if(StandType == 1)
    {
        x = ++x % llGetListLength(Stands);
    } else if(StandType == 2)
    {
        if(llGetListLength(Stands) > 1)
        {
            do
            {
                x = (integer)llFrand(llGetListLength(Stands));
            } while(llList2String(Stands, x) == s);
        }
    }
    s = llList2String(Stands, x);
    Anims = llListReplaceList(Anims, [s], 20, 20);
    StartAni(20, s);
}

// AO an
SetOn()
{
    On = TRUE;
    llSetLinkTexture(LinkOn, TextureOn, ALL_SIDES);
    CurAni = llGetAnimation(llGetOwner());
    integer x = llListFindList(AnimTypes, [CurAni]);
    StartAni(x, llList2String(Anims, x));
    llSetTimerEvent(TIME);
}

// AO aus
SetOff()
{
    llSetLinkTexture(LinkOn, TextureOff, ALL_SIDES);
    On = FALSE;
    if(CurAni != "") llStopAnimation(CurAni);
    llSetTimerEvent(0.0);
}

default
{
    state_entry()
    {
        Init();
        state readnc;
    }
}

state readnc
{
    state_entry()
    {
        NCLine = 0;
        Count = 0;
        if(llGetInventoryType(NCNAME) != INVENTORY_NOTECARD)
        {
            llOwnerSay("Keine config vorhanden. Angehalten.");
        } else
        {
            NCid = llGetNotecardLine(NCNAME, NCLine++);
            llOwnerSay("Lese config...");
        }
    }
    dataserver(key requested, string data)
    {
        if(requested == NCid)
        {
            if(data != EOF)
            {
                ReadNCLine(data);
            } else
            {
                llOwnerSay((string)Count + " Animationen gelesen.");
                state running;
            }
        }
    }
}

state running
{
    state_entry()
    {
        Listener = llListen(DlgChannel, "", NULL_KEY, "");
        if(llGetAttached()) llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
    }
    run_time_permissions(integer permissions)
    {
        if(permissions & PERMISSION_TAKE_CONTROLS) llTakeControls(CONTROL_BACK|CONTROL_FWD, TRUE, TRUE);
    }
    changed(integer change)
    {
        if(change & CHANGED_INVENTORY) llResetScript();
        // folgender Block gilt nur für OpenSim
        // für SL bitte löschen
        if(change & CHANGED_ANIMATION)
        {
            if(!On) return;
            string s = llGetAnimation(llGetOwner());
            integer x = llListFindList(AnimTypes, [s]);
            if(x != CurAnimType && x != -1) StartAni(x, llList2String(Anims, x));
        }
        // Blockende
        if(change & CHANGED_TELEPORT) NextStand();
    }
    attach(key attached)
    {
        if(attached != NULL_KEY)
        {
            llSetPos(LocalPos);
            llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
        }
    }
    timer()
    {
        if(!On) return;
        integer x = llGetAgentInfo(llGetOwner()) & AGENT_TYPING;
        if(x != 0)
        {
            if(CurAnimType != 25 && CurAnimType != 26)
            {
                TempAni = CurAni;
                TempType = CurAnimType;
                StartAni(25, llList2String(Anims, 25));
            }
        } else if(CurAnimType == 25) StartAni(TempType, TempAni);

        else if(llGetTime() >= StandTime)
        {
            if(CurAnimType == 20) NextStand();
            else llResetTime();
        }
        // für SL hier die Kommentarstriche entfernen
        //string s = llGetAnimation(llGetOwner());
        //integer x = llListFindList(AnimTypes, [s]);
        //if(x != CurAnimType) StartAni(x, llList2String(Anims, x));
    }
    touch_start(integer total_number)
    {
        integer x = llDetectedLinkNumber(0);
        if(x == LinkMenu) Menu1();
        else if(x == LinkOn)
        {
            if(On) SetOff(); else SetOn();
        }
    }
    listen(integer channel, string name, key id, string message)
    {
        if(DlgMain(message)) return;
        string s;
        if(DlgType == 1)
        {
            if(message == "Reset") llResetScript();
            else if(message == "Ende") return;
            else if(message == "Optionen")
            {
                Menu2();
                return;
            } else if(message == "Stands")
            {
                Menu3();
                return;
            } else if(message == "Walks")
            {
                Menu4();
                return;
            } else if(message == "Sits")
            {
                Menu5();
                return;
            } else if(message == "Groundsits")
            {
                Menu6();
                return;
            } else if(message == "Dance")
            {
                Menu7();
                return;
            } else if(message == "Hinsetzen")
            {
                StartAni(0, llList2String(Anims, 0));
                Menu1();
                return;
            } else if(message == "Aufstehen")
            {
                llStopAnimation(CurAni);
                CurAni = "";
                CurAnimType = -1;
                NextStand();
                Menu1();
                return;
            }
        } else if(DlgType == 2)
        {
            if(message == "Ende") return;
            else if(message == "Zurück")
            {
                Menu1();
                return;
            } else if(message == "Stand 20s") StandTime = 20;
            else if(message == "Stand 40s") StandTime = 40;
            else if(message == "Stand 60s") StandTime = 60;
            else if(message == "Stand 80s") StandTime = 80;
            else if(message == "Stand 100s") StandTime = 100;
            else if(message == "Zufällig") StandType = 2;
            else if(message == "Reihe") StandType = 1;
            else if(message == "Fest") StandType = 0;
            else if(message == "Sitzen an")
            {
                SitAlways = TRUE;
                if(CurAnimType == 1) StartAni(1, llList2String(Anims, 1));
            } else if(message == "Sitzen aus")
            {
                SitAlways = FALSE;
                if(CurAnimType == 1 && CurAni != "")
                {
                    llStopAnimation(CurAni);
                    CurAni = "";
                    llStartAnimation("sit");
                }
            }
            Menu2();
            return;
        } else if(DlgType == 3)
        {
            if(message == "Ende") return;
            else if(message == "Zurück")
            {
                Menu1();
                return;
            }
            s = llList2String(Stands, (integer)message - 1);
            if(s != "") Anims = llListReplaceList(Anims, [s], 20, 20);
            if(CurAnimType == 20) StartAni(20, s);
            Menu3();
            return;
        } else if(DlgType == 4)
        {
            if(message == "Ende") return;
            else if(message == "Zurück")
            {
                Menu1();
                return;
            }
            s = llList2String(Walks, (integer)message - 1);
            if(s != "") Anims = llListReplaceList(Anims, [s], 18, 18);
            if(CurAnimType == 18) StartAni(18, s);
            Menu4();
            return;
        } else if(DlgType == 5)
        {
            if(message == "Ende") return;
            else if(message == "Zurück")
            {
                Menu1();
                return;
            }
            s = llList2String(Sits, (integer)message - 1);
            if(s != "") Anims = llListReplaceList(Anims, [s], 1, 1);
            if(CurAnimType == 1) StartAni(1, s);
            Menu5();
            return;
        } else if(DlgType == 6)
        {
            if(message == "Ende") return;
            else if(message == "Zurück")
            {
                Menu1();
                return;
            }
            s = llList2String(GroundSits, (integer)message - 1);
            if(s != "") Anims = llListReplaceList(Anims, [s], 0, 0);
            if(CurAnimType == 0) StartAni(0, s);
            Menu6();
            return;
        } else if(DlgType == 7)
        {
            if(message == "Ende") return;
            else if(message == "Zurück")
            {
                Menu1();
                return;
            } else if(message == "Stop")
            {
                if(CurAnimType == 26)
                {
                    llStopAnimation(CurAni);
                    CurAni = "";
                    CurAnimType = -1;
                    NextStand();
                }
            } else
            {
                s = llList2String(Dances, (integer)message - 1);
                if(s != "") Anims = llListReplaceList(Anims, [s], 26, 26);
                StartAni(26, s);
                Menu7();
                return;
            }
        }
    }
    control(key id, integer levels, integer edges)
    {
        if(!On) return;
        if(edges && llGetAnimation(llGetOwner()) == "Walking")
        {
            if(levels & edges & (CONTROL_BACK | CONTROL_FWD))
            {
                if(llGetListLength(Walks) > 0)
                {
                    llStopAnimation("walk");
                    llStopAnimation("female_walk");
                }
            }
            StartAni(18, llList2String(Anims, 18));
        }
    }
}
Beispiel-config:
Code:
AnimType = Sitting on Ground
GSitShy

AnimType = Sitting
sitShy1
sitshy2

AnimType = Striding

AnimType = Crouching
crouchshy

AnimType = CrouchWalking

AnimType = Soft Landing
AnimType = Standing Up

AnimType = Falling Down

AnimType = Hovering Down
HoverD

AnimType = Hovering Up
HoverU

AnimType = FlyingSlow

AnimType = Flying
FlyShy

AnimType = Hovering
Hover

Animtype = Jumping
jumP

Animtype = PreJumping
Prejump

AnimType = Running
runf
runfist

AnimType = Turning Right
TURNR

AnimType = Turning Left
TURNL

Animtype = Walking
sexywalk
walk_bis
walk 3

AnimType = Landing
LandingF

Animtype = Standing
stand1
stand2
stand2-2
stand3
stand4
stand4-4
stand6
stand7
stand8-1
stand10
standingf
stand14
stand14-1
stand17
stand17-1

AnimType = Swimming Down

AnimType = Swimming Up

AnimType = Swimming Forward
swimF

AnimType = Floating
float

Animtype = Typing
ftyping

AnimType = Dance
Butterscotch
we love you girl
weeeee
Danke für den hilfreichen Thread,RebekkaSmile
Hab das Skript noch mal leicht geändert, damit bei eigenen Tänzen die Tippsel-Ani nicht dazwischen funkt.