Difference between revisions of "User:Daemonika Nightfire/Scripts/Single Pose Sitter"

From Second Life Wiki
Jump to navigation Jump to search
Line 40: Line 40:
integer LinkTarget = LINK_THIS;
integer LinkTarget = LINK_THIS;
vector Position = <0.00, -0.00, 0.43>;
vector Position = <0.00, -0.00, 0.43>;
vector Rotation = <00, 00, 00>;
vector Rotation = <0, 0, 0>;


// Auswahl der Animationen inclusive individueller Vectoren.
// Auswahl der Animationen inclusive individueller Vectoren.
Line 49: Line 49:
integer avi_link;
integer avi_link;
vector avi_pos = <0,0,0.65>;
vector avi_pos = <0,0,0.65>;
vector avi_rot = <0,0,0>;
vector avi_rot = <0,0,90>;


// Menue mit dynamischen Channel.
// Menue mit dynamischen Channel.

Revision as of 00:12, 27 July 2024

*DS* Single Pose Sitter v5.0.03

Dieses Script ist das Ergebnis unseres Unterrichts. Es eignet sich ideal fuer einzelne Moebel die fuer 1 Avatar gedacht sind. Des weiteren verfuegt dieses Script ueber saemtliche bis dato aktuellen Funktionen, also es ist technich auf dem neusten Stand (Juli. 2024).

Das Format der Notecard um die Animationen zu verwalten sieht pro Zeile wiefolgt aus.
AnimationsName|VectorPosition|VectorRotation
Dazu trage jeweils einen Eintrag pro Zeile in die Notecard ein.

Warum haben wir uns bei der Rotation fuer den Vector entschieden?
Ganz einfach, den Vector kann man im freihant editieren und das Script rechnet es selbst in ein Quaternion um.
/*
    *DS* Single Pose Sitter by *DS* Script-Schule
    
    Single Pose bedeutet 1 Avatar pro Link_Set.
    Weitere Avatare mit zusaetzlichen Scripten werden nicht beruecksichtigt.
    Im Gegenteil, es kann zu irretationen fuerhren.
    
    Dieses Script kann bis zu 9 verschiedene Posen nutzen.
    Jede Pose kann individuell angepasst und gespeichert werden.
    Bei bedarf kann man die entsprechende Einstellung ebenfalls in die Notecard uebertragen.
    
    Es sind 9 Button-Namen fuer die jeweiligen Posen vorgegeben.
    Die Liste dieser Button passt sich automatisch der Anzahl Posen an.
    Werden also nur 2 Posen aus der notecard gelesen, erhaeltst du nur die Button [ one ] & [ two ].
*/

key owner;

// Notecard auslesen.
string nc_name = "posen";
key read_nc;

// Avatar Key, Status & Berechtigung.
key Avatar = "";
integer Sitting = FALSE;
integer Permission = FALSE;

// Grund-Einstellungen fuer den SitTarget.
integer LinkTarget = LINK_THIS;
vector Position = <0.00, -0.00, 0.43>;
vector Rotation = <0, 0, 0>;

// Auswahl der Animationen inclusive individueller Vectoren.
list button_index = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine"];
list posen = [];
string choice;
string Animation = "";
integer avi_link;
vector avi_pos = <0,0,0.65>;
vector avi_rot = <0,0,90>;

// Menue mit dynamischen Channel.
integer menu_handler;
integer menu_channel;
menu(key uuid, string title, list buttons)
{
    llListenRemove(menu_handler);
    menu_channel = (integer)(llFrand(1) * -DEBUG_CHANNEL);
    menu_handler = llListen(menu_channel,"","","");
    llDialog(uuid, title + "\nCurrent choice: [ " + choice + " ]", buttons, menu_channel);
    
    llSetTimerEvent(60);
}

// Anpassbare Vectoren fuers Einstellungs-Menue.
list pos_step_button = ["1cm", "5cm", "25cm"];
list pos_steps = [0.01, 0.05, 0.25];
integer pos_counter = 0;
float pos_step = 0.01;
postion_menu(key uuid)
{
    menu(uuid, "\nPositioning\n", ["Main",llList2String(pos_step_button, pos_counter),"Save","Pos x-","Pos y-","Pos z-","Pos x+","Pos y+","Pos z+"]);
}

list rot_step_button = ["1°","6°","30°"];
list rot_steps = [1.0, 6.0, 30.0];
integer rot_counter = 0;
float rot_step = 1.0;
rotation_menu(key uuid)
{
    menu(uuid, "\nOrientation\n", ["Main",llList2String(rot_step_button, rot_counter), "Save","Rot x-","Rot y-","Rot z-","Rot x+","Rot y+","Rot z+"]);
}

// Ausfuehrung der individuellen Vectoren.
string current_animation;
integer index = 0;
Change(key uuid)
{
    list parsed = llParseString2List(llList2String(posen, index), ["|"],[]);
    current_animation = llList2String(parsed, 0);
    avi_pos = (vector)llList2String(parsed, 1);
    avi_rot = (vector)llList2String(parsed, 2);
    
    llStartAnimation(current_animation);
    if(current_animation != Animation)
    {
        llStopAnimation(Animation);
    }
    Animation = current_animation;
    llSetLinkPrimitiveParamsFast(avi_link, [PRIM_POS_LOCAL, avi_pos, PRIM_ROT_LOCAL, llEuler2Rot(avi_rot * DEG_TO_RAD)]);
    menu(uuid, "\nChoose your options.\n", ["Position","Rotation","Close"] + button_index);
}


default
{
    state_entry()
    {
        owner = llGetOwner();
        llLinkSitTarget(LinkTarget, Position, llEuler2Rot(Rotation * DEG_TO_RAD));
        
        if(llGetInventoryNumber(INVENTORY_ANIMATION) > 0 && Animation == "")
        {
            Animation = llGetInventoryName(INVENTORY_ANIMATION, 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)
                {
                    // An dieser Stelle wird die Liste mit den 9 Button an die Laenge der Liste Posen angepasst.
                    // Hier wird lediglich jeder weitere unnoetige Button einfach geloescht.
                    integer bl = llGetListLength(posen);
                    button_index = llDeleteSubList(button_index, i, -1);
                    
                    choice = llList2String(button_index, 0);
                    llSay(0,"---EOF---\n" + (string)bl + " poses loaded.\n" + (string)llGetUsedMemory() + " bytes memory in use.");
                }
                else
                {
                    if(line != "")
                    {
                        posen += line;
                    }
                }
            }
            while(++i <= count);
        }
    }
    
    touch_start(integer total_number)
    {
        key agent = llDetectedKey(0);
        if(agent == Avatar)
        {
            menu(agent, "\nChoose your options.\n", ["Position","Rotation","Close"] + button_index);
        }
    }
    
    listen(integer channel, string name, key id, string message)
    {
        list temp = llParseString2List(message, [" "], []);
        string cmd = llList2String(temp, 0);
        string data = llList2String(temp, 1);
        
        if(cmd == "Close")
        {
            llSetTimerEvent(0.0);
            llListenRemove(menu_handler);
        }
        else if(cmd == "Main")
        {
            menu(id, "\nChoose your options.\n", ["Position","Rotation","Close"] + button_index);
        }
        else if(~llListFindList(button_index, [cmd]))
        {
            integer i = llListFindList(button_index, [cmd]);
            if(i != -1)
            {
                index = i;
                choice = cmd;
                Change(id);
            }
        }
        
        // Positions-Einstellungen
        else if(cmd == "Position")
        {
            postion_menu(id);
        }
        else if(~llListFindList(pos_step_button, [cmd]))
        {
            pos_counter++;
            if(pos_counter == llGetListLength(pos_steps))
            {
                pos_counter = 0;
            }
            pos_step = llList2Float(pos_steps, pos_counter);
            postion_menu(id);
        }
        else if(cmd == "Pos")
        {
            if(data == "x-")      { avi_pos.x -= pos_step; }
            else if(data == "x+") { avi_pos.x += pos_step; }
            else if(data == "y-") { avi_pos.y -= pos_step; }
            else if(data == "y+") { avi_pos.y += pos_step; }
            else if(data == "z-") { avi_pos.z -= pos_step; }
            else if(data == "z+") { avi_pos.z += pos_step; }
            
            llSetLinkPrimitiveParamsFast(avi_link, [PRIM_POS_LOCAL, avi_pos, PRIM_ROT_LOCAL, llEuler2Rot(avi_rot * DEG_TO_RAD)]);
            postion_menu(id);
        }
        
        // Rotations-Einstellungen
        else if(cmd == "Rotation")
        {
            rotation_menu(id);
        }
        else if(~llListFindList(rot_step_button, [cmd]))
        {
            rot_counter++;
            if(rot_counter == llGetListLength(rot_steps))
            {
                rot_counter = 0;
            }
            rot_step = llList2Float(rot_steps, rot_counter);
            rotation_menu(id);
        }
        else if(cmd == "Rot")
        {
            if(data == "x-")      { avi_rot.x -= rot_step; }
            else if(data == "x+") { avi_rot.x += rot_step; }
            else if(data == "y-") { avi_rot.y -= rot_step; }
            else if(data == "y+") { avi_rot.y += rot_step; }
            else if(data == "z-") { avi_rot.z -= rot_step; }
            else if(data == "z+") { avi_rot.z += rot_step; }
            
            llSetLinkPrimitiveParamsFast(avi_link, [PRIM_POS_LOCAL, avi_pos, PRIM_ROT_LOCAL, llEuler2Rot(avi_rot * DEG_TO_RAD)]);
            rotation_menu(id);
        }
        
        // Speichern der Einstellungen
        else if(cmd == "Save")
        {
            string store = Animation + "|" + (string)avi_pos + "|" + (string)avi_rot;
            posen = llListReplaceList(posen, [store], index, index);
            if(id == owner)
            {
                llOwnerSay("Insert the following line into the notecard or replace it.\n" + store);
            }
        }
    }
    
    changed(integer Change)
    {
        if(Change & CHANGED_LINK)
        {
            if(!Sitting)
            {
                Avatar = llAvatarOnLinkSitTarget(LinkTarget);
                if(Avatar)
                {
                    Sitting = TRUE;
                    integer prims = llGetNumberOfPrims();
                    integer i = 0;
                    do
                    {
                        string name = llGetLinkName(i);
                        if(name == llKey2Name(Avatar))
                        {
                            avi_link = i;
                        }
                    }
                    while(++i <= prims);
                    
                    if(Animation != "")
                    {
                        llRequestPermissions(Avatar, PERMISSION_TRIGGER_ANIMATION);
                    }
                }
            }
            else if(Sitting)
            {
                if(Permission)
                {
                    if(llKey2Name(Avatar) != "")
                    {
                        llStopAnimation(Animation);
                    }
                    Permission = FALSE;
                }
                Sitting = FALSE;
                Avatar = "";
            }
        }
        else if(Change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }
    
    run_time_permissions(integer Permission)
    {
        if(Permission & PERMISSION_TRIGGER_ANIMATION)
        {
            llStopAnimation("sit_generic");
            llStopAnimation("sit");
            Change(Avatar);
        }
    }
    
    timer()
    {
        llSetTimerEvent(0.0);
        llListenRemove(menu_handler);
    }
    
    on_rez(integer Dae)
    {
        llResetScript();
    }
}