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
Bird Perching bird  

Perching bird

A free-flying bird that perches on your arm

Category: Bird
By : Ferd Frederix
Created: 2013-11-19 Edited: 2013-11-19
Worlds: Second Life

the Zip file

Download all files for Perching bird
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Script.lsl

This script by Ferd Frederix may be used in any manner, modified, and republished.  Unless specified otherwise, my scripts are always free and open source.  Objects made with these scripts may be sold with no restrictions.  All I ask is that you point others to this location should they ask you about it and to not sell this script, unless it is for $0 L. Please help improve my work by reporting bugs and improvements.

1 // ______ _ ______ _ _
2 // | ___| | | | ___| | | (_)
3 // | |_ ___ _ __ __| | | |_ _ __ ___ __| | ___ _ __ ___ __
4 // | _/ _ \ '__/ _` | | _| '__/ _ \/ _` |/ _ \ '__| \ \/ /
5 // | || __/ | | (_| | | | | | | __/ (_| | __/ | | |> <
6 // \_| \___|_| \__,_| \_| |_| \___|\__,_|\___|_| |_/_/\_\
7 //
8 // fred@mitsi.com
9 // tour bird script
10 //
11 //Revisions:
12 // 1/28/2010 initial release
13 // 03/06/2010 added perching
14
15 integer debug = 0;
16 /////////////// CONSTANTS ///////////////////
17 string FWD_DIRECTION = "x";
18 vector POSITION_OFFSET; // Local coords
19 float SCAN_REFRESH = 0.5;
20 float MOVETO_INCREMENT = 0.5;
21 key gOwner;
22 rotation gFwdRot;
23 float gTau;
24 float gMass;
25 integer count;
26 integer repeat;
27 integer flag2 = 0;
28 vector Pos;
29 float FORCE = 2;
30 float DAMPING2 = .2; // and how soon
31 integer seek = TRUE;
32 integer movement = 0;
33 ///////////// END PERCH CONSTANTS /////////////////
34
35 vector rezpoint; // home point
36 rotation rezrot;
37 integer Flying;
38
39 integer listen_chan;
40 integer listener;
41 float i ; //counter for timer moving
42 vector up_vel = <10,0,9>; // speed and direction away
43 vector down_vel = <6,0,-8>; // and to go home, small numbers for less speed and mass objects
44 float STRENGTH = 2.0; // how hard to turn
45 float DAMPING = 0.2; // and how soon
46 float MAX = 3.0; // MAX strength ( slow turns)
47 float MIN = 1.0; // fast turns
48
49 float timerate = 0.215;
50 float roam_range = 10; // default range
51 string flag ; // what menu item thay need integers for
52
53 vector newpos;
54
55 vector dir;
56 float dist;
57 vector direction;
58 vector Destination;
59 float atimer;
60 float INTERVAL = .050; // seconds to move
61 integer SeekingFish = FALSE;
62
63 Dialog()
64 {
65 listener = llListen(listen_chan,"","","");
66 llDialog(llGetOwner(),"Flight Controls: Home: current place is the roost\nTime: How often to fly when no one is near\nRange: Distance to roam\nFlap: Flap wings\nHelp: get notecard",["Range","Flap","Help","Home","Time","Ferd"],listen_chan);
67 }
68
69
70 rotation GetRotation(rotation rot)
71 {
72 vector Fwd;
73 Fwd = llRot2Fwd(rot);
74
75 float Angle = llAtan2( Fwd.y, Fwd.x );
76 return gFwdRot * llAxisAngle2Rot(<0, 0, 1>, Angle);
77 }
78
79 rotation GetFwdRot()
80 {
81 // Special case... 180 degrees gives a math error
82 if(FWD_DIRECTION == "-x")
83 {
84 return llAxisAngle2Rot(<0, 0, 1>, PI);
85 }
86
87 string Direction = llGetSubString(FWD_DIRECTION, 0, 0);
88 string Axis = llToLower(llGetSubString(FWD_DIRECTION, 1, 1));
89
90 vector Fwd;
91 if(Axis == "x")
92 Fwd = <1, 0, 0>;
93 else if(Axis == "y")
94 Fwd = <0, 1, 0>;
95 else
96 Fwd = <0, 0, 1>;
97
98 if(Direction == "-")
99 Fwd *= -1;
100
101 return llRotBetween(Fwd, <1, 0, 0>);
102 }
103
104
105 CheckDir()
106 {
107 vector currPos = llGetPos();
108 if(currPos.z > Destination.z)
109 {
110 direction = down_vel;
111 // if(debug) llOwnerSay("D");
112 }
113 else
114 {
115 direction = up_vel;
116 //if(debug) llOwnerSay("U");
117 }
118
119 if(! SeekingFish)
120 {
121 // go no lower than the rez point plus some slop
122 if(currPos.z < rezpoint.z )
123 {
124 //if(debug) llOwnerSay("U");
125 Destination.z = rezpoint.z + 1.0;
126 direction = up_vel;
127 }
128 }
129 }
130
131 // Move to a position far away from the current one.
132 MoveTo(vector target)
133 {
134 vector Pos = llGetPos();
135
136 while(llVecDist(Pos, target) > .1)
137 {
138 Pos += llVecNorm(target - Pos) * MOVETO_INCREMENT;
139 llSetPos(Pos);
140 }
141 llSetPos(target);
142 }
143
144
145 DoMove()
146 {
147 integer selected;
148
149 CheckDir();
150
152 llRotLookAt(llRotBetween(<1,0,0>, Destination - llGetPos()), STRENGTH, DAMPING);
153 llSleep(DAMPING*3);
155 llSleep(.1);
157 }
158
159
160 NewDest()
161 {
162 // random direction
163 Destination = llGetPos();
164 Destination.x += llFrand(roam_range) - 0.5 * roam_range;
165 Destination.y += llFrand(roam_range) - 0.5 * roam_range;
166 Destination.z += (llFrand(1.0) -.5 ) + .5;
167
168 if(Destination.z < rezpoint.z )
169 {
170 Destination.z = rezpoint.z + 4.0;
171 direction = up_vel;
172 }
173 }
174
175
176 Fly()
177 {
178
179 if(debug ) llOwnerSay("Fly");
180
181 Flying = 1;
182 i = 50;
183 STRENGTH = MAX; // how hard to turn
184
185 NewDest();
186
187 SeekingFish = FALSE;
188 llSensorRepeat("Rainbow Trout","", ACTIVE|PASSIVE|SCRIPTED, 96, PI, 10.0);
189
191 llMessageLinked(LINK_SET,0,"FLY",""); // hop up
192 movement = 0;
193 llSetTimerEvent(.1); // fast
194 }
195
196 default
197 {
198
200 {
202 }
203
205 {
207 gOwner = llGetOwner();
208 gFwdRot = GetFwdRot();
209 gMass = llGetMass();
210 gTau = 0.4;
211
212 llMessageLinked(LINK_SET,0,"SIT",""); // hop up
214 llSetBuoyancy(0.8);
215 rezpoint = llGetPos();
216 rezrot = llGetRot();
217
218
221 llGroundRepel(2.0, TRUE, 0.2);
228 llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, .1);
231 llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, .1);
232
235
238
241
242 atimer = 60;
243 llOwnerSay("Flight range is 10 meters. Timer is 1 minute. Click bird when it flies to change settings");
245
246 }
247
249 {
251 {
252 llStartAnimation("Perch");
253 state Avatar;
254 }
255 else
256 {
257 state moving;
258 }
259 }
260
261 }
262
263
264
265
266 state moving
267 {
268
270 {
272 }
273
274 timer()
275 {
276
277
278 if(debug) llOwnerSay("Flying = " + (string) Flying);
279
280 if(! Flying)
281 {
282 if(debug ) llOwnerSay("Was not flying");
283 Fly();
284 }
285
286 if(--i == 0)
287 {
288 if(debug ) llOwnerSay("Too long");
289 SeekingFish = FALSE;
290 i = 50;
291 Flying ++; // force HOME
292 Destination = rezpoint;
293 STRENGTH = MIN; // turn sharply
294 }
295
296
297 DoMove();
298
299 if(llVecDist(Destination,llGetPos()) < 2)
300 {
301 if(debug) llOwnerSay("At Dest");
302 i = 50;
303 Flying++;
304 }
305
306 if(! SeekingFish && Flying < 8)
307 {
308 if((integer) i % 10 == 0)
309 {
310 NewDest();
311 if(debug ) llOwnerSay("New dest");
312 }
313
314 if((llVecDist(rezpoint,llGetPos()) > roam_range) )
315 {
316 if(debug ) llOwnerSay("Too far");
317 Destination = rezpoint;
318 Flying++;
319 STRENGTH = MIN; // turn sharply
320 }
321 }
322
323
324 if(SeekingFish && llVecDist(Destination,llGetPos()) < 2)
325 {
326 if(debug ) llOwnerSay("Caught Fish");
327 llPlaySound("Bald Eagle Cry",1.0);
328 llWhisper(2222,"fish");
329
330 llMessageLinked(LINK_SET,0,"SIT",""); // grab the fish
331 llMessageLinked(LINK_SET,0,"FISH",""); // grab the fish
332 SeekingFish = FALSE;
333 Flying = 8;
334 i=50; // need some time to get home
335 }
336
337 if(Flying == 9)
338 {
339 Flying = FALSE;
340
341 state Avatar;
342 }
343
344 }
345
347 {
348 Fly(); // Fly at startup
349 }
350
351
352 sensor(integer total_number)
353 {
354 if(debug ) llOwnerSay("Found Fish");
355 llPlaySound("Bald Eagle Call",1.0);
356 Destination = llDetectedPos(0);
357 Destination.z += 2.0;
358 SeekingFish = TRUE;
360 STRENGTH = 1.0; // how hard to turn
361 i = 50; // need time to catch a fish
362 }
363
365 {
367 {
368 listen_chan=llCeil(llFrand(10000) + 10000);
369 Dialog();
370 }
371 else
372 {
373 if(atimer)
374 Fly();
375 }
376 }
377
378 listen(integer channel,string name, key id, string msg)
379 {
380 if(msg == "Range")
381 {
382 llDialog(llGetOwner(),"Range from Avatar in meters",["10","15","20","25","30","35","40","45","50"],listen_chan);
383 flag = "R";
384 }
385 else if((integer) msg >= 10 && flag == "R")
386 {
387 roam_range = (integer) msg;
388 flag = "";
389 Dialog();
390 }
391
392 else if(msg == "Help")
394 else if(msg == "Flap")
395 {
396 llMessageLinked(LINK_SET,0,"FLAP",""); // hop up
397 llPlaySound("Bald Eagle Cry",1.0);
398 Dialog();
399 }
400 else if(msg == "Home")
401 {
402 rezpoint = llGetPos();
403 llOwnerSay("Position is set to " + (string) rezpoint);
404 Dialog();
405 }
406 else if(msg =="Time")
407 {
408 llDialog(llGetOwner(),"How often they auto fly in seconds",["Off","15s","30s","1min","2min","3min","5min","15min","hour"],listen_chan);
409 }
410 else if(msg =="Off")
411 {
412 atimer = 0;
413 }
414 else if(msg =="15s")
415 atimer = 15;
416 else if(msg =="30s")
417 atimer = 30;
418 else if(msg =="1min")
419 atimer = 60;
420 else if(msg =="2min")
421 atimer = 120;
422 else if(msg =="5min")
423 atimer = 300;
424 else if(msg =="15min")
425 atimer = 900;
426 else if(msg =="hour")
427 atimer = 3600;
428
429 else if(msg =="Ferd")
430 llLoadURL(llGetOwner(),"More Info about Ferd Frederix","http://secondlife.mitsi.com");
431
432 llOwnerSay("Flight range is " + (string) roam_range + " meters. ");
433 if(atimer)
434 llOwnerSay("The bird will fly every " + (string) atimer + " seconds");
435 else
436 llOwnerSay("The bird will fly only when you touch it");
437
438 if(! Flying)
439 {
440 llSetTimerEvent(atimer);
441 }
442 }
443 }
444
445
446
447 state setposition //contingency
448 {
450 {
451 if(debug)llOwnerSay("Oops, forcing home");
452 llSetTimerEvent(INTERVAL);
453 }
454
456 {
458 }
459
460 timer()
461 {
462 if(llVecMag(llGetPos() - rezpoint) > 5)
463 {
464 llSetPos((llVecNorm(Destination - llGetPos()) * 0.5) + llGetPos());
465 }
466 else
467 {
468 llSetRot(rezrot);
469 llSetPos(rezpoint);
470 if(debug)llOwnerSay("Homed");
471 llMessageLinked(LINK_SET,0,"SIT",""); // hop up
472 state moving;
473 }
474
475 }
477 {
479 }
480
481 }
482
483
484 state Avatar
485 {
487 {
488 seek = TRUE;
489 llSetStatus(STATUS_PHANTOM, TRUE);
490 llSetTimerEvent(atimer);
492 llSensorRepeat("", gOwner, AGENT, 20.0, PI, SCAN_REFRESH);
493 llMoveToTarget(llGetPos(), gTau);
494 }
495
496
497 timer()
498 {
499 state moving;
500 }
501
502 touch_start(integer num_detected)
503 {
504
505 state moving;
506 }
507
509 {
510 rezpoint = llGetPos();
514 llStopAnimation("Perch");
515 }
516
517 sensor(integer num_detected)
518 {
519
520 rotation TargetRot;
521 Pos = llDetectedPos(0);
522
523 rotation Rot = llDetectedRot(0);
526 string anim = llGetAnimation(gOwner);
527
529
530
531 if((anim != "Standing") || llListFindList(anims,[(key)("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9")]) != -1)
532 {
533 llStopAnimation("Perch");
534 POSITION_OFFSET = <0.0, -.4, (size.z /2) + 1>;
535 if(flag2++ % 2 == 0) {
536 llSetPos(llGetPos() + <0,0,.1>);
537 llMessageLinked(LINK_SET,0,"FLY",""); // grab the fish
538 }
539 else
540 {
541 llSetPos(llGetPos() + <0,0,-.1>);
542 llMessageLinked(LINK_SET,0,"FLAP",""); // grab the fish
543 }
544
545
546 }
547 else
548 {
549 POSITION_OFFSET = <0, -.4, (size.z /2) +.3>;
550 //POSITION_OFFSET = <0, 0, 0>;
551 llMessageLinked(LINK_SET,0,"SIT",""); // grab the fish
552 llStartAnimation("Perch");
553 }
554
555 TargetRot = GetRotation(Rot);
556 vector Offset = POSITION_OFFSET * Rot;
557 Pos += Offset;
558
559 if(llVecDist(Pos,llGetPos()) > .5)
560 {
562 llMoveToTarget(Pos,0.2);
563 llRotLookAt(TargetRot, 0.2 , 0.050);
564 movement++;
565 }
566 else
567 {
568 if(movement)
569 {
571 //llStopLookAt();
573 //rotation xyz_angles = llEuler2Rot(<0,0,0> * DEG_TO_RAD);
574 //llSetRot(llGetRot()*xyz_angles); //Do the Rotation...
575 llSetPos(Pos);
576 movement = 0;
577 }
578
579 }
580 count=0;
581 repeat=0;
582 }
583
584
585
586 no_sensor()
587 {
588 llMessageLinked(LINK_SET,0,"FLY",""); // grab the fish
589
590 count += 1;
591 if(count > 150)
592 {
593 repeat += 1;
595 string pos = (string)llGetPos();
596 string simName=llGetRegionName();
597 if(repeat < 2)
598 {
599 llInstantMessage(llGetOwner(),name + ", I am lost at:" + simName + pos + ". Please come and get me !");
600 }
601 else
602 {
603 llInstantMessage(llGetOwner(),name + ", This one will go to bed !");
604 llDie();
605 }
606 count=0;
607 }
608 }
609
610
611 on_rez(integer start_param)
612 {
614 }
615 }

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