ChaosRaine Posted July 8, 2014 Share Posted July 8, 2014 I'm trying to addstring 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 andstring 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 scriptstring 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 animationI can't seem to figure out what I am doing wrong. Can somebody please help me? Link to comment Share on other sites More sharing options...
Rolig Loon Posted July 8, 2014 Share Posted July 8, 2014 As long as you have more than one anim in the object's inventory, start_anim is always going to return a value that makes if (start_anim(Anim_Num)) =TRUE. Therefore, you'll always get the IM. Link to comment Share on other sites More sharing options...
ChaosRaine Posted July 8, 2014 Author Share Posted July 8, 2014 but I didn't get it before adding the link set commands. It works fine without them Link to comment Share on other sites More sharing options...
Qie Niangao Posted July 8, 2014 Share Posted July 8, 2014 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 More sharing options...
irihapeti Posted July 8, 2014 Share Posted July 8, 2014 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 More sharing options...
ChaosRaine Posted July 8, 2014 Author Share Posted July 8, 2014 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 More sharing options...
irihapeti Posted July 9, 2014 Share Posted July 9, 2014 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 More sharing options...
ChaosRaine Posted July 10, 2014 Author Share Posted July 10, 2014 Thank you so much! I got it working now. =) Link to comment Share on other sites More sharing options...
Recommended Posts
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