470 lines
12 KiB
Plaintext
470 lines
12 KiB
Plaintext
// :CATEGORY:Bird
|
|
// :NAME:Roaming Owl
|
|
// :AUTHOR:Fred Beckhusen (Ferd Frederix)
|
|
// :CREATED:2013-09-06
|
|
// :EDITED:2013-09-18 15:39:01
|
|
// :ID:707
|
|
// :NUM:966
|
|
// :REV:1
|
|
// :WORLD:Second Life
|
|
// :DESCRIPTION:
|
|
// main script
|
|
// :CODE:
|
|
|
|
// ______ _ ______ _ _
|
|
// | ___| | | | ___| | | (_)
|
|
// | |_ ___ _ __ __| | | |_ _ __ ___ __| | ___ _ __ ___ __
|
|
// | _/ _ \ '__/ _` | | _| '__/ _ \/ _` |/ _ \ '__| \ \/ /
|
|
// | || __/ | | (_| | | | | | | __/ (_| | __/ | | |> <
|
|
// \_| \___|_| \__,_| \_| |_| \___|\__,_|\___|_| |_/_/\_\
|
|
//
|
|
// fred@mitsi.com
|
|
// owl bird script
|
|
//
|
|
//Revisions:
|
|
// 1/28/2010 initial release
|
|
|
|
string CRY = "Bubo-virginianus";
|
|
string SHORT = "Bubo-virginianus short";
|
|
string SURPRISE = "Scotopelia-peli";
|
|
string prey = "Squirrel and feeder";
|
|
|
|
|
|
// fly sit, catch land
|
|
|
|
integer debug = 0;
|
|
vector rezpoint; // home point
|
|
rotation rezrot;
|
|
integer Flying;
|
|
|
|
integer listen_chan;
|
|
integer listener;
|
|
float i ; //counter for timer moving
|
|
vector up_vel = <10,0,9>; // speed and direction away
|
|
vector down_vel = <6,0,-8>; // and to go home, small numbers for less speed and mass objects
|
|
float STRENGTH = 2.0; // how hard to turn
|
|
float DAMPING = 0.2; // and how soon
|
|
float MAX = 3.0; // MAX strength ( slow turns)
|
|
float MIN = 1.0; // fast turns
|
|
|
|
float timerate = 0.215;
|
|
float roam_range = 10; // default range
|
|
string flag ; // what menu item thay need integers for
|
|
|
|
|
|
|
|
|
|
|
|
vector direction;
|
|
vector Destination;
|
|
float atimer;
|
|
float INTERVAL = .050; // seconds to move
|
|
integer SeekingFish = FALSE;
|
|
|
|
Dialog()
|
|
{
|
|
listener = llListen(listen_chan,"","","");
|
|
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);
|
|
}
|
|
|
|
CheckDir()
|
|
{
|
|
vector currPos = llGetPos();
|
|
if (currPos.z > Destination.z)
|
|
{
|
|
direction = down_vel;
|
|
// if (debug) llOwnerSay("D");
|
|
}
|
|
else
|
|
{
|
|
direction = up_vel;
|
|
//if (debug) llOwnerSay("U");
|
|
}
|
|
|
|
if (! SeekingFish)
|
|
{
|
|
// go no lower than the rez point plus some slop
|
|
if (currPos.z < rezpoint.z )
|
|
{
|
|
//if (debug) llOwnerSay("U");
|
|
Destination.z = rezpoint.z + 1.0;
|
|
direction = up_vel;
|
|
}
|
|
}
|
|
}
|
|
|
|
DoMove()
|
|
{
|
|
|
|
|
|
llMessageLinked(LINK_SET,1,"flap",""); // hop up
|
|
CheckDir();
|
|
|
|
//llSetStatus(STATUS_PHYSICS, TRUE);
|
|
//llStopLookAt();
|
|
llRotLookAt(llRotBetween(<1,0,0>, Destination - llGetPos()), STRENGTH, DAMPING);
|
|
llSleep(DAMPING*3);
|
|
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, 1 * direction);
|
|
llSleep(.1);
|
|
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, ZERO_VECTOR);
|
|
//llSetStatus(STATUS_PHYSICS, FALSE);
|
|
|
|
|
|
}
|
|
|
|
|
|
NewDest()
|
|
{
|
|
// random direction
|
|
Destination = llGetPos();
|
|
Destination.x += llFrand(roam_range) - 0.5 * roam_range;
|
|
Destination.y += llFrand(roam_range) - 0.5 * roam_range;
|
|
Destination.z += (llFrand(1.0) -.5 ) + .5;
|
|
|
|
if (Destination.z < rezpoint.z )
|
|
{
|
|
Destination.z = rezpoint.z + 4.0;
|
|
direction = up_vel;
|
|
}
|
|
}
|
|
|
|
|
|
Fly()
|
|
{
|
|
if (debug ) llOwnerSay("Fly");
|
|
|
|
Flying = 1;
|
|
i = 50;
|
|
STRENGTH = MAX; // how hard to turn
|
|
|
|
NewDest();
|
|
|
|
llPlaySound(CRY,1.0);
|
|
|
|
SeekingFish = FALSE;
|
|
llSensorRepeat(prey,"", ACTIVE|PASSIVE|SCRIPTED, 96, PI, 10.0);
|
|
|
|
llSetStatus(STATUS_PHYSICS, TRUE);
|
|
llMessageLinked(LINK_SET,1,"fly",""); // hop up
|
|
|
|
llSetTimerEvent(.1); // fast
|
|
}
|
|
|
|
default
|
|
{
|
|
|
|
on_rez(integer a)
|
|
{
|
|
llResetScript();
|
|
}
|
|
|
|
state_entry()
|
|
{
|
|
llMessageLinked(LINK_SET,1,"sit",""); // hop up
|
|
llSetStatus(STATUS_DIE_AT_EDGE,TRUE);
|
|
llSetBuoyancy(0.8);
|
|
rezpoint = llGetPos();
|
|
rezrot = llGetRot();
|
|
|
|
llSetStatus(STATUS_PHYSICS, FALSE);
|
|
llSetVehicleFlags(-1);
|
|
llSetVehicleType(VEHICLE_TYPE_CAR);
|
|
|
|
llRemoveVehicleFlags(VEHICLE_FLAG_LIMIT_MOTOR_UP | VEHICLE_FLAG_LIMIT_ROLL_ONLY);
|
|
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.8);
|
|
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.8);
|
|
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, .1);
|
|
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, .1);
|
|
llSetVehicleFloatParam(VEHICLE_HOVER_EFFICIENCY, 0.8); // hover
|
|
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, .1);
|
|
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, .1);
|
|
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, .1);
|
|
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, .1);
|
|
|
|
llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1.0, .1, 1000.0>);
|
|
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <.1, .1, .1>);
|
|
|
|
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, .8);
|
|
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, .1);
|
|
|
|
llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.25);
|
|
llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.1);
|
|
llGroundRepel(2.0, TRUE, 0.2);
|
|
|
|
|
|
|
|
atimer = 60;
|
|
llOwnerSay("Flight range is 10 meters. Timer is 1 minute. Click bird to change settings");
|
|
state moving;
|
|
}
|
|
}
|
|
|
|
|
|
state moving
|
|
{
|
|
|
|
on_rez(integer a)
|
|
{
|
|
llResetScript();
|
|
}
|
|
|
|
timer()
|
|
{
|
|
|
|
if (! Flying)
|
|
{
|
|
if (debug ) llOwnerSay("Was not flying");
|
|
Fly();
|
|
}
|
|
|
|
if (--i == 0)
|
|
{
|
|
if (debug ) llOwnerSay("Too long");
|
|
SeekingFish = FALSE;
|
|
i = 50;
|
|
Flying ++; // force HOME
|
|
Destination = rezpoint;
|
|
llPlaySound(CRY,1.0);
|
|
STRENGTH = MIN; // turn sharply
|
|
}
|
|
|
|
|
|
DoMove();
|
|
|
|
if (llVecDist(Destination,llGetPos()) < 2)
|
|
{
|
|
if (debug) llOwnerSay("At Dest");
|
|
i = 50;
|
|
Flying++;
|
|
}
|
|
|
|
if (! SeekingFish && Flying < 8)
|
|
{
|
|
if ((integer) i % 10 == 0)
|
|
{
|
|
NewDest();
|
|
if (debug ) llOwnerSay("New dest");
|
|
}
|
|
|
|
if ((llVecDist(rezpoint,llGetPos()) > roam_range) )
|
|
{
|
|
if (debug ) llOwnerSay("Too far");
|
|
Destination = rezpoint;
|
|
Flying++;
|
|
STRENGTH = MIN; // turn sharply
|
|
llPlaySound(CRY,1.0);
|
|
}
|
|
}
|
|
|
|
|
|
if (SeekingFish && llVecDist(Destination,llGetPos()) < 2)
|
|
{
|
|
if (debug ) llOwnerSay("Caught Fish");
|
|
llPlaySound(SURPRISE,1.0);
|
|
llWhisper(2222,"fish");
|
|
|
|
//llMessageLinked(LINK_SET,1,"sit",""); // grab the fish
|
|
llMessageLinked(LINK_SET,1,"catch",""); // grab the fish
|
|
SeekingFish = FALSE;
|
|
Flying = 8;
|
|
i=50; // need some time to get home
|
|
}
|
|
|
|
if (Flying == 9)
|
|
{
|
|
// back on the ground
|
|
Destination = rezpoint;
|
|
i=50;
|
|
|
|
if (debug ) llOwnerSay("Heading Home");
|
|
}
|
|
|
|
if (Flying >= 10)
|
|
{
|
|
|
|
float dist = llVecDist(rezpoint,llGetPos());
|
|
|
|
// if (dist < 2)
|
|
// {
|
|
llMessageLinked(LINK_SET,1,"land",""); // hop up
|
|
// }
|
|
llPlaySound(SHORT,1.0);
|
|
|
|
llSleep(0.5);
|
|
|
|
llSetStatus(STATUS_PHYSICS, FALSE);
|
|
llMessageLinked(LINK_SET,1,"sit",""); // hop up
|
|
|
|
llSetRot(rezrot);
|
|
llSetPos(rezpoint);
|
|
|
|
|
|
// we may not have made it home, could have run into something
|
|
if (dist > 1)
|
|
{
|
|
if (debug) llOwnerSay("Forced Home");
|
|
state setposition; //contingency
|
|
}
|
|
//if(debug) llOwnerSay("At Home");
|
|
|
|
SeekingFish = FALSE;
|
|
Flying = 0;
|
|
llSetTimerEvent(atimer);
|
|
|
|
llSensorRepeat("","",AGENT,roam_range,PI,5);
|
|
|
|
}
|
|
}
|
|
|
|
state_entry()
|
|
{
|
|
llSensorRepeat("","",AGENT,roam_range,PI,5);
|
|
SeekingFish = FALSE;
|
|
Fly(); // Fly at startup
|
|
}
|
|
|
|
|
|
|
|
|
|
sensor(integer total_number)
|
|
{
|
|
if (Flying)
|
|
{
|
|
if (debug ) llOwnerSay("Found Fish");
|
|
llPlaySound(SURPRISE,1.0);
|
|
Destination = llDetectedPos(0);
|
|
Destination.z += 2.0;
|
|
SeekingFish = TRUE;
|
|
llSensorRemove();
|
|
STRENGTH = 1.0; // how hard to turn
|
|
i = 50; // need time to catch a fish
|
|
}
|
|
else
|
|
{
|
|
if (atimer)
|
|
Fly();
|
|
}
|
|
}
|
|
|
|
touch_start(integer a)
|
|
{
|
|
if (llDetectedKey(0) == llGetOwner())
|
|
{
|
|
listen_chan=llCeil(llFrand(10000) + 10000);
|
|
Dialog();
|
|
}
|
|
else
|
|
{
|
|
if (atimer)
|
|
Fly();
|
|
}
|
|
}
|
|
|
|
listen(integer channel,string name, key id, string msg)
|
|
{
|
|
if (msg == "Range")
|
|
{
|
|
llDialog(llGetOwner(),"Range from Home place in meters",["10","15","20","25","30","35","40","45","50"],listen_chan);
|
|
flag = "R";
|
|
}
|
|
else if ((integer) msg >= 10 && flag == "R")
|
|
{
|
|
roam_range = (integer) msg;
|
|
flag = "";
|
|
Dialog();
|
|
}
|
|
|
|
else if (msg == "Help")
|
|
llGiveInventory(llGetOwner(),"Help");
|
|
else if (msg == "Flap")
|
|
{
|
|
llMessageLinked(LINK_SET,1,"land",""); // hop up
|
|
llPlaySound(CRY,1.0);
|
|
llSleep(1); // time to see it
|
|
llMessageLinked(LINK_SET,1,"sit",""); // hop up
|
|
Dialog();
|
|
}
|
|
else if (msg == "Home")
|
|
{
|
|
rezpoint = llGetPos();
|
|
llOwnerSay("Position is set to " + (string) rezpoint);
|
|
Dialog();
|
|
}
|
|
else if (msg =="Time")
|
|
{
|
|
llDialog(llGetOwner(),"How often they auto fly in seconds",["Off","15s","30s","1min","2min","3min","5min","15min","hour"],listen_chan);
|
|
}
|
|
else if (msg =="Off")
|
|
{
|
|
atimer = 0;
|
|
}
|
|
else if (msg =="15s")
|
|
atimer = 15;
|
|
else if (msg =="30s")
|
|
atimer = 30;
|
|
else if (msg =="1min")
|
|
atimer = 60;
|
|
else if (msg =="2min")
|
|
atimer = 120;
|
|
else if (msg =="5min")
|
|
atimer = 300;
|
|
else if (msg =="15min")
|
|
atimer = 900;
|
|
else if (msg =="hour")
|
|
atimer = 3600;
|
|
|
|
else if (msg =="Ferd")
|
|
llLoadURL(llGetOwner(),"More Info at our web site","http://secondlife.mitsi.com");
|
|
|
|
llOwnerSay("Flight range is " + (string) roam_range + " meters. ");
|
|
if (atimer)
|
|
llOwnerSay("The bird will fly every " + (string) atimer + " seconds");
|
|
else
|
|
llOwnerSay("The bird will fly only when someone is near");
|
|
|
|
if (! Flying)
|
|
{
|
|
llSetTimerEvent(atimer);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
state setposition //contingency
|
|
{
|
|
state_entry()
|
|
{
|
|
if (debug)llOwnerSay("Oops, forcing home");
|
|
llSetTimerEvent(INTERVAL);
|
|
}
|
|
|
|
on_rez(integer a)
|
|
{
|
|
llResetScript();
|
|
}
|
|
|
|
timer()
|
|
{
|
|
if (llVecMag(llGetPos() - rezpoint) > 5)
|
|
{
|
|
llSetPos((llVecNorm(Destination - llGetPos()) * 0.5) + llGetPos());
|
|
}
|
|
else
|
|
{
|
|
llSetRot(rezrot);
|
|
llSetPos(rezpoint);
|
|
if (debug)llOwnerSay("Homed");
|
|
llMessageLinked(LINK_SET,1,"sit",""); // hop up
|
|
state moving;
|
|
}
|
|
|
|
}
|
|
state_exit()
|
|
{
|
|
llSetTimerEvent(0);
|
|
}
|
|
|
|
}
|
|
|