Jump to content

Linkset script spams me


ChaosRaine
 Share

You are about to reply to a thread that has been inactive for 3571 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I'm trying to add

string lay = llGetInventoryName(INVENTORY_TEXTURE, 0);
llSetLinkAlpha(2, 0.0, ALL_SIDES);
llSetLinkAlpha(1, 1.0, ALL_SIDES);
llSetLinkAlpha(3, 1.0, ALL_SIDES);
llSetLinkTexture(1,lay,ALL_SIDES);

when a avatar is not seated on a prim and

string stand = llGetInventoryName(INVENTORY_TEXTURE, 1);
llSetLinkAlpha(2, 1.0, ALL_SIDES);
llSetLinkAlpha(1, 1.0, ALL_SIDES);
llSetLinkAlpha(3, 0.0, ALL_SIDES);
llSetLinkTexture(1,stand,ALL_SIDES);

When they are. I ended up with this script

string  HelperName  = "Sit Target Helper 3b";

list    Anims;              // names of anims in object's inventory
integer AnimNum;            // index of current anim
string  LastAnim;           // anim last sitter used
key     LastAv;             // av who sat, just a guard
rotation OrigRotation;      // rotation to return seat to, when av stands
integer Rotating;           // whether rotating seat

integer MenuChan;

list Buttons = [
      "SET"
    , "DONE"
    ];

// Return a channel number that's based on the prim's key -- unique per object
integer channel() {
    return (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1));
}

do_menu(key id) {
    llDialog(id,
          "Choose SET to set the sit target.  Then test."
        + "\nChoose DONE when you're happy."
        + "\nTo change the target later, reset the script."
        + "\n(e.g., select, and Tools -> Reset scripts in selection)",
        Buttons,
        MenuChan);
}
          
do_sensor() {
     // Find the helper
     llSensor(HelperName, NULL_KEY, ACTIVE|PASSIVE, 20, PI);
     llSay(0, "Searching for '" + HelperName + "'");
}

// Collect the set of anims in this prim

get_anims()
{
    integer ix;
    string  anim;

    llUnSit(llAvatarOnSitTarget());    
    Anims = [];

    for (ix = 0; TRUE; ix++) {

        anim = llGetInventoryName(INVENTORY_ANIMATION, ix);
        if (anim == "") {
            llWhisper(0, (string)llGetListLength(Anims) + " animations");
            return;
        }
        Anims += [anim];
    }
}


// Start the animation given by ordinal number

integer start_anim(integer ix) {
    integer numAnims = llGetListLength(Anims);
    key     id = llAvatarOnSitTarget();

    list anims = llGetAnimationList(id);
    integer jx;
    for (; jx < llGetListLength(anims); ++jx) {
        llStopAnimation(llList2String(anims, jx));
    }


    if (numAnims > 0) {
        string anim = llList2String(Anims, ix);

        llStartAnimation(anim);

        // If this is the first we've seen of this av, stop default sits
        if (LastAv == NULL_KEY) {
            llStopAnimation("sit");
            llStopAnimation("sit_generic");
            llStopAnimation("sit_female");
        }
        LastAnim = anim;
        LastAv = id;
    }

    return (numAnims > 1);
}


// Start the next anim in inventory

next_anim()
{
    AnimNum++;
    if (AnimNum >= llGetListLength(Anims)) {
        AnimNum = 0;
    }
    start_anim(AnimNum);
}


// Start the previous anim in inventory

prev_anim()
{
    AnimNum--;
    if (AnimNum < 0) {
        AnimNum = llGetListLength(Anims) - 1;
    }
    start_anim(AnimNum);
}


// Rotate the stool by the given angle

rotate(float amt)
{
  rotation rot = llGetRot();
  rotation r = llEuler2Rot(<0,0,amt * DEG_TO_RAD>);
  llSetRot(rot * r);
}


// React to an arrow or shift-arrow key

handle_control(integer level, integer change) {

    key     id = llAvatarOnSitTarget();

    if (level & CONTROL_RIGHT) {
        next_anim();
        llInstantMessage(id, LastAnim);
    } else if (level & CONTROL_LEFT) {
        prev_anim();
        llInstantMessage(id, LastAnim);
    } else if (level & CONTROL_ROT_LEFT) {
        rotate(-15.0);
    } else if (level & CONTROL_ROT_RIGHT) {
        rotate(15.0);
    }        
}


// Calculate the sit target, compensating for the known bug
// Big thanks to Lex Neva for this!

calc_sit_target()
{

    vector   helper_pos = llDetectedPos(0);
    rotation helper_rot = llDetectedRot(0);
    
    vector   my_pos = llGetPos();
    rotation my_rot = llGetRot();
    
    // calculate where the avatar actually is
    vector avatar_pos = helper_pos + <0.,0.,.01> * helper_rot; // due to helper's sit target
    avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target
    
    vector target_pos = (avatar_pos - my_pos) / my_rot;
    target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target
    rotation target_rot = helper_rot / my_rot;
    
    llSitTarget(target_pos, target_rot);
    llSay(0, "llSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");");
}


upgrade() {
    string me   = llGetScriptName();
    string name = "Sit Target Setter";
    integer n = llGetInventoryNumber(INVENTORY_SCRIPT);
    while (n-- > 0) {        
        string item = llGetInventoryName(INVENTORY_SCRIPT, n);
        if (item != me && 0 == llSubStringIndex(item, name)) {
            llOwnerSay("removing old script: " + item);
            llRemoveInventory(item);
        }
    }
}

default
{
    state_entry() {
        
        upgrade();
        state s_setting;
    }
}

// Sit-target setting mode
// On click, show menu.  On "SHOW", set the sit target.  On "DONE", go to furniture mode.
// Might be a good idea to disallow to simplify and avoid user mistakes.

state s_setting
{
    state_entry() {    
        llSay(0, "Put desired sit animations in this prim "
            + "and in the Sit Target Helper.");
        llSay(0, "Sit on Sit Target Helper, move the helper to desired position, "
            + "and then click this prim to get menu");
        get_anims();
        MenuChan = channel();
        llListen(MenuChan, "", NULL_KEY, "");
    }
    
    on_rez(integer arg) {
        state default;      // do this to reset chan, to avoid object crosstalk
    }


    touch_end(integer total_number) {
        do_menu(llDetectedKey(0));
    }
    
    listen(integer chan, string name, key id, string msg) {
        if (msg == "SET") {
            do_sensor();
            return;
        }
        
        if (msg == "DONE") {
            state s_normal;
        }
    }

    // no helper around, do nothing
    no_sensor() {
        llSay(0, "Can't find " + HelperName + ".");
    }

    // Found the helper: set sit target and go to furniture mode
    sensor(integer num) {
        if (num > 1) {
            llSay(0, "Multiple Sit Target Helpers found.  Using closest one.");
        } else {
            llSay(0, "Setting sit target.");
        }
        
        calc_sit_target();
    }

    changed(integer change) {
        if (change & CHANGED_INVENTORY) {
            get_anims();
            return;
        }

        if (llAvatarOnSitTarget() == NULL_KEY) {
            LastAv = NULL_KEY;    // nobody's sitting now

           
           string lay = llGetInventoryName(INVENTORY_TEXTURE, 0);
llSetLinkAlpha(2, 0.0, ALL_SIDES);
llSetLinkAlpha(1, 1.0, ALL_SIDES);
llSetLinkAlpha(3, 1.0, ALL_SIDES);
llSetLinkTexture(1,lay,ALL_SIDES);
            
        } else {
            


            
            llRequestPermissions(llAvatarOnSitTarget(),
                PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
                                                     string stand = llGetInventoryName(INVENTORY_TEXTURE, 1);
           llSetLinkAlpha(2, 1.0, ALL_SIDES);
           llSetLinkAlpha(1, 1.0, ALL_SIDES);
           llSetLinkAlpha(3, 0.0, ALL_SIDES);
           llSetLinkTexture(1,stand,ALL_SIDES);
        }
    }


    run_time_permissions(integer perm) {
        // allow shift-arrow for selecting pose, but not rotation in this state.
        llTakeControls(CONTROL_RIGHT | CONTROL_LEFT, TRUE, FALSE);

        if (start_anim(AnimNum)) {
           llInstantMessage(llAvatarOnSitTarget(),
                "shift-left/right to change animation");
        }
    }

    // Handle arrow keys
    control(key id, integer level, integer change) {
        handle_control(level, change);
    }

    state_exit() {
      //  llSetTimerEvent(0.0);
        llSay(0, "Converting to normal furniture mode");
        integer linknum = llGetLinkNumber();
        string text = "To put me back in sit-target programming mode, reset the '"
            + llGetScriptName() + "' script in ";
            
        if (linknum > 1) {
            text += "prim " + (string) linknum + " (" + llGetObjectName() + ")";
        } else {
            text += "this object";
        }
        llSay(0, text);
    }
}


state s_renormal {
    state_entry() {
        state s_normal;
    }
}

// Normal 'sit' mode: now we're just furniture.

state s_normal
{
    state_entry() {
        OrigRotation = llGetRot();
    }

    changed(integer change) {
        if (change & CHANGED_INVENTORY) {
            get_anims();
            return;
        }

        if (llAvatarOnSitTarget() == NULL_KEY) {
            LastAv = NULL_KEY;          // nobody's sitting now

            if (Rotating) {
                llSetRot(OrigRotation);     // restore original rotation
            }
        } else {
            

            OrigRotation = llGetRot();  // save current seat rotation
            llRequestPermissions(llAvatarOnSitTarget(),
                PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
        }
    }

    run_time_permissions(integer perm) {
        integer controls;
        
        // Grab shift-arrow keys for changing anims.
        // If "rotat" is anywhere in the description,
        // support rotation (i.e., also grab arrow keys).

        if (llSubStringIndex(llToUpper(llGetObjectDesc()), "ROTAT") == -1) {
            Rotating = FALSE;
            // anim changing only
            controls =  CONTROL_RIGHT | CONTROL_LEFT;
        } else {
            Rotating = TRUE;
            // rotation support too
            controls =  CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT;
        }

        llTakeControls(controls, TRUE, FALSE);
        if (start_anim(AnimNum)) {
            llInstantMessage(llAvatarOnSitTarget(),
                "shift-left/right to change animation");;
        }
    }

    control(key id, integer level, integer change) {
        handle_control(level, change);
    }

    state_exit() {
        if (Rotating) {
            llSetRot(OrigRotation);
        }
    }
}

 and it edits the linkset the way I want it to, but for some reson it spams me with shift-left/right to change animation

I can't seem to figure out what I am doing wrong. Can somebody please help me?

 

 

Link to comment
Share on other sites

Which prim is this script in? My hunch is that it's in the root prim, which is link #1 in the multi-prim linkset, which is one of the ones you change with the link commands... and in the s_setting state you have a changed() handler that calls llGetPermissions, from which the run_time_permissions handler will IM about the shift controls. So I"m guessing that the link commands cause CHANGED_COLOR and CHANGED_TEXTURE events, and the changed() handler isn't checking for the specific change when it should ask for perms.

Link to comment
Share on other sites

what Qie said

can check for permissions already granted before calling llRequestPermissions. longhand example:

 

if ( (llGetPermissions() & (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION)) !=    (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION) ){  llRequestPermissions ( ... ,  PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION );}  

 

Link to comment
Share on other sites

Thanks a lot that is helping I put it in like this though

string  HelperName  = "Sit Target Helper 3b";list    Anims;              // names of anims in object's inventoryinteger AnimNum;            // index of current animstring  LastAnim;           // anim last sitter usedkey     LastAv;             // av who sat, just a guardrotation OrigRotation;      // rotation to return seat to, when av standsinteger Rotating;           // whether rotating seatinteger MenuChan;list Buttons = [      "SET"    , "DONE"    ];// Return a channel number that's based on the prim's key -- unique per objectinteger channel() {    return (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1));}do_menu(key id) {    llDialog(id,          "Choose SET to set the sit target.  Then test."        + "\nChoose DONE when you're happy."        + "\nTo change the target later, reset the script."        + "\n(e.g., select, and Tools -> Reset scripts in selection)",        Buttons,        MenuChan);}          do_sensor() {     // Find the helper     llSensor(HelperName, NULL_KEY, ACTIVE|PASSIVE, 20, PI);     llSay(0, "Searching for '" + HelperName + "'");}// Collect the set of anims in this primget_anims(){    integer ix;    string  anim;    llUnSit(llAvatarOnSitTarget());     Anims = [];    for (ix = 0; TRUE; ix++) {        anim = llGetInventoryName(INVENTORY_ANIMATION, ix);        if (anim == "") {            llWhisper(0, (string)llGetListLength(Anims) + " animations");            return;        }        Anims += [anim];    }}// Start the animation given by ordinal numberinteger start_anim(integer ix) {    integer numAnims = llGetListLength(Anims);    key     id = llAvatarOnSitTarget();    list anims = llGetAnimationList(id);    integer jx;    for (; jx < llGetListLength(anims); ++jx) {        llStopAnimation(llList2String(anims, jx));    }    if (numAnims > 0) {        string anim = llList2String(Anims, ix);        llStartAnimation(anim);                // If this is the first we've seen of this av, stop default sits        if (LastAv == NULL_KEY) {            llStopAnimation("sit");            llStopAnimation("sit_generic");            llStopAnimation("sit_female");        }        LastAnim = anim;        LastAv = id;    }    return (numAnims > 1);}// Start the next anim in inventorynext_anim(){    AnimNum++;    if (AnimNum >= llGetListLength(Anims)) {        AnimNum = 0;    }    start_anim(AnimNum);}// Start the previous anim in inventoryprev_anim(){    AnimNum--;    if (AnimNum < 0) {        AnimNum = llGetListLength(Anims) - 1;    }    start_anim(AnimNum);}// Rotate the stool by the given anglerotate(float amt){  rotation rot = llGetRot();  rotation r = llEuler2Rot(<0,0,amt * DEG_TO_RAD>);  llSetRot(rot * r);}// React to an arrow or shift-arrow keyhandle_control(integer level, integer change) {    key     id = llAvatarOnSitTarget();    if (level & CONTROL_RIGHT) {        next_anim();        llInstantMessage(id, LastAnim);    } else if (level & CONTROL_LEFT) {        prev_anim();        llInstantMessage(id, LastAnim);    } else if (level & CONTROL_ROT_LEFT) {        rotate(-15.0);    } else if (level & CONTROL_ROT_RIGHT) {        rotate(15.0);    }        }// Calculate the sit target, compensating for the known bug// Big thanks to Lex Neva for this!calc_sit_target(){    vector   helper_pos = llDetectedPos(0);    rotation helper_rot = llDetectedRot(0);        vector   my_pos = llGetPos();    rotation my_rot = llGetRot();        // calculate where the avatar actually is    vector avatar_pos = helper_pos + <0.,0.,.01> * helper_rot; // due to helper's sit target    avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target        vector target_pos = (avatar_pos - my_pos) / my_rot;    target_pos = target_pos + <0,0,0.186>/my_rot - <0,0,0.4>; // correct for the bug again, this time in my sit target    rotation target_rot = helper_rot / my_rot;        llSitTarget(target_pos, target_rot);    llSay(0, "llSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");");}upgrade() {    string me   = llGetScriptName();    string name = "Sit Target Setter";    integer n = llGetInventoryNumber(INVENTORY_SCRIPT);    while (n-- > 0) {                string item = llGetInventoryName(INVENTORY_SCRIPT, n);        if (item != me && 0 == llSubStringIndex(item, name)) {            llOwnerSay("removing old script: " + item);            llRemoveInventory(item);        }    }}default{    state_entry() {        upgrade();        state s_setting;    }}// Sit-target setting mode// On click, show menu.  On "SHOW", set the sit target.  On "DONE", go to furniture mode.// Might be a good idea to disallow to simplify and avoid user mistakes.state s_setting{    state_entry() {            llSay(0, "Put desired sit animations in this prim "            + "and in the Sit Target Helper.");        llSay(0, "Sit on Sit Target Helper, move the helper to desired position, "            + "and then click this prim to get menu");        get_anims();        MenuChan = channel();        llListen(MenuChan, "", NULL_KEY, "");    }        on_rez(integer arg) {        state default;      // do this to reset chan, to avoid object crosstalk    }    touch_end(integer total_number) {        do_menu(llDetectedKey(0));    }        listen(integer chan, string name, key id, string msg) {        if (msg == "SET") {            do_sensor();            return;        }                if (msg == "DONE") {            state s_normal;        }    }    // no helper around, do nothing    no_sensor() {        llSay(0, "Can't find " + HelperName + ".");    }    // Found the helper: set sit target and go to furniture mode    sensor(integer num) {        if (num > 1) {            llSay(0, "Multiple Sit Target Helpers found.  Using closest one.");        } else {            llSay(0, "Setting sit target.");        }                calc_sit_target();    }    changed(integer change) {        if (change & CHANGED_INVENTORY) {            get_anims();            return;        }        if (llAvatarOnSitTarget() == NULL_KEY) {                    string lay = llGetInventoryName(INVENTORY_TEXTURE, 0);            LastAv = NULL_KEY;    // nobody's sitting now                                     llSetLinkAlpha(2, 0.0, ALL_SIDES);;           llSetLinkAlpha(1, 1.0, ALL_SIDES);           llSetLinkAlpha(3, 1.0, ALL_SIDES);           llSetLinkTexture(1,lay,ALL_SIDES);        } else {            string stand = llGetInventoryName(INVENTORY_TEXTURE, 1);          //  llRequestPermissions(llAvatarOnSitTarget(),          //      PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);                         llSetLinkAlpha(2, 1.0, ALL_SIDES);;           llSetLinkAlpha(1, 1.0, ALL_SIDES);           llSetLinkAlpha(3, 0.0, ALL_SIDES);           llSetLinkTexture(1,stand,ALL_SIDES);           if ( (llGetPermissions() & (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION)) !=    (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION) ){  llRequestPermissions (llAvatarOnSitTarget(),  PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION );}          }    }    run_time_permissions(integer perm) {        // allow shift-arrow for selecting pose, but not rotation in this state.        llTakeControls(CONTROL_RIGHT | CONTROL_LEFT, TRUE, FALSE);        if (start_anim(AnimNum)) {            llInstantMessage(llAvatarOnSitTarget(),                "shift-left/right to change animation");        }    }    // Handle arrow keys    control(key id, integer level, integer change) {        handle_control(level, change);    }    state_exit() {        llSetTimerEvent(0.0);        llSay(0, "Converting to normal furniture mode");        integer linknum = llGetLinkNumber();        string text = "To put me back in sit-target programming mode, reset the '"            + llGetScriptName() + "' script in ";                    if (linknum > 1) {            text += "prim " + (string) linknum + " (" + llGetObjectName() + ")";        } else {            text += "this object";        }        llSay(0, text);    }}state s_renormal {    state_entry() {        state s_normal;    }}// Normal 'sit' mode: now we're just furniture.state s_normal{    state_entry() {        OrigRotation = llGetRot();    }    changed(integer change) {        if (change & CHANGED_INVENTORY) {            get_anims();            return;        }        if (llAvatarOnSitTarget() == NULL_KEY) {            LastAv = NULL_KEY;          // nobody's sitting now                    llSetLinkAlpha(2, 1.0, ALL_SIDES);;           llSetLinkAlpha(1, 1.0, ALL_SIDES);           llSetLinkAlpha(3, 1.0, ALL_SIDES);            if (Rotating) {                llSetRot(OrigRotation);     // restore original rotation            }        } else {            OrigRotation = llGetRot();  // save current seat rotation                      if ( (llGetPermissions() & (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION)) !=    (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION) ){  llRequestPermissions (llAvatarOnSitTarget(),  PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION );}          }    }    run_time_permissions(integer perm) {        integer controls;        // Grab shift-arrow keys for changing anims.        // If "rotat" is anywhere in the description,        // support rotation (i.e., also grab arrow keys).        if (llSubStringIndex(llToUpper(llGetObjectDesc()), "ROTAT") == -1) {            Rotating = FALSE;            // anim changing only            controls =  CONTROL_RIGHT | CONTROL_LEFT;        } else {            Rotating = TRUE;            // rotation support too            controls =  CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT;        }        llTakeControls(controls, TRUE, FALSE);        if (start_anim(AnimNum)) {            llInstantMessage(llAvatarOnSitTarget(),                "shift-left/right to change animation");        }    }    control(key id, integer level, integer change) {        handle_control(level, change);    }    state_exit() {        if (Rotating) {            llSetRot(OrigRotation);        }    }}

 and now I'm getting a "Unable to find specified agent to request permissions" when I stand

Link to comment
Share on other sites


ChaosRaine wrote:

 and now I'm getting a "Unable to find specified agent to request permissions" when I stand

is mostly bc the script is using llAvatarOnSitTarget() to do stuff. And when stand then is no avatar on the sittarget. So error

the script has a global var LastAv. Is kinda used but also kinda not used

assuming that we not concerned about multiple avatars all trying to sit at once on the same object then if was me:

 

// globalkey LastAv = NULL_KEY;changed (integer change){   // test for avatar first before doing anything else   // assumes that not also linking/unlinking prims/objects   // if we are then also need to keep track of how many link objects there are   // but assume not for this example case   if (change & CHANGED_LINK)   {        key thisAv = llAvatarOnSitTarget();        if ((thisAv == NULL_KEY) // then a avatar got off        {            // do any script tidy up here to return to the resting state            // e.g. llReleaseControls(); etc                       LastAv = NULL_KEY;            return;        }        if (LastAv == NULL_KEY) // then is a new avatar sitting: thisAv        {            llRequestPermissions(thisAv, PERM... );            // at this point can also test if the permissions been granted            // have to watch the lag if do this tho            // if do test then can sleep the script at this point             // or use a polling method which is better imo            if ( (llGetPermissionsKey() != thisAv) ||                  ((llGetPermissions() & (PERM...)) != (PERM...)) )             {                  llUnSit(thisAv);  // kick them off so they will resit                 return;            }            LastAv = thisAv;            }   }                          // at this point should have a valid avatar and permissions: LastAv   // so can do the rest of the code here       ...}

 

+

also go thru the code and change any avatar references to use LastAv

if get errors after doing this then test for LastAv == NULL_KEY or != as appropriate

 

ETA: exmalpe code typo

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3571 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...