SHARE
TWEET

Simple PF/KFM Roving Seat

N3K0 Sep 15th, 2019 (edited) 106 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     o   o o-o  o  o  o-o  o-O-o o-o    o-o o  o                 Roving Seat (F+KF)
  3.     |\  |    | | /  o  /o   |      |  /    |  |            By Motleypuss@email.com
  4.     | \ |  oo  OO   | / |   |    oo  O     O--O
  5.     |  \|    | | \  o/  o   |      |  \    |  |                 Created 2019.09.10
  6.     o   o o-o  o  o  o-o    o   o-o    o-o o  o                Modified 2019.09.23
  7.    
  8.   This is a simple roving seat. Given a Notecard containing vectors which repres-
  9.   ent locations of interest, the seat will travel between each destination in a
  10.   random order, with the path it takes being controlled by The Lab's pathfinding
  11.   system.
  12. */
  13. integer debug_this_shit    = FALSE;              /*TRUE to enable debug.*/
  14. string  kcd                = "*Destinations";    /*Destination NCD name.*/
  15. integer degrees_per_second = 45;                 /*Degrees turned per second.*/
  16. integer metres_per_second  = 1;                  /*Metres moved per second.*/
  17. integer arsehole_time      = 120;                /*Timeout before new path.*/
  18. float   navmesh_offset     = 1.0;                /*Z offset from navmesh.*/
  19. float   point_ignore_dist  = 0.5;                /*Skip distance.*/
  20. /*##############################################################################*/
  21. D(string t){/*Prints a debug message (if debug_this_shit is TRUE).*/
  22.   if(debug_this_shit){llOwnerSay(">DBG "+t);}
  23. }
  24. /*##############################################################################*/
  25. Handout(key k){/*Hands out the second Notecard (if one exists).*/
  26.   if(llGetInventoryName(INVENTORY_NOTECARD,1)!=""){
  27.     llGiveInventory(k,llGetInventoryName(INVENTORY_NOTECARD,1));
  28.   }
  29. }
  30. /*##############################################################################*/
  31. Bar(integer n,integer m){/*Draws a progress bar.*/
  32.   if(n==-1){llSetText(" ",<0,0,0>,0);return;}
  33.   float barLen=20;float my_max=(float)m/barLen;
  34.   float my_n=(float)n;integer i=0;string t;
  35.   while((float)i<barLen){if(i*my_max<=my_n){t+="█";}else{t+="░";}i++;}
  36.   llSetText("Loading local destinations...\n"+t,<1,0,1>,1);
  37. }
  38. /*##############################################################################*/
  39. integer Find(key k){/*Returns link number of avatar, otherwise FaLSE.*/
  40.   integer i=llGetNumberOfPrims(); while(i>1){
  41.   if(llGetLinkKey(i)==k){return i;}i--;}return FALSE;
  42. }
  43. /*##############################################################################*/
  44. Initiate(){/*Initialises the system and kickstarts Notecard load.*/
  45.   points=[];Bar(-1,-1);
  46.   if(llGetInventoryType(kcd)==INVENTORY_NOTECARD){
  47.     kln=0;nln=-99;kid=llGetNumberOfNotecardLines(kcd);Bar(0,100);
  48.     D("Loading Notecard '"+kcd+"'. Please wait.");
  49.   }else{
  50.     llOwnerSay("ERR: Notecard '"+kcd+"' is missing! Roving cannot happen without "+
  51.     "this Notecard!");
  52.   }
  53. }
  54. /*##############################################################################*/
  55. float NormSpd(float Q){/*Normalise a quaternion.*/
  56.   Q/=metres_per_second;float magic=45.0;Q=llRound(magic*Q)/magic;if (Q>0.1){return
  57.   Q;}else{return 0.1;}
  58. }
  59. /*##############################################################################*/
  60. Next(){/*Handles next move or next move+rotation.*/
  61.   llSetTimerEvent(0.0);
  62.   if(!patrolling){return;}
  63.   if(path_pc<llGetListLength(current_path)){
  64.     target=llList2Vector(current_path,path_pc);
  65.     if(llVecDist(target,ZERO_VECTOR)>0.1){
  66.       target+=<0,0,navmesh_offset>;
  67.       vector rp=llGetRootPosition();
  68.       rotation rr=llGetRootRotation();    
  69.       vector t_pos=target-rp;
  70.       float  speed=NormSpd(llVecDist(rp,target));
  71.       if(speed<0.2){speed=0.2;}
  72.       /*Hacky angle motion calculation.*/
  73.       rotation fuck;
  74.       fuck=llRotBetween(<1,0,0>,llVecNorm(<target.x,target.y,0>-<rp.x,rp.y,0> ));
  75.       vector tr=llRot2Euler(fuck)*RAD_TO_DEG;
  76.       vector br=llRot2Euler(rr)*RAD_TO_DEG;
  77.       float angle=llFabs(tr.z-br.z);
  78.       if(angle>180){angle=llFabs(angle-360);}
  79.       /*Either move OR rotate and THEN move.*/
  80.       float rotspeed=NormSpd(llFabs(angle)/(float)degrees_per_second);
  81.       if(angle<5){
  82.         llSetKeyframedMotion([t_pos,ZERO_ROTATION,speed],[]);
  83.       }else{
  84.         if(rotspeed<0.2){rotspeed=0.2;}
  85.         llSetKeyframedMotion([ZERO_VECTOR,fuck/rr,rotspeed,
  86.         t_pos,ZERO_ROTATION,speed],[]);
  87.       }
  88.       D("o Next point "+(string)target+" SPD "+(string)speed+" RSPD "+(string)rotspeed+".");
  89.       llSetTimerEvent(arsehole_time);
  90.     }else{FetchPath(TRUE);}
  91.   }else{FetchPath(TRUE);}
  92. }
  93. /*##############################################################################*/
  94. FetchPath(integer on){/*Picks a random destination and fetches its path.*/
  95.   if(!on){patrolling=FALSE;llSetTimerEvent(0.0);return;}
  96.   current_path=[];path_pc=0;
  97.   integer q=llFloor(llFrand(llGetListLength(points)));
  98.   if(q>=llGetListLength(points)){q=llGetListLength(points)-1;}
  99.   vector v=llList2Vector(points,q);
  100.   current_path=llGetStaticPath(llGetPos(),v,1,[]);
  101.   integer i=0;vector prior;vector p;integer r=0;
  102.   integer result_code = llList2Integer(current_path,-1);
  103.   if(result_code==0){
  104.     current_path=llList2List(current_path,0,-2);/*Remove status code.*/
  105.     p=llList2Vector(current_path,0);
  106.     prior=llGetRootPosition();
  107.     /*Remove redundant additional points. We have to do this backwards to preserve
  108.       the 'latest' path point, since that's usually the one that results in the correct
  109.       rotation.*/
  110.     i=llGetListLength(current_path)-1;
  111.     while(i>-1){
  112.       p=llList2Vector(current_path,i);  
  113.       if(llVecDist(p,prior)<point_ignore_dist){
  114.         current_path=llDeleteSubList(current_path,i,i);r++;
  115.       }
  116.       if(p==ZERO_VECTOR){
  117.         current_path=llDeleteSubList(current_path,i,i);r++;
  118.       }
  119.       prior=p;
  120.       i--;
  121.     }
  122.     D("Removed "+(string)r+" rendundant path point(s).");
  123.     /*Begin execution.*/
  124.     D("Next path: "+llList2CSV(current_path)+".");
  125.     Next();
  126.   }else{
  127.     llOwnerSay( "ERR:"+ (string)v );
  128.     /*Wait a while and then try again.*/
  129.     llSetTimerEvent(1.0);
  130.   }
  131. }
  132. /*##############################################################################*/
  133. integer patrolling=FALSE;key kid=NULL_KEY;integer kln=0;integer loaded=FALSE;
  134. integer nln=1;list current_path=[];integer path_pc=0;vector target=ZERO_VECTOR;
  135. list points=[];
  136. /*##############################################################################*/
  137. default{
  138.   timer(){FetchPath(TRUE);}
  139.   moving_end(){if(llVecDist(llGetRootPosition(),target)<0.6){path_pc++;Next();}}
  140.   on_rez(integer mew){llResetScript();}
  141.   dataserver(key k,string d){
  142.     if(k==kid){
  143.       if(nln==-99){
  144.         nln=(integer)d;Bar(kln,nln);kid=llGetNotecardLine(kcd,kln);return;
  145.       }
  146.       if(d==EOF){
  147.         Bar(-1,-1);D("Notecard '"+kcd+"' loaded. Click to begin roving.");
  148.         if(points!=[]){loaded=TRUE;}else{
  149.           llOwnerSay("ERR: Notecard '"+kcd+"' contains no destinations1");
  150.         }return;
  151.       }
  152.       d=llStringTrim(d,STRING_TRIM);
  153.       if(d!=""){if(llSubStringIndex(d,"#")<0){points+=[(vector)d];}}
  154.       kln++;Bar(kln,nln);kid=llGetNotecardLine(kcd,kln);
  155.     }
  156.   }
  157.   state_entry(){
  158.     llSetKeyframedMotion([],[]);llSleep(1.0);
  159.     llSetStatus(STATUS_BLOCK_GRAB,TRUE);
  160.     llSetStatus(STATUS_BLOCK_GRAB_OBJECT,TRUE);
  161.     D("Reset.");llCollisionSound("",0);
  162.     llSitTarget(ZERO_VECTOR,ZERO_ROTATION);integer i;
  163.     for(i=llGetNumberOfPrims();i>1;i--){
  164.       if(llGetLinkName(i)=="sithax"){
  165.         llLinkSitTarget(i,<0.3,0,.17>,ZERO_ROTATION);
  166.         llSetLinkTexture(i,TEXTURE_TRANSPARENT,ALL_SIDES);
  167.       }
  168.     }
  169.     Initiate();
  170.   }
  171.   touch_start(integer total_number){
  172.     if(Find(llDetectedKey(0))!=FALSE){
  173.       if(llDetectedKey(0)!=llGetOwner()){Handout(llDetectedKey(0));return;}
  174.     }
  175.     if(llDetectedKey(0)!=llGetOwner()){return;}
  176.     patrolling=!patrolling;
  177.     if(loaded){
  178.       if(patrolling){
  179.         D("Initiating roving.");
  180.         if(current_path!=[]){Next();}else{FetchPath(TRUE);}
  181.       }else{
  182.         D("Stopping.");llSetKeyframedMotion([],[]);FetchPath(FALSE);
  183.       }
  184.     }else{
  185.       llRegionSayTo(llDetectedKey(0),0,"Please wait for load to complete "+
  186.       "before initiating roving.");
  187.     }
  188.   }
  189.   changed(integer mew){
  190.     if(mew&CHANGED_INVENTORY){
  191.       llResetScript();
  192.     }
  193.   }
  194. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top