Advertisement
Guest User

Untitled

a guest
Jul 18th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Sit target system by Lex Neva.  Please distribute willy-nilly.
  2. // learjeff innis: allow to leave script in furniture.
  3. // Note that shift-drag to copy will lose the sit target.
  4.  
  5. // v2d: anim menu
  6. // v2e: shift-lef/right to switch anims
  7. // v2f: left/right to rotate (normal furniture mode only), and only if "Rotat" is in description
  8. // v2g: compensate for LSL bug?  key sent to "control" is not always av on sit target!
  9. // v2h: comments, optimize stopping of default sits
  10. // v2i: ?
  11. // v2i1: fix rotation after getting up
  12.  
  13. // v3: menu!  Make it so finished furniture doesn't show a clickable cursor
  14.  
  15.  
  16. string  HelperName  = "Sit Target Helper 3";
  17.  
  18. list    Anims;              // names of anims in object's inventory
  19. integer AnimNum;            // index of current anim
  20. string  LastAnim;           // anim last sitter used
  21. key     LastAv;             // av who sat, just a guard
  22. rotation OrigRotation;      // rotation to return seat to, when av stands
  23. integer Rotating;           // whether rotating seat
  24.  
  25. integer MenuChan;
  26.  
  27. list Buttons = [
  28.     "SET"
  29.         , "DONE"
  30.             ];
  31.  
  32. // Return a channel number that's based on the prim's key -- unique per object
  33. integer channel() {
  34.     return (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1));
  35. }
  36.  
  37. do_menu(key id) {
  38.     llDialog(id,
  39.         "Choose SET to set the sit target.  Then test."
  40.             + "\nChoose DONE when you're happy."
  41.         + "\nTo change the target later, reset the script."
  42.         + "\n(e.g., select, and Tools -> Reset scripts in selection)",
  43.         Buttons,
  44.         MenuChan);
  45. }
  46.  
  47. do_sensor() {
  48.     // Find the helper
  49.     llSensor(HelperName, NULL_KEY, ACTIVE|PASSIVE, 20, PI);
  50.     llSay(0, "Searching for '" + HelperName + "'");
  51. }
  52.  
  53. // Collect the set of anims in this prim
  54.  
  55. get_anims()
  56. {
  57.     integer ix;
  58.     string  anim;
  59.  
  60.     llUnSit(llAvatarOnSitTarget());
  61.     Anims = [];
  62.  
  63.     for (ix = 0; TRUE; ix++) {
  64.  
  65.         anim = llGetInventoryName(INVENTORY_ANIMATION, ix);
  66.         if (anim == "") {
  67.             llWhisper(0, (string)llGetListLength(Anims) + " animations");
  68.             return;
  69.         }
  70.         Anims += [anim];
  71.     }
  72. }
  73.  
  74.  
  75. // Start the animation given by ordinal number
  76.  
  77. integer start_anim(integer ix) {
  78.     integer numAnims = llGetListLength(Anims);
  79.     key     id = llAvatarOnSitTarget();
  80.  
  81.     list anims = llGetAnimationList(id);
  82.     integer jx;
  83.     for (; jx < llGetListLength(anims); ++jx) {
  84.         llStopAnimation(llList2String(anims, jx));
  85.     }
  86.  
  87.  
  88.     if (numAnims > 0) {
  89.         string anim = llList2String(Anims, ix);
  90.  
  91.         llStartAnimation(anim);
  92.  
  93.         // If this is the first we've seen of this av, stop default sits
  94.         if (LastAv == NULL_KEY) {
  95.             llStopAnimation("sit");
  96.             llStopAnimation("sit_generic");
  97.             llStopAnimation("sit_female");
  98.         }
  99.         LastAnim = anim;
  100.         LastAv = id;
  101.     }
  102.  
  103.     return (numAnims > 1);
  104. }
  105.  
  106.  
  107. // Start the next anim in inventory
  108.  
  109. next_anim()
  110. {
  111.     AnimNum++;
  112.     if (AnimNum >= llGetListLength(Anims)) {
  113.         AnimNum = 0;
  114.     }
  115.     start_anim(AnimNum);
  116. }
  117.  
  118.  
  119. // Start the previous anim in inventory
  120.  
  121. prev_anim()
  122. {
  123.     AnimNum--;
  124.     if (AnimNum < 0) {
  125.         AnimNum = llGetListLength(Anims) - 1;
  126.     }
  127.     start_anim(AnimNum);
  128. }
  129.  
  130.  
  131. // Rotate the stool by the given angle
  132.  
  133. rotate(float amt)
  134. {
  135.     rotation rot = llGetRot();
  136.     rotation r = llEuler2Rot(<0,0,amt * DEG_TO_RAD>);
  137.     llSetRot(rot * r);
  138. }
  139.  
  140.  
  141. // React to an arrow or shift-arrow key
  142.  
  143. handle_control(integer level, integer change) {
  144.  
  145.     key     id = llAvatarOnSitTarget();
  146.  
  147.     if (level & CONTROL_RIGHT) {
  148.         next_anim();
  149.         llInstantMessage(id, LastAnim);
  150.     } else if (level & CONTROL_LEFT) {
  151.             prev_anim();
  152.         llInstantMessage(id, LastAnim);
  153.     } else if (level & CONTROL_ROT_LEFT) {
  154.             rotate(-15.0);
  155.     } else if (level & CONTROL_ROT_RIGHT) {
  156.             rotate(15.0);
  157.     }
  158. }
  159.  
  160.  
  161. // Calculate the sit target, compensating for the known bug
  162. // Big thanks to Lex Neva for this!
  163.  
  164. calc_sit_target()
  165. {
  166.  
  167.     vector   helper_pos = llDetectedPos(0);
  168.     rotation helper_rot = llDetectedRot(0);
  169.  
  170.     vector   my_pos = llGetPos();
  171.     rotation my_rot = llGetRot();
  172.  
  173.     // calculate where the avatar actually is
  174.     vector avatar_pos = helper_pos + <0,0,1> * helper_rot; // due to helper's sit target
  175.     avatar_pos = avatar_pos - <0,0,0.186> + <0,0,0.4> * helper_rot; // correct for a bug in llSitTarget(), for helper sit target
  176.  
  177.     vector target_pos = (avatar_pos - my_pos) / my_rot;
  178.     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
  179.     rotation target_rot = helper_rot / my_rot;
  180.  
  181.     llSitTarget(target_pos, target_rot);
  182.     llSay(0, "llSitTarget(" + (string)target_pos + ", " + (string)target_rot + ");");
  183. }
  184.  
  185.  
  186. upgrade() {
  187.     string me   = llGetScriptName();
  188.     string name = "Sit Target Setter";
  189.     integer n = llGetInventoryNumber(INVENTORY_SCRIPT);
  190.     while (n-- > 0) {
  191.         string item = llGetInventoryName(INVENTORY_SCRIPT, n);
  192.         if (item != me && 0 == llSubStringIndex(item, name)) {
  193.             llOwnerSay("removing old script: " + item);
  194.             llRemoveInventory(item);
  195.         }
  196.     }
  197. }
  198.  
  199. default
  200. {
  201.     state_entry() {
  202.         upgrade();
  203.         state s_setting;
  204.     }
  205. }
  206.  
  207. // Sit-target setting mode
  208. // On click, show menu.  On "SHOW", set the sit target.  On "DONE", go to furniture mode.
  209. // Might be a good idea to disallow to simplify and avoid user mistakes.
  210.  
  211. state s_setting
  212. {
  213.     state_entry() {
  214.         llSay(0, "Put desired sit animations in this prim "
  215.             + "and in the Sit Target Helper.");
  216.         llSay(0, "Sit on Sit Target Helper, move the helper to desired position, "
  217.             + "and then click this prim to get menu");
  218.         get_anims();
  219.         MenuChan = channel();
  220.         llListen(MenuChan, "", NULL_KEY, "");
  221.     }
  222.  
  223.     on_rez(integer arg) {
  224.         state default;      // do this to reset chan, to avoid object crosstalk
  225.     }
  226.  
  227.  
  228.     touch_end(integer total_number) {
  229.         do_menu(llDetectedKey(0));
  230.     }
  231.  
  232.     listen(integer chan, string name, key id, string msg) {
  233.         if (msg == "SET") {
  234.             do_sensor();
  235.             return;
  236.         }
  237.  
  238.         if (msg == "DONE") {
  239.             state s_normal;
  240.         }
  241.     }
  242.  
  243.     // no helper around, do nothing
  244.     no_sensor() {
  245.         llSay(0, "Can't find " + HelperName + ".");
  246.     }
  247.  
  248.     // Found the helper: set sit target and go to furniture mode
  249.     sensor(integer num) {
  250.         if (num > 1) {
  251.             llSay(0, "Multiple Sit Target Helpers found.  Using closest one.");
  252.         } else {
  253.                 llSay(0, "Setting sit target.");
  254.         }
  255.  
  256.         calc_sit_target();
  257.     }
  258.  
  259.     changed(integer change)
  260.     {
  261.         if (change & CHANGED_INVENTORY) {
  262.             get_anims();
  263.             return;
  264.         }
  265.  
  266.         if (llAvatarOnSitTarget() == NULL_KEY)
  267.         {
  268.             LastAv = NULL_KEY;    // nobody's sitting now
  269.         }
  270.         else
  271.         {
  272.             if (llAvatarOnSitTarget()!= llGetOwner())
  273.             {
  274.                 llUnSit(llAvatarOnSitTarget() );
  275.                 return;
  276.             }
  277.             llRequestPermissions(llAvatarOnSitTarget() ,
  278.                 PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
  279.         }
  280.     }
  281.  
  282.  
  283.     run_time_permissions(integer perm) {
  284.         // allow shift-arrow for selecting pose, but not rotation in this state.
  285.         llTakeControls(CONTROL_RIGHT | CONTROL_LEFT, TRUE, FALSE);
  286.  
  287.         if (start_anim(AnimNum)) {
  288.             llInstantMessage(llAvatarOnSitTarget(),
  289.                 "shift-left/right to change animation");
  290.         }
  291.     }
  292.  
  293.     // Handle arrow keys
  294.     control(key id, integer level, integer change) {
  295.         handle_control(level, change);
  296.     }
  297.  
  298.     state_exit() {
  299.         llSetTimerEvent(0.0);
  300.         llSay(0, "Converting to normal furniture mode");
  301.         integer linknum = llGetLinkNumber();
  302.         string text = "To put me back in sit-target programming mode, reset the '"
  303.             + llGetScriptName() + "' script in ";
  304.  
  305.         if (linknum > 1) {
  306.             text += "prim " + (string) linknum + " (" + llGetObjectName() + ")";
  307.         } else {
  308.                 text += "this object";
  309.         }
  310.         llSay(0, text);
  311.     }
  312. }
  313.  
  314.  
  315. state s_renormal {
  316.     state_entry() {
  317.         state s_normal;
  318.     }
  319. }
  320.  
  321. // Normal 'sit' mode: now we're just furniture.
  322.  
  323. state s_normal
  324. {
  325.     state_entry() {
  326.         OrigRotation = llGetRot();
  327.     }
  328.  
  329.     changed(integer change) {
  330.         if (change & CHANGED_INVENTORY) {
  331.             get_anims();
  332.             return;
  333.         }
  334.  
  335.         if (llAvatarOnSitTarget() == NULL_KEY) {
  336.             LastAv = NULL_KEY;          // nobody's sitting now
  337.             if (Rotating) {
  338.                 llSetRot(OrigRotation);     // restore original rotation
  339.             }
  340.         } else {
  341.                 OrigRotation = llGetRot();  // save current seat rotation
  342.             llRequestPermissions(llAvatarOnSitTarget(),
  343.                 PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
  344.         }
  345.     }
  346.  
  347.     run_time_permissions(integer perm) {
  348.         integer controls;
  349.  
  350.         // Grab shift-arrow keys for changing anims.
  351.         // If "rotat" is anywhere in the description,
  352.         // support rotation (i.e., also grab arrow keys).
  353.  
  354.         if (llSubStringIndex(llToUpper(llGetObjectDesc()), "ROTAT") == -1) {
  355.             Rotating = FALSE;
  356.             // anim changing only
  357.             controls =  CONTROL_RIGHT | CONTROL_LEFT;
  358.         } else {
  359.                 Rotating = TRUE;
  360.             // rotation support too
  361.             controls =  CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT;
  362.         }
  363.  
  364.         llTakeControls(controls, TRUE, FALSE);
  365.         if (start_anim(AnimNum)) {
  366.             llInstantMessage(llAvatarOnSitTarget(),
  367.                 "shift-left/right to change animation");
  368.         }
  369.     }
  370.  
  371.     control(key id, integer level, integer change) {
  372.         handle_control(level, change);
  373.     }
  374.  
  375.     state_exit() {
  376.         if (Rotating) {
  377.             llSetRot(OrigRotation);
  378.         }
  379.     }
  380. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement