Jump to content

Kayaker Magic

Resident
  • Posts

    151
  • Joined

  • Last visited

Everything posted by Kayaker Magic

  1. There is an old bug that treats NaN as a legitimate number for moving prims. This was used to impliment the old PosJump function before llSetRegionPos() was available. It looks like your prim is trying to move to NaN an being prevented from doing so by the 10 meter maximum distance that llSetPos is allowed to go. Several comments on your script: (Intended to be constructive!!!) There are better ways to move a non-physical prim, I recommend llSetKeyframedMotion(); Moving prims in a for loop is very bad form, you should find an event-driven way to do this, such as moving in a timer event. llSetPos() has a built-in delay, you can use llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,[traveled]); with no delay. You are calculating your positions using Cartesian math, which has sigularities as you discovered with the NaN values. There are ways of calculating points around a circle that do not have this problem. One way would be to use the rotation data type to rotate a vector around in a circle.
  2. In OpenSimulator there is a problem that people call "particle starvation" and I thought that this problem did not exist in SL. The probem is caused by the PSYS_SRC_BURST_RATE parameter of llParticleSystem. The Wiki says that if you set PSYS_SRC_BURST_RATE to 0.0, it will generate particles as fast as possible. But in OpenSimulator if you do this, it will starve particles from all the other particle emmiters in the same SIM. The recomendation, in OpenSimulator, is to never set this paremeter 0, instead use 0.001 for example. A number that small produces lots of particles, usually indistinguishable from using 0.0, but it does not starve particles from other emiters. Unfortinately, the fix for this is to track down all the other particle scripts in the SIM, look at the PSYS_SRC_BURST_RATE parameters, and if it is zero, then replace it with 0.001. This is unfortunate because you may not have access to all the particle scripts in your SIM. And like I said, I thought this was a bug in OpenSumulator an not in SL, so the whole exersize may be wasted. -------- So here is a completely different suggestion, a way of getting your "flame spine" without using particles at all: How about wearing a couple of flat prims that have a flame texture animation running on them? That could look pretty cool!
  3. I've been doing things like "pathfinding" with things like fish for YEARS, since long before LL added code to do pathfinding in the server. The scrit below impliments the bare bones of swimming motion in a single prim. It moves around in the water, curves smoothly away from different boundaries. You can add a back and forth motion, add llSensor to avoid or attack avatars, put in more tests, change the distance that it looks for certain borders, change the acceleration for different obsticals, etc. Even changing the order of the tests results in different behavior. // Swimmer // A script that gets pretty smooth motion and // moves a critter around sort of like "pathfinding" in in water. // This version is an example of how to do that using the // llSetKeyframedMotion function. // // Put this script in a prim that is long in the X direction, it will swim in the // direction of it's local X axis. Paint it with a texture that allows you to // tell which way is the top (the local Y axis). // // This simple critter behaves in the following ways: // It moves in a straight line until: // moves out of the water but falls back down // avoids getting close to the bottom // turns away from the SIM edges // turns away from parcel boundary edges. // turns away from the waters edge (llGround>llWater) // // I give this code away, use it in your products for sale. float DEFLECT=0.20; //how hard things deflect me away (m/s/s) float LOOKAHEAD=2.0; //how far to look ahead to avoid stuf integer run=1; //flag indicating if I'm running or not list params=[ //make the smoke PSYS_PART_FLAGS,0 , PSYS_SRC_PATTERN,PSYS_SRC_PATTERN_DROP , PSYS_SRC_BURST_RATE,0.125, PSYS_SRC_BURST_PART_COUNT ,1, PSYS_PART_MAX_AGE,30.0, PSYS_PART_START_SCALE, <.75,.75,0>, //magenta smoke PSYS_PART_START_COLOR, <1,0,1> ]; // This function, OKfly, checks for all the places that you don't want your prim to move. // Across sim boundaries, into the ground, onto dry land. // I use parcels to create boundaries where the critter has to stay, so I test // for parcel boundaries here also. // You could test for other things, like a fish can't leave the water or a bird // can't enter water, but fish jump and birds dive so I do that elsewhere. // Nothing prevents this critter from passing through solid objects, even if it is not // phantom. But if it is not phantom it will stop when colliding with an avatar. integer OKfly(vector pos) //return true if OK to move to pos { //don't go outside the edges of the region if (pos.x<=0.0 || pos.x>=256.0 || pos.y<=0.0 || pos.y>=256.0) return FALSE; vector vel=pos-llGetPos(); float gnd = llGround(vel); if (pos.z<gnd) //don't go below ground return FALSE; if (gnd>llWater(vel)) //don't go where the ground is above the water return FALSE; //don't leave the current parcel key curpar = llList2Key(llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_ID]),0); key nxtpar = llList2Key(llGetParcelDetails(pos, [PARCEL_DETAILS_ID]),0); if (curpar!=nxtpar) return FALSE; //insert other rules here, like fish not allowed out of the water return TRUE; //otherwise, it is OK to fly here! } //Single Frame motion routines // These 3 functions impliment smooth motion using llSetKeyFramedMotion // The way it works is this: // You call SFrame with a new position, rotation and time // I usually call SFrame once a second from the timer event with an updated //position and rotation. //But it works over longer times and distances. //UNLIKE llSetKeyframedMotion, here you specify the region co-ordinates and rotation! //I did it in these tree functions to make it modular, I can replace all 3 of them //with routines that work on grids that don't have llSetKeyframedMotion SFsetup() //any necessary setup { //This setup is necessary in SL, and may cause errors on Open Sim, if so delete it llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]); } //move the calling root prim from its current position and rotation //to the requested position and rotation in the requested time. //UNLIKE llSetKeyframedMotion, you specify the region co-ordinates and rotation! SFrame(vector pos,rotation rot, float seconds) { llSetKeyframedMotion([pos-llGetPos(),rot/llGetRot(),seconds], [KFM_MODE,KFM_FORWARD,KFM_DATA,KFM_TRANSLATION|KFM_ROTATION]); } SFstop() //stop the key framed motion { llSetKeyframedMotion([],[KFM_COMMAND,KFM_CMD_STOP]); } SFnotat() //call this from your not_at_target event { //not necessary with llSetKeyframedMotion, so this function is a NOP } default { state_entry() { llOwnerSay("reset"); llParticleSystem(params); //Start the smoke llSetTimerEvent(1.0); //recalculte movement every second SFsetup(); } on_rez(integer param) { //turn to a random direction on rez llSetRot(llEuler2Rot(<0,llFrand(PI-PI/2.0),llFrand(TWO_PI)>)); } timer() //every second, calculate a new direction to turn and move { vector pos=llGetPos(); //get my current position rotation rot=llGetRot(); //and rotation vector vel=<1,0,0>*rot; //use my direction as velocity //here are the RULES that give this critter behavior: //first (four) rule(s): Avoid the edges of things. vector xvel=llVecNorm(<vel.x,0,0>); //get orthagonal components of velocity vector yvel=llVecNorm(<0,vel.y,0>); if (!OKfly(pos+LOOKAHEAD*xvel)) //so you can pong off the edges of the sim vel -= DEFLECT*xvel; //slow down as you approach X edge. if (!OKfly(pos-LOOKAHEAD*xvel)) //checking both sides makes me vel += DEFLECT*xvel; //accelerate away from walls if (!OKfly(pos+LOOKAHEAD*yvel)) //do the same thing in Y vel -= DEFLECT*yvel; if (!OKfly(pos-LOOKAHEAD*yvel)) vel += DEFLECT*yvel; //I could use LOOKAHEAD to avoid running out of the water (I do that for the //ground below) but I thought it would be fun to allow this swimmer to jump //out of the water and fall back in float wat=llWater(ZERO_VECTOR); if (pos.z>wat) //after I have already popped out of the water, vel -= <0,0,1>*DEFLECT; //accelerate back down //When the critter gets within LOOKAHEAD meters of the ground, I start //accelerating back up. Using the ground normal makes it turn sideways //away from cliffs instead of always turning straight up. vector npos=pos+vel; //next position if ((npos.z-LOOKAHEAD)<llGround(vel)) //if my next position is too close to the ground vel += llGroundNormal(vel)*DEFLECT; //deflect away from the ground normal //I'm limiting this critter to 1 meter per second, you could go faster //but beware, llAxes2Rot requires unit vectors! You would have to //calculate a separate vector that is the normalized velocity and use that below. vel = llVecNorm(vel); //limit my velocity to 1m/sec //here I convert the velocity vector into a rotation. These steps result in the //prim always rotating to keep the head "up". Actually the local Y axis is always //parallell to the XY plane, the local Z axis is allowed to rotate away from //straight up to turn the nose to rise or fall. vector lft=llVecNorm(<0,0,1>%vel); rot = llAxes2Rot(vel,lft,vel%lft); //calculate new rotation in direction of vel //SFrame will refuse to go somplace that OKfly does not like, but I do //another test here and try to do something random to avoid getting stuck. if (!OKfly(pos+vel)) //final test: If I'm still going out of bounds, { if (llVecMag(lft)<0.5) //detect Gymbol lock! lft=<0,1,0>; //and make a hard turn in this unusual case. vel = llVecNorm(vel+lft*(llFrand(2.0)-1.0)); //randomly turn left or right lft=llVecNorm(<0,0,1>%vel); //to try to get out of edge lock rot = llAxes2Rot(vel,lft,vel%lft); //re-calc the rotation vel=ZERO_VECTOR; //stop and wait for rotation to turn me } SFrame(pos+vel,rot,1.0); //start moving and turning } //once SFrame is running, even the build dialog cannot change the position //or rotation without it being changed back. So I added this touch to stop the //critter so I could move it or rotate it, then touch start it moving again. touch_start(integer num) { if ((run = run^1) ==0) //toggle the run flag { llSetTimerEvent(0); SFstop(); //demonstrate how to use SFstop! llParticleSystem([]); //turn off the smoke while stopped. llOwnerSay("stopped"); } else { llSetTimerEvent(1.0); //the next call to SFrame in timer will start it up again llParticleSystem(params); llOwnerSay("running"); } } }
  4. Ah, you should have stressed one thing! The objects that I want to transfer, have to be marked as "next owner can transfer", or they will not transfer with the parcel. The land sold sooner than I expected, and for a while I thought I had given away the store, in the form of my vending machines. But none of them were marked TRANS so they all still belone to me. WHEW! Problem is, many prims I planed on transfering. Now I have to mark those as for sale in place and let the new owner buy them...
  5. In preparation for putting my SIM up for sale, I combined all the parcels into one, marked it for sale, including the prims, and set the price to a HUGE VALUE. I chose the value to prevent someone from purchasing the parcel, since it was the SIM I wanted to sell. In fact, I set the parcel price to the ammount I hoped to get for selling the whole SIM. Then within a day, someone purchased the parcel for that HUGE sum! Well, that's great and if she wants the SIM as well, I'll sell that to her for L$1 more since I already got the price I wanted. I wish I had a fiew minutes of warning to remove a few personal prims before they were all aquired. But this whole transaction is bothering me. Why would someone pay so much just for a parcel? This person has not tried to contact me. I am still the owner of the SIM and the estate manager. I checked her profile and she has been a resident for years, implying some experience here. So I'm wondering if this sale is too good to be true...
  6. I have a region with sim extenders that are cusom made to look like they are continuations of the terrain out into the Void Sea. I want to include these as part of the sale (yes, I have transfer permission on them). How do I include these as part of the region transfer? I see the button in setting a parcel for sale that has the option to include prims when someone buys a parcel. If I set that before the region transfer, do the prims get tansfered to the new owner with the land? Or should I set that option and then have them buy the whole parcel with the prims before starting the transfer? (If they then back out it might be a hassle to get ownership of all the prims back). I could mark everything for sale for L$0 in place, but I don't want to have to do that with every tree... What is the best practice for transfering all the prims with the region?
  7. There are products for sale in the marketplace that will tell you when your friends (or enemies) log in and out of SL. I assume you can point them at yourself. I wrote one once and had it keep statistics like how many hours spent in-world per month. My GF felt that "that thing" was a violation of her privacy, so I named the prim STALKER. I never put this up for sale because I found out there were several of them already in the marketplace under names like "Friend Finder".
  8. It is unclear to me what your Light Saber does in RL or in SL. It is difficult to imagine that it does the same thing as a movie light saber in RL, since several of the effects of Light Sabers are physically impossible in RL. Snel's Law tells what light does when crossing the boundary of a lens, it cannot make a glowing buzzing blade that extends only a meter out of the lens and cuts through solid metal. By reading between the lines of your post and looking at the pictures, it looks like your SL light saber is an optics simulation program that casts rays through simulated lenses and verifies that the lenses do what they were designed to do. I don't think you will find many people in SL who would be interested in this. I suspect that if you offered a Light Saber script or object in SL, most people would expect this to be a role-play weapon. They would expect a cool looking handle that sprouts a glowing blade when activated and makes a buzzing sound. Extra points if it changes sounds when moving, penetrating prims or passing near another light saber.
  9. I have used ixwebhosting for years, perhaps over a decade. And I have used their server, PHP, MySQL, etc. for many different SL and OpenSim based projects. They have worked well, been reliable, and the price is incredibly low. I don't see the plan I am on, but their current pricing is under $8 per month (paid in an annual lump sum in advance).
  10. On OpenSim, physics is an iffy proposistion. If this is a SIM that you are maintaining, you can use the new Bulletsim physics engine which is under active development and getting better. The old ODE physics engine is full of bugs and regularly crashes SIMs and nobody is working on fixing it. And even if the physics routines worked, llMoveToTarget doesn't move objects at a linear velocity, it moves them at a "critically damped" velocity, slowing down as it reaches the target. The only way to move a physical object at a constant velocity is to use the vehicle functions which are very complicated to use and even less likely to work well in OpenSim. You might consider instead using llSetKeyframedMotion (SKFM) wich has several advantages: It works on OpenSim 0.7.6, it moves non-physical objects, it moves objects at a linear speed, it doesn't require a debugged physics engine, and it is deterministic (unlike all physics engines, even the one in SL). SKFM accepts a list of delta positions, rotations, and times, but I usually call it with a list of one, then re-calculate the next position and call SKFM again. Sort of like llMoveToTarget but without the overhead and wierdness of physics. I published a script in the OSGrid Scripting Forum some time ago that impliments a simple flying critter. That was written before OS 0.7.6 came out and does not even use SKFM, but could be easily modified to do so. It could be modified to stick to the terrain surface, use llCastRay to try to avoid objects, etc.
  11. I know of two ways to sit multiple avatars on a single prim. I am surprised that AVsitter does not do this for you in the script. Perhaps you should contact them and find out how to enable this feature. Here is a link to an article with a script that I wrote, that script will sit an infinite number of avatars on a single prim! How many avatars can sit on the head of a prim?
  12. I don't think this is what you asked for, and it is certainly not libs. But the Phoenix family of viewers have had a pre-processor for LSL for years now that have an #include command and other things you expect from a pre-processor. I have been using this for some time, and have "libraries" of modular functions that I can just #include in a new script. The included files come off my hard drive, so I can't give someone a script written this way. (Well, you can, but they can only use the post-processed half of the script, with the comments stripped off and the included files added to the body of the code). It's not perfect, in fact it is sometimes difficult to use. It splits your code into pre and post processed listings. The LSL compiler reports errors in the post processed list, sometimes it is difficult to find where those errors are in your original code. The viewer will let you edit the post processed code, so sometimes I fix things there without realizing I'm not editing the original code and the pre-processor is going to undo all my work.
  13. By "grow" I thought the original poster meant "slowly increase in size like a plant growing", not blow up instantly. I think s/he is looking for something like: float size=1.0; //start out 1mdefault{ state_entry() { llSetTimerEvent(0.5); } on_rez(integer param) { size=1.0; //go back to 1m on rez llSetTimerEvent(0.5); } timer() { llSetScale(<size,size,size>); size += 0.1; if (size>5.0) //bigger than 5m? llSetTimerEvent(0); //stop the clock }}
  14. That “do { llSleep(30); } while” loop in your first posting made my hair stand on end! I'm glad Innula told you better, but I would like to emphasize this. Any time you are using an indefinite loop, you are violating the principles of event-driven-programming. Loops are for looking at lists, doing other things that won't take much time. You should strive to return AS SOON AS POSSIBLE from any event. I don't know how Linden Labs does it, but in Open Simulator it turns out that llSleep blocks the thread that is running your script. The simulator has a limited number of threads, so if enough scripts call llSleep at the same time, it could lock up all scripting (on Open Simulator at least). Your first posting was potentially spending HOURS in that do loop, hogging system resources to do nothing! Is there a page in the Wiki that has a list of "good programming practices" for LSL?
  15. For a long time I have had this problem where some of my texture maps turn white on my viewer. They are not white to anyone else, just me until I clear the cache. It seems to happen most often when I am going back and forth between different grids. I thought it was caused by different texture maps in different grids having the same UUID, but I'm told that is astronomically unlikely. Well, I found a way to force the problem to happen now! I have a script that loads a series of sculpt maps to animate the head of a critter. I load them by UUID so that multiple copies of the build use the same texture maps and all the nearby viewers only have to load them once. I also paint the sculpt maps on the surfaces of a hidden prim to prevent them from being forgotten by the viewer cache when not in use for a minute. I have the same build and the same script running on several grids, so I have an #ifdef in the code to load a different set of UUIDs on each grid. (I use the Firestorm pre-processor for this sort of thing). Well yesterday I updated the script on one grid (InWorldz) without changing the #define and built it with UUIDs from another grid (Virtual Highway). The head of my critter turned into a blob and I immediately realized my mistake. But as the script re-loaded the sculpt map over and over, the blobs turned into the correct shapes, even though the UUIDs were from a different grid! The viewer had the sculpt maps from the other grid still in the cache and for a while everything worked! I re-built with the correct UUIDs, and the head of my critter turned back into a blob. I waited for the local copies of the sculpt maps to get into the cache but some of them never did. I looked at those sculpt maps in inventory and saw that they had turned white! The only way to get them back was to clear the cache on the viewer and re-log. I'm not sure why this should be happening, I was loading the bad texture by UUID and for a while it was still in the cache so I see why things temporarily worked. Then I loaded the correct texture, also by UUID. It should have seemed like a completely new texture. The only thing the two textures had in common was the name in inventory. Somehow the viewer decided to associate the correct UUID with the contents of the bad UUID which was invalid in the current grid so a white texture map was substituted. Yeah, I suppose I should submit this as a bug to the Phoenix/Firestorm people.
  16. When you download the free bvh files for all the internal animations from LL (see here), they give you one for each of the expressions. What gives with that? I looked at them and they seem to be posing the joints. I did a test, animation my avatar with "express_anger" and uploading "avatar_express_anger" and trying that one out. Of course I had to request the angry facial expression when I uploaded that one. The two animations are not the same! "express_anger" just morphs your face while "avatar_express_anger" shakes the head back and forth and poses the arms in a angry shaking way. (I should have requested fisted hands as well). I also requested that the animation loop, hoping that the expression would loop with it. No such luck, the facial expression happens the first time through the loop and then never happens again. I tried an experiment,:I built an animation (with Quavimator) that had just one frame with a T-pose, I hoped if I marked that on as loop it would loop the expression. Well it did not, and it posed me in the T-pose. So I tried one more experiment: I built one last animation that had two frames, both T-poses, hoping that this animation would loop and do nothing except the hands and face. But the system would not let me upload that one at all!
  17. When you say your land borders the ocean, do you mean the “Void Sea”, the water that appears where there is no SIM to simulate anything? If so here is a completely crazy odd-ball solution: The Void Sea is VERY DEEP. I once built a steam punk submarine that carried me 300 meters down there. After around only 20 meters down it gets very dark and difficult to see anything, but I recall that full-bright and glowing prims faired better. I never experimented with lights. I always meant to script some glowing underwater fish to swim there. So whatever you are building, build it as an off-sim extender and hang it down in the Abysmal Depths of the Void Sea! The new prim distance limits allow you to make things up to 56 meters in diameter. That means that after you leave one prim behind on the shore, you could have some prims 40 meters offshore and 40 meters below the bottom. A tall thin build closer to shore could go deeper of course (56 meters in the limit). Then the easiest way to get to your off-sim structure would be to have seats built into it. Just reach down and click on the top of the structure and your avatar would land on one of the seats in the dark. OK, here's an easier solution: Set up a megaprim at 2000m above the ground, texture it with rippling water, mark it phantom and call it the water level. Put some sculpty islands on it. Build your structure underneath this water prim and you are done.
  18. I have had lots of experience making shorelines on private regions, but I don't know if this will help you either. Because I'm crazy and my favorite tool for doing this is GIMP! (Photoshop would work). I paint a greyscale picture of the land and water that I want and use the Gausian blur tool to blend (slope) the border between the two. Then I use Backhoe (a program that runs on the Mac, tools to do this are available on other platforms) to import that greyscale terrain map into a .RAW terrain file. Then I log in-world and import the raw terrain file with the region management tools. If you just wanted to add a nice beach on one end of a region you already had, you can export the region terrain map to your PC, extract the terrain height plane, paint in the beach, import back into the raw file, import the raw file back in-world. Easy!?
  19. Short version: flexible (but stiff) prim in a build sometimes displays at a slight angle, is there a way to prevent this? Long version: A long time ago I learned this trick here: If you want to make one prim in a build phantom without making the rest of the build phantom, you can do that by marking the prim flexible but setting the parameters so it was actually very stiff. For example, make the water prim on a hot tub flexible so if people walk over it, they sink through the water but stop when their feet hit the non-phantom bottom. I hear rumors that there is a new official way to do this now, but I'm building things that I want to work on Open Simulator so I'm still using the old tried and true trick. But I recently ran into a problem, which is probably a problem in the viewer. (I like Firestorm these days). I built a BIG pool (using megaprims) that is 128m long on the longest side. It has sandy-textured beach prims around it, a sandy textured bottom and water made from a 128x64m prim with a transparent water texture on it. This water prim is marked flexy so if people walk on it they sink to the bottom. Most of the time this works fine. (My scripted vehicles know to float on the water prim). But I was swimming in my pool recently and noticed that at one end the water was higher than at the other end. I checked it with the build menu and it was not rotated, and when I closed the build menu the prim suddenly rotated back to where it belonged! But I looked away and back again later and the prim tilted again. If I change it to non-flexy it also goes back to the zero rotation. Has anyone else had this problem? Is it just a Firestorm problem or do other viewers do this? Is there a workaround for it? (I've tried changing the flexy parameters with no luck so far).
  20. Sounds like you saw Scratch for Second Life http://web.mit.edu/~eric_r/Public/S4SL/ scratch is a very interesting computer language concept in itself, and this is a version that outputs LSL!
  21. I could not resist that title! What I should have said was: How to sit many avatars on one prim with one script. I wrote a set of scripts once to sit multiple avatars on a single prim. It was very complex, requiring a separate script for each potential sitter and a list to keep track of which scripts were in use already. Recently I learned, in How to use llAvatarOnSitTarget, how to sit many avatars on many prims with only one script. So I have taken what I learned and made one script that can sit many avatars on only one prim. When multiple avatars sit on a single prim, llAvatarOnSitTarget() fails to do anything useful. It always reports the UUID of the first avatar to sit instead of the most recent one. If the first avatar jumps off, llAvatarOnSitTargeg() returns NULL_KEY even if there are still other avatars seated on the prim. Fortunately you can get the UUID of the most reacent avatar from llGetLinkKey(llGetNumberOfPrims()) because the last avatar to sit is always the last 'prim' in the linkset. Next you have to know where you want to put each avatar. In the script below I used a formula based on the number of avatars sitting. In furniture you could read the positions out of a notecard. After the first avatar sits down, llSitTarget stops working and the following avatars sit where they touched. But since I know where I want each one to go, I force them to move and rotate into place with llSetLinkPrimitiveParamsFast. As I learned, it is not necessary to hold onto permissions after sitting an avatar. So I just ask for new permissions for each new avatar as they arrive, animate them and forget! If you also need other permissions from the avatars, or need to hold onto the permissions, this trick will not work. Note that this script will only work right if the avatars don't jump on and off after sitting. To fix this you need to keep a list of avatars already seated and what positions they are in. The resulting code would be thrice as big as this and you would not be able to see the essential details here. //This demonstrates multiple avatars sitting on one prim //To keep the example simple, it only works if the avatars don't jump off and back on again integer lastnum; //last number of prims in the build default { state_entry() { llSetClickAction(CLICK_ACTION_SIT); //force to sit mode llSitTarget(<0,0,1.44>,ZERO_ROTATION); //and set the first sit position lastnum=llGetNumberOfPrims(); } //state_entry changed(integer flags) { if (flags&CHANGED_LINK) { integer num=llGetNumberOfPrims(); //goes up every time a new avatar sits if (num>lastnum) //if the number of prims increased, it must be a new sitter { //don't trust llSitTarget, force the avatar to the position you want //note: the most recent avatar to jump on is always the last 'prim' in the link list llSetLinkPrimitiveParamsFast(num,[PRIM_POS_LOCAL,<2-num,0,1.44>,PRIM_ROT_LOCAL,ZERO_ROTATION]); llRequestPermissions(llGetLinkKey(num),PERMISSION_TRIGGER_ANIMATION); //ask to animate } lastnum=num; } } //changed run_time_permissions( integer perm ) { if (perm&PERMISSION_TRIGGER_ANIMATION) { llStartAnimation("surf"); //put the new guy into the surfing pose llStopAnimation("sit"); //stop the default sit animation } } } //default
  22. My Momma done raised me right! She taught me to close doors behind me! And free memory that I malloc'ed, and fclose files that I fopen'ed, and to llStopAnimation the animations that I llStartAnimation'ed! I just ASSUMED that I needed to hold onto that permission to stop the animation later! If I don't have to do that, then I can use llAvatarOnLinkSitTarget (to answer my own question) to sit all the avatars on all the seats in a build with one script and one set of animations in the inventory of one prim! Below is the script that I was able to get working after reading all the suggestions above! Each avatar is seated with an animation selected at random out of inventory. I'd like to expand this to allow touching on the seat to select one of the animations from a dialog, or randomly fidgeting by switching between the animations on a timer. I'm not sure if I can re-aquire the permission to do this, but I'll go try that next! Thanks everyone! //multiple seater. One script and a set of animations in one prim// will sit all the avatars on all the seats in a build.//// Name each of the seats in the build "Xseat"// Put several animations in the root prim with this script// Each time anyone sits on one of the seat prims, this script will// sit that avatar with one of the animations at random.list IDseated; //list of seated avatarslist LNseated; //list of prims they are seated onvector sitpos=<-0.1,0,0.1>; //offset to make the animation look rightrotation sitrot=ZERO_ROTATION; //rotation to put the avatar uprightstring sitname="Xseat"; //each child prim with this name becomes a seatdefault{ state_entry() { llOwnerSay("Set up seats"); integer i; for (i=1;i<=llGetNumberOfPrims();i++) //look at all the prims { if (llGetLinkName(i)==sitname) //each seat prim must be named "xseat" llLinkSitTarget(i,sitpos,sitrot); } } changed(integer flags) { if (flags&CHANGED_LINK) //if the link changed it must be a sit/unsit { integer i; for (i=1;i<=llGetNumberOfPrims();i++) { if (llGetLinkName(i)==sitname) //each seat prim must be named this { key sav=llAvatarOnLinkSitTarget(i); if (sav!=NULL_KEY) //is someone seated there ? { if (llListFindList(IDseated,[sav])<0) //they are new { IDseated += [sav]; //add them to the list LNseated += [i]; llRequestPermissions(sav,PERMISSION_TRIGGER_ANIMATION); //request animations return; } } else //no one seated here, see if they just left { integer j=llListFindList(LNseated,[i]); //check to see if the are in the list if (j>=0) //if they were in the list but unsat, { //then remove them IDseated = llListReplaceList(IDseated,[],j,j); LNseated = llListReplaceList(LNseated,[],j,j); return; } } } //all the child prims named sitname } //for all the child prims llOwnerSay("oops, didn't catch one!"); } //if this is a CHANGED_LINK } //changed run_time_permissions(integer perms) { if (perms&PERMISSION_TRIGGER_ANIMATION) { //pick an animation at random out of inventory string anim=llGetInventoryName(INVENTORY_ANIMATION,(integer)llFrand(llGetInventoryNumber(INVENTORY_ANIMATION))); llStartAnimation(anim); //start the new one llStopAnimation("sit"); //stop the default sit } }}
  23. I'm trying to use the new llLinkSitTarget and llAvatarOnLinkSitTarget to decrease the number of scripts in a build. I have a row of theater seats that is linked into one build, and currently each child seat prim has its own script. This is because llSitTarget only sets the position and llAvatarOnSitTarget only returns the id of the avatar sitting on the calling prim. The two new functions look like they will allow me to manage all the child prim seats from a single script in the root. I can call llLinkSitTarget in a loop to set all the seats up. When changed() happens, I can search through all the child prims and ask llAvatarOnLinkSitTarget which seat has someone sitting on it. I have to keep a list of seated avatars so I know when one of the prims acquires or looses a sitter. Once I know the key of a newly sat avatar, I can llRequestPermissions to animate that particular avatar. But then I run into a problem: run_time_permissions does not tell me WHICH avatar I just got permission to animate and llStartAnimation doesn't give me an option to specify which of them to animate. llRequestPermissions only seems to remember the permissions for one avatar at a time and calling it again releases previous permissions (according to the Wiki) and apparently also releases the previous avatar at the same time. Each script seems to have its own copy and only one copy of the currently granted permissions and avatar, so the only way to do what I want is to have one script per prim, which is how I did it before the new LinkSitTarget functions. Is my analysis correct? Is there some other way to use the new LinkSitTarget functions?
  24. I love llSetKeyframedMotion! (llSKFM) I'm switching lots of things over to it that I used to use physics for. It has always been a shame that you had to drag in the huge, complex, finicky, buggy physics engine just to move an object smoothly. The way that I am using llSKFM is to calculate the next position and rotation of my “vehicle” or “critter” once a second in the timer() event I then give that position, rotation and 1 second to llSKFM to interpolate motion smoothly. Then I come back a second later and set up a new call to llSKFM. As for the jerkiness, if you focus your camera (ctrl-alt-leftclick) on the seated avatar, the jerkiness goes away: the avatar and the vehicle move together. You can also get focused on your avatar by tapping one of the control keys, like left arrow. If you focus on the vehicle, the jerkiness comes back. If you focus on the ground as the vehicle goes by... I think the jerkiness is there. If you have two passengers on the vehicle, you can focus on one and the other will be jerky, or you can focus on the second and the first one will be jerky! There is no solution! I don't know if physical vehicles have this same problem. I have seen the same problem in Open Simulator, so I am beginning to think it is a viewer problem...
  25. I've had this effect for years with both vehicles and llMoveToTarget. It happens every once in a while and I've just learned to ignore it. It is not "movement prediction" because the build often takes off at a velocity and direction that have nothing to do with the previous movement. Usually that velocity is high, but when it is low, the object can move accross sim boundaries and annoy my neighbors. It is hard to claim that this is client only, since people on other sims see the object with their own viewers and in one case was able to delete the object before it snapped back to where it belonged on my sim. They were able to delete it because it was over their land, but it was repoted deleted to me at the snap back co-ordinates where it was supposed to be on my land.
×
×
  • Create New...