Script.lsl 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. // :CATEGORY:Pets
  2. // :NAME:Kevin the Bird pet follower
  3. // :AUTHOR:Ferd Frederix
  4. // :CREATED:2013-12-17 10:52:05
  5. // :EDITED:2013-12-17 10:52:05
  6. // :ID:1007
  7. // :NUM:1559
  8. // :REV:1
  9. // :WORLD:Second Life
  10. // :DESCRIPTION:
  11. // This is from Kevin the bird - a Pet follower. It stays in one area and runs and up yells hello.
  12. // :CODE:
  13. ////////////////////////////////////////////
  14. // Follow Me Script
  15. //
  16. // Written by Xylor Baysklef
  17. // Adapted and added by Garth Fairlight
  18. // Adapted by Ferd Frederix
  19. ////////////////////////////////////////////
  20. float DIST = 10; // how far to sense avatars
  21. string GREET = "39d0abf5-8921-8317-915c-2efcc87e0bfe"; // a sound for Meow
  22. string BYE = "0098ae21-325a-ae76-522f-f66e844471c6"; // a sound for a meow
  23. float X = -2.0; // usually tyhis far back
  24. float Y = .0; // rugth in the mioddle
  25. float posX;
  26. float posY;
  27. vector POSITION_OFFSET = <0.0, 0.75, -0.8>; // Local coords
  28. vector FLY_OFFSET = <2.0, -2.75, 0.0>;
  29. vector FLYANGLE = <80, 0, 10>;
  30. float DAMP = 8; // damping for flight
  31. float TURNSPEED = 10.0;
  32. vector startPos;
  33. rotation startRot;
  34. integer returning;
  35. /////////////// CONSTANTS ///////////////////
  36. vector last;
  37. integer flag;
  38. integer playchannel = 1;
  39. string FWD_DIRECTION = "-y";
  40. float SCAN_REFRESH = 0.2;
  41. string FOLLOW = "/follow";
  42. string STAY = "/stay";
  43. integer FOLLOW_STOP = 5000;
  44. integer FOLLOW_START = 5001;
  45. float MOVETO_INCREMENT = 3.0;
  46. ///////////// END CONSTANTS /////////////////
  47. ///////////// GLOBAL VARIABLES ///////////////
  48. key gOwner;
  49. rotation gFwdRot;
  50. float gTau;
  51. float gMass;
  52. integer count;
  53. integer repeat;
  54. /////////// END GLOBAL VARIABLES /////////////
  55. float randBetween(float min, float max)
  56. {
  57. return llFrand(max - min) + min;
  58. }
  59. help()
  60. {
  61. llWhisper(0,"You can say the following commands:");
  62. llWhisper(0,"/follow <-- I will follow you around");
  63. llWhisper(0,"/stay <-- I will stay where I am.");
  64. llWhisper(0,"/help <-- I will repeat this message.");
  65. llWhisper(0,"if I lose you I will IM my position to you unless");
  66. llWhisper(0,"I am in a no script area, then I can do nothing.");
  67. }
  68. StartScanning()
  69. {
  70. llSetStatus(STATUS_PHYSICS, TRUE);
  71. llSensorRepeat("", "", AGENT, DIST, PI, SCAN_REFRESH);
  72. }
  73. StopScanning()
  74. {
  75. llSetStatus(STATUS_PHYSICS, FALSE);
  76. llSensorRemove();
  77. }
  78. // Move to a position far away from the current one.
  79. MoveTo(vector target)
  80. {
  81. vector Pos = llGetPos();
  82. while (llVecDist(Pos, target) > MOVETO_INCREMENT)
  83. {
  84. Pos += llVecNorm(target - Pos) * MOVETO_INCREMENT;
  85. llSetPos(Pos);
  86. }
  87. llSetPos(target);
  88. }
  89. rotation GetFwdRot()
  90. {
  91. // Special case... 180 degrees gives a math error
  92. if (FWD_DIRECTION == "-x")
  93. {
  94. return llAxisAngle2Rot(<0, 0, 1>, PI);
  95. }
  96. string Direction = llGetSubString(FWD_DIRECTION, 0, 0);
  97. string Axis = llToLower(llGetSubString(FWD_DIRECTION, 1, 1));
  98. vector Fwd;
  99. if (Axis == "x")
  100. Fwd = <1, 0, 0>;
  101. else if (Axis == "y")
  102. Fwd = <0, 1, 0>;
  103. else
  104. Fwd = <0, 0, 1>;
  105. if (Direction == "-")
  106. Fwd *= -1;
  107. return llRotBetween(Fwd, <1, 0, 0>);
  108. }
  109. rotation GetRotation(rotation rot)
  110. {
  111. vector Fwd;
  112. Fwd = llRot2Fwd(rot);
  113. float Angle = llAtan2( Fwd.y, Fwd.x );
  114. return gFwdRot * llAxisAngle2Rot(<0, 0, 1>, Angle);
  115. }
  116. default
  117. {
  118. state_entry()
  119. {
  120. posX = X;
  121. posY = Y;
  122. startPos = llGetPos();
  123. startRot = llGetRot();
  124. llCollisionSound("",0);
  125. llSetStatus(STATUS_PHANTOM, TRUE);
  126. gOwner = llGetOwner();
  127. gFwdRot = GetFwdRot();
  128. gMass = llGetMass();
  129. gTau = 0.2;
  130. llListen(0, "", "", "");
  131. llSetTimerEvent(1.5);
  132. StartScanning();
  133. llMoveToTarget(llGetPos(), gTau);
  134. }
  135. sensor(integer num_detected)
  136. {
  137. rotation TargetRot;
  138. vector Pos = llDetectedPos(0);
  139. rotation Rot = llDetectedRot(0);
  140. vector size = llGetAgentSize(llDetectedKey(0));
  141. if((llGetAnimation(gOwner) == "Flying") || (llGetAnimation(gOwner) == "FlyingSlow"))
  142. {
  143. TargetRot = llEuler2Rot( FLYANGLE * DEG_TO_RAD) * GetRotation(Rot);
  144. POSITION_OFFSET = FLY_OFFSET;
  145. llMessageLinked(LINK_THIS, playchannel, "fly", "");
  146. }
  147. else
  148. {
  149. TargetRot = GetRotation(Rot);
  150. // update randimly sometimes
  151. if (llFrand(4) < 1)
  152. {
  153. posX = randBetween(0,X);
  154. posY = randBetween(0,2);
  155. if (llFrand(1) > 0.5)
  156. posY = -posY;
  157. }
  158. POSITION_OFFSET = <posX , posY, (-size.z / 2) + 0.1>;
  159. vector pos = llGetPos();
  160. if (llVecDist(pos, last) > 1)
  161. {
  162. last = pos;
  163. if (flag == 0) {
  164. llMessageLinked(LINK_THIS, playchannel, "stand", "");
  165. llSleep(1.0);
  166. }
  167. llMessageLinked(LINK_THIS, playchannel, "walk", "");
  168. flag++;
  169. }
  170. else
  171. {
  172. if (flag)
  173. {
  174. llMessageLinked(LINK_THIS, playchannel, "sit", "");
  175. flag = 0;
  176. }
  177. }
  178. }
  179. vector Offset = POSITION_OFFSET * Rot;
  180. Pos += Offset;
  181. if (llVecDist(startPos,Pos ) > DIST)
  182. {
  183. if (returning)
  184. {
  185. llTriggerSound(BYE,1.0);
  186. returning = FALSE;
  187. }
  188. //llLookAt(startPos,gTau * TURNSPEED, gTau);
  189. llRotLookAt(startRot, gTau * TURNSPEED, gTau);
  190. llMoveToTarget(startPos, gTau * DAMP);
  191. }
  192. else
  193. {
  194. if (! returning)
  195. {
  196. llTriggerSound(GREET,1.0);
  197. returning = TRUE;
  198. }
  199. //llLookAt(Pos,gTau * TURNSPEED, gTau);
  200. llRotLookAt(TargetRot, gTau * TURNSPEED, gTau);
  201. llMoveToTarget(Pos, gTau * DAMP);
  202. }
  203. count=0;
  204. repeat=0;
  205. }
  206. listen(integer channel, string name, key id, string mesg)
  207. {
  208. mesg = llToLower(mesg);
  209. if ((id == gOwner) && (mesg == FOLLOW))
  210. {
  211. StartScanning();
  212. }
  213. else if ((id == gOwner) && (mesg == STAY))
  214. {
  215. StopScanning();
  216. }
  217. else if ((id == gOwner) && (mesg == "/help"))
  218. {
  219. help();
  220. }
  221. else
  222. {
  223. integer stop;
  224. string word;
  225. integer check = FALSE;
  226. if((id==gOwner) || (name == llGetObjectName())) { check=TRUE;}
  227. if(check == FALSE)
  228. {
  229. do
  230. {
  231. stop = llSubStringIndex(mesg, " ");
  232. if(stop == -1) { stop = 0;}
  233. word = llGetSubString(mesg, 0, stop - 1);
  234. mesg = llDeleteSubString(mesg, 0, stop);
  235. if((word=="brb") || (word=="afk"))
  236. {
  237. llSay(0,"We wait, hurry back !");
  238. stop = 0;
  239. }
  240. else if((word=="smoke") || (word=="joint"))
  241. {
  242. llSay(0,"Can this one smoke?");
  243. stop = 0;
  244. }
  245. else if((word=="cool") || (word=="kewl"))
  246. {
  247. llSay(0,word + ", yes yes yes ");
  248. stop = 0;
  249. }
  250. else if((word=="hi") || (word=="hello") || (word=="Greetings") || (word=="howdy") || (word=="Gday") || (word=="hej"))
  251. {
  252. llSay(0,word + " " + name + ", :)");
  253. stop = 0;
  254. }
  255. else if((word=="cya") || (word=="bye") || (word=="goodbye"))
  256. {
  257. llSay(0,word + " " + name + " :)");
  258. stop = 0;
  259. }
  260. else if((word=="food") || (word=="eat") || (word=="ate"))
  261. {
  262. float rnd = llFrand(10.0);
  263. if(rnd < 5) { llSay(0,"Can this one eat too?");}
  264. else { llSay(0,name + ", This one is hungry !");}
  265. stop = 0;
  266. }
  267. else if((word=="fuck") || (word=="Fuck") || (word=="FUCK"))
  268. {
  269. llSay(0,"Ewwww, the F word");
  270. stop = 0;
  271. }
  272. } while(stop != 0);
  273. }
  274. }
  275. }
  276. touch_start(integer num)
  277. {
  278. integer choice = (integer)llFrand(6.0);
  279. if(choice == 1) { llSay(0,"ALT+F4 will fix u Lag!");}
  280. else if(choice == 2) { llSay(0,"They touch this one!");}
  281. else if(choice == 3) { llSay(0,"Piss off !");}
  282. else if(choice == 4) { llSay(0,"U not my Master!");}
  283. else if(choice == 5) { llSay(0,"Dont touch my dick, plz !");}
  284. else { llSay(0,"Go play with u self !");}
  285. }
  286. on_rez(integer start_param)
  287. {
  288. llResetScript();
  289. }
  290. }