Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
Special Effects Avatar_Magnet  

Avatar_Magnet

Avatar Magnet.lsl

Category: Special Effects
By : Anonymous
Created: 2010-01-10 Edited: 2010-01-10
Worlds: Second Life

the Zip file

Download all files for Avatar_Magnet
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Avatar_Magnet_1.lsl
1
2 // Avatar Magnet Script 0.1
3 // a simple avatar magnet with some "nice" features built in
4 // if you turn these features off *please*
5 // don't use it outside of a combat area
6 // even if you leave them on this script uses push to simulate a
7 // magnet effect it *will* register as PvP outside combat areas
8 //
9 // if you turn OBJECTS on it will attract physical objects too
10 // but it doesn't work very well
11 // especially with small objects as they usually end up flying off world
12 //
13 // this script is mostly untested
14 // if you have problems let me know and i'll try to fix them
15
16
17 // whether the object asks permission to attract or not
18 // be nice and ask ;)
19 integer REQUIRE_PERMISSION = TRUE;
20
21 // if we are requiring permissions set this based on whether
22 // you want it to prompt nearby users for permissions
23 // or require them to touch this object to be asked permission
24 // TRUE means it will ask without touching
25 // FALSE means they must touch it to be asked
26 integer UNSOLICITED = TRUE;
27
28 // how far to look around for targets
29 // this is highly dependant on the mass of this object
30 // and the mass of the target
31 // small objects might not have enough energy to attract far away targets
32 // maximum of 96.0 meters
33 float RADIUS = 30.0;
34
35 // how forceful you want to the magnet to be
36 // if you set this too high it's hard for the magnet to keep up
37 // with the velocity of the target so you get a lot of "ping-pong" effect
38 // if you set it too low then the target can break away easily
39 // if it has the ability to apply its own impulse
40 // (an avatar can fly away from the magnet if it's set too low ...
41 // but this may be a good thing)
42 // the maximum amount is effectively 2147483647
43 // but really > 100 is too much
44 float FORCE = 20.0;
45
46 // attract avatars
47 integer AVATARS = TRUE;
48
49 // attract physical objects
50 // this really doesn't work very well, especially for small objects
51 integer OBJECTS = FALSE;
52
53 // if we're asking permission we need to keep a list of people
54 // who have accepted and people who have declined
55 // unfortunately due to memory constraints these lists will be capped
56 // i haven't tested this!
57 // if you get stack-heap errors you will need to lower the cap
58 integer CAP = 50;
59 list declined;
60 list accepted;
61
62 // listener handle
63 integer listener;
64
65 askPermission(key avatar) {
66 // build the message based on the settings
67 string message = "May this magnet attract ";
68 if(AVATARS) message += "you";
69 if(OBJECTS && AVATARS) message += " and ";
70 if(OBJECTS) message += "your objects";
71 message += "?";
72
73 // build dialog button list
74 // based on whether or not this is the owner
75 list buttons = ["Accept", "Decline"];
76 if(avatar == llGetOwner()) buttons += ["Turn Off"];
77
78 llDialog(avatar, message, buttons, -38739454);
79 }
80
81 default {
82 state_entry() {
83 // turn of collision effects
85 llCollisionSound("", 0.0);
86
87 llSetText("Magnet Off", <1.0, 1.0, 1.0>, 1.0);
88
89 llOwnerSay("Magnet Off");
90 }
91
92 touch_start(integer touches) {
93 // turn the magnet on
94 if(llDetectedKey(0) == llGetOwner()) state magnetized;
95 }
96 }
97
98 state magnetized {
99 on_rez(integer start) {
101 }
102
103 state_entry() {
104 // clear out the accepted list
105 accepted = [];
106
107 llSetText("Magnet On", <1.0, 1.0, 1.0>, 1.0);
108
109 llOwnerSay("Magnet On");
110
111 // the magnet shouldn't be phantom or you get weird results
112 llSetStatus(STATUS_PHANTOM, FALSE);
113
114 // figure out which types of targets we're attracting
115 integer types;
116 if(AVATARS) types = types | AGENT;
117 if(OBJECTS) types = types | ACTIVE;
118
119 // set our sensor
120 llSensorRepeat("", "", types, RADIUS, TWO_PI, 0.1);
121
122 // listen for dialog responses if we're asking permission
123 if(REQUIRE_PERMISSION)
124 listener = llListen(-38739454, "", "", "");
125 }
126
127 listen(integer channel, string name, key id, string message) {
128 // only listen to avatars
129 if(llGetOwnerKey(id) == id) {
130 if(message == "Accept") {
131 // if they were already on the accepted list
132 // remove their earlier entry
133 integer index = llListFindList(accepted, [id]);
134
135 if(index > -1)
136 accepted = llDeleteSubList(accepted, index, index);
137
138 // add to the end of the accepted list
139 accepted += [id];
140
141 // make sure our list isn't bigger than the cap
142 if(llGetListLength(accepted) > CAP)
143 accepted = llDeleteSubList(accepted, 0, 0);
144
145 // remove from the declined list if they're on it
146 index = llListFindList(declined, [id]);
147
148 if(index > -1)
149 declined = llDeleteSubList(declined, index, index);
150 } else if(message == "Decline") {
151 // remove from the accepted list if they're on it
152 integer index = llListFindList(accepted, [id]);
153
154 if(index > -1)
155 accepted = llDeleteSubList(accepted, index, index);
156
157 // if they were already on the declined list
158 // remove their earlier entry
159 index = llListFindList(declined, [id]);
160
161 if(index > -1)
162 declined = llDeleteSubList(declined, index, index);
163
164 // add to the end of the declined list
165 declined += [id];
166
167 // make sure our list isn't bigger than the cap
168 if(llGetListLength(declined) > CAP)
169 declined = llDeleteSubList(declined, 0, 0);
170 } else if(message == "Turn Off" && id == llGetOwner()) {
171 state default;
172 }
173 }
174 }
175
176 touch_start(integer touches) {
177 key toucher = llDetectedKey(0);
178
179 if(REQUIRE_PERMISSION) {
180 askPermission(toucher);
181
182 return;
183 }
184
185 if(toucher == llGetOwner()) state default;
186 }
187
188 sensor(integer sensed) {
189 integer i;
190
191 for (i = 0; i < sensed; i ++) {
192 key target_key = llDetectedKey(i);
193
194 // if we're getting permission
195 // we need to see if we've alreay bothered this person
196 if(REQUIRE_PERMISSION) {
197 // since we may be attracting objects too
198 // we need to make sure we're asking the owner
199 key owner_key = llDetectedOwner(i);
200
201 // if this person has not already accepted
202 // don't attract them
203 if(llListFindList(accepted, [owner_key]) == -1) {
204 // but if we haven't already bothered them
205 // we need to ask them
206 if(llListFindList(declined, [owner_key]) == -1) {
207 // put their name on the denied list
208 declined += [owner_key];
209
210 // make sure our list isn't bigger than the cap
211 if(llGetListLength(declined) > CAP)
212 declined = llDeleteSubList(declined, 0, 0);
213
214 if(UNSOLICITED) askPermission(owner_key);
215 }
216
217 return;
218 }
219 }
220
221 // the position of our target
222 vector target_pos = llDetectedPos(i);
223
224 vector my_pos = llGetPos();
225
226 // normalized vector describing the direction
227 // from our target to us
228 // this is a negative vector
229 // which will draw the object towards us
230 vector direction = llVecNorm(my_pos - target_pos);
231
232 // apply set amount of force
233 // in the direction from the target to this object
234 vector impulse = FORCE * direction;
235
236 // equalize for the targets mass so pull is consistent
237 impulse *= llGetObjectMass(target_key);
238
239 // equalize for the distance of the target
240 // so pull is consistent
241 impulse *= llPow(llVecDist(my_pos, target_pos), 3.0);
242
243 // negate the targets current velocity
244 impulse -= llDetectedVel(i);
245
246 llPushObject(target_key, impulse, ZERO_VECTOR, FALSE);
247 }
248 }
249
250 state_exit() {
251 // we don't actually need to do this any more because
252 // listeners are cleaned up on state change but we might as well
253 if(REQUIRE_PERMISSION) llListenRemove(listener);
254 }
255 }
256
257
258 // END //

Back to the Best Free Tools in Second Life and OpenSim.