normalized perms on all files, to avoid relying on any stored executable bits in...
[feisty_meow.git] / huffware / huffotronic_scripts / swiveller_v1.1.txt
1 
2 //huffware script: swiveller, modified by fred huffhines.
3
4 //original docs:
5 // This script is as end-user friendly as possible. Moving the swing will make it reset to it's new position and orientation. Occasionally JUST rotating it won't work, so in that case you will need to nudge it sideways just a little (1mm will do). This is a quirk of LSL and it intermittent.
6 // Put this script in the pivot - the thing the swing swings around (it doesn't have to be a long rod). That needs to be the root of the prim set that actually swings - if you want/need a frame that needs to be a separate item. SL doesn't yet allow us hierarchical linking.
7 //
8 // fred's modifications are licensed by:
9 //   this script is licensed by the GPL v3 which is documented at: http://www.gnu.org/licenses/gpl.html
10 //   do not use it in objects without fully realizing you are implicitly accepting that license.
11 //
12
13 // configuration variables -- these control how the swing behaves.
14
15 integer is_swinging = FALSE;  // if set to FALSE, then the swing is not running when rezzed.
16
17 float SWING_PERIOD = 0.4;
18     // the delay between changing the swing's position.  decrease this number to increase
19     // speed of swinging.
20
21 integer SWING_STEPS = 12;
22     // The total number of steps in the swing's path.  More steps makes for a
23     // smoother swing.  More steps (alone) means slower swinging also--time for
24     // a complete swing cycle is SWING_STEPS * swing_period.
25
26 integer SWING_ANGLE_DEGREES = 10;
27     // How far from the vertical the swing will move.
28 //This is in both directions?
29
30 /////
31
32 integer swing_step = 1;
33     // the current swing position.
34     
35 float swingRad;
36
37 vector normal;
38
39 rotation Inverse(rotation r) { return <-r.x, -r.y, -r.z, r.s>; }
40
41 rotation GetParentRot() { return Inverse(llGetLocalRot()) * llGetRot(); }
42
43 SetLocalRot(rotation x) { llSetRot(x*Inverse(GetParentRot())); }
44
45
46 //////////////
47
48 //////////////
49 // huffware script: auto-retire, by fred huffhines, version 2.5.
50 // distributed under BSD-like license.
51 //   !!  keep in mind that this code must be *copied* into another
52 //   !!  script that you wish to add auto-retirement capability to.
53 // when a script has auto_retire in it, it can be dropped into an
54 // object and the most recent version of the script will destroy
55 // all older versions.
56 //
57 // the version numbers are embedded into the script names themselves.
58 // the notation for versions uses a letter 'v', followed by two numbers
59 // in the form "major.minor".
60 // major and minor versions are implicitly considered as a floating point
61 // number that increases with each newer version of the script.  thus,
62 // "hazmap v0.1" might be the first script in the "hazmap" script continuum,
63 // and "hazmap v3.2" is a more recent version.
64 //
65 // example usage of the auto-retirement script:
66 //     default {
67 //         state_entry() {
68 //            auto_retire();  // make sure newest addition is only version of script.
69 //        }
70 //     }
71 // this script is partly based on the self-upgrading scripts from markov brodsky
72 // and jippen faddoul.
73 //////////////
74 auto_retire() {
75     string self = llGetScriptName();  // the name of this script.
76     list split = compute_basename_and_version(self);
77     if (llGetListLength(split) != 2) return;  // nothing to do for this script.
78     string basename = llList2String(split, 0);  // script name with no version attached.
79     string version_string = llList2String(split, 1);  // the version found.
80     integer posn;
81     // find any scripts that match the basename.  they are variants of this script.
82     for (posn = llGetInventoryNumber(INVENTORY_SCRIPT) - 1; posn >= 0; posn--) {
83 //log_it("invpo=" + (string)posn);
84         string curr_script = llGetInventoryName(INVENTORY_SCRIPT, posn);
85         if ( (curr_script != self) && (llSubStringIndex(curr_script, basename) == 0) ) {
86             // found a basic match at least.
87             list inv_split = compute_basename_and_version(curr_script);
88             if (llGetListLength(inv_split) == 2) {
89                 // see if this script is more ancient.
90                 string inv_version_string = llList2String(inv_split, 1);  // the version found.
91                 // must make sure that the retiring script is completely the identical basename;
92                 // just matching in the front doesn't make it a relative.
93                 if ( (llList2String(inv_split, 0) == basename)
94                     && ((float)inv_version_string < (float)version_string) ) {
95                     // remove script with same name from inventory that has inferior version.
96                     llRemoveInventory(curr_script);
97                 }
98             }
99         }
100     }
101 }
102 //
103 // separates the base script name and version number.  used by auto_retire.
104 list compute_basename_and_version(string to_chop_up)
105 {
106     // minimum script name is 2 characters plus a version.
107     integer space_v_posn;
108     // find the last useful space and 'v' combo.
109     for (space_v_posn = llStringLength(to_chop_up) - 3;
110         (space_v_posn >= 2) && (llGetSubString(to_chop_up, space_v_posn, space_v_posn + 1) != " v");
111         space_v_posn--) {
112         // look for space and v but do nothing else.
113 //log_it("pos=" + (string)space_v_posn);
114     }
115     if (space_v_posn < 2) return [];  // no space found.
116 //log_it("space v@" + (string)space_v_posn);
117     // now we zoom through the stuff after our beloved v character and find any evil
118     // space characters, which are most likely from SL having found a duplicate item
119     // name and not so helpfully renamed it for us.
120     integer indy;
121     for (indy = llStringLength(to_chop_up) - 1; indy > space_v_posn; indy--) {
122 //log_it("indy=" + (string)space_v_posn);
123         if (llGetSubString(to_chop_up, indy, indy) == " ") {
124             // found one; zap it.  since we're going backwards we don't need to
125             // adjust the loop at all.
126             to_chop_up = llDeleteSubString(to_chop_up, indy, indy);
127 //log_it("saw case of previously redundant item, aieee.  flattened: " + to_chop_up);
128         }
129     }
130     string full_suffix = llGetSubString(to_chop_up, space_v_posn, -1);
131     // ditch the space character for our numerical check.
132     string chop_suffix = llGetSubString(full_suffix, 1, llStringLength(full_suffix) - 1);
133     // strip out a 'v' if there is one.
134     if (llGetSubString(chop_suffix, 0, 0) == "v")
135         chop_suffix = llGetSubString(chop_suffix, 1, llStringLength(chop_suffix) - 1);
136     // if valid floating point number and greater than zero, that works for our version.
137     string basename = to_chop_up;  // script name with no version attached.
138     if ((float)chop_suffix > 0.0) {
139         // this is a big success right here.
140         basename = llGetSubString(to_chop_up, 0, -llStringLength(full_suffix) - 1);
141         return [ basename, chop_suffix ];
142     }
143     // seems like we found nothing useful.
144     return [];
145 }
146 //
147 //////////////
148
149 default
150 {
151     state_entry() { if (llSubStringIndex(llGetObjectName(),  "huffotronic") < 0) state real_default; }
152     on_rez(integer parm) { state rerun; }
153 }
154 state rerun { state_entry() { state default; } }
155
156 state real_default
157 {
158     state_entry()
159     {
160         normal = llRot2Euler(llGetRot());
161         swingRad = SWING_ANGLE_DEGREES * DEG_TO_RAD;
162         llSetTouchText("Swing");
163     }
164     touch_start(integer num)
165     {
166         if (is_swinging) {
167             is_swinging = FALSE;
168             llSetTouchText("Swing");
169         } else {
170             is_swinging = TRUE;
171             llSetTouchText("Stop swing");
172             llSetTimerEvent(SWING_PERIOD);
173         }
174     }
175     timer()
176     {
177         float stepOffset = (float)swing_step / SWING_STEPS * TWO_PI;
178         if (swing_step > SWING_STEPS) swing_step = 1;
179         if (!is_swinging && (swing_step>=SWING_STEPS || swing_step==SWING_STEPS/2)) {
180             llSetTimerEvent(0.0);
181             SetLocalRot(llEuler2Rot(<normal.x, normal.y,
182                 normal.z + swingRad*llSin(stepOffset)>));
183         } else {
184             SetLocalRot(llEuler2Rot(<normal.x, normal.y,
185                 normal.z + swingRad*llSin(stepOffset)>));
186             swing_step++;
187         }
188     }
189     moving_end()
190     {
191         normal = llRot2Euler(llGetRot());
192     }
193 }