Jump to content

Quistess Alpha

Resident
  • Posts

    3,769
  • Joined

  • Last visited

Everything posted by Quistess Alpha

  1. As far as I know, the only way to set the default attach point is to actually attach to an avatar. Closest thing would be to llAttachToAvatar (NOT the temp version, which would destroy the object) then llDetachFromAvatar immediately after attached in the attach() event. Unfortunately it is also impossible to 'drop' (detach, then rez self on ground) an object via script. <technical meandering> It's probable that 'default attach point' is a property of inventory assets, and not the actual objects themselves, which would mean setting it without it being attached would be basically impossible to implement. </technical meandering>
  2. This was kinda fun to think through. integer within_hull(vector test, list points) { integer ind_a= 0; integer ind_b= 1; integer ind_c= 2; // indexes for 3 points from points. vector a = llList2Vector(points,ind_a); vector b = llList2Vector(points,ind_b); vector c = llList2Vector(points,ind_c); integer len = llGetListLength(points); // for all pairs of 3 points a,b,c: while(ind_c<len) { vector normal = (b-a)%(c-a); integer side = (test-a)*normal >0; // on which side of the plane defined by a,b,c is test? integer outside = TRUE; //early return variable. integer ind_p = len; // for each other point p: while(~--ind_p) { if(ind_p!=ind_a && ind_p!=ind_b && ind_p!=ind_c) { vector p = llList2Vector(points,ind_p); if( (((p-a)*normal)>0) != side) { //llOwnerSay("point del"); // p is on opposite side from test: // remove it from list. points = llDeleteSubList(points,ind_p,ind_p); // fix indexes! --len; if(ind_c>ind_p) --ind_c; if(ind_b>ind_p) --ind_b; if(ind_a>ind_p) --ind_a; }else { // it is possible test is within points: outside = FALSE; } } } if(outside) // there were no points on the same side of a,b,c as test, therefore it is impossible it is within the cloud: { return FALSE; } // set indexes for next loop: if((ind_a+1)<ind_b) { a = llList2Vector(points,++ind_a); }else { a = llList2Vector(points,ind_a=0); if((ind_b+1)<ind_c) { b = llList2Vector(points,++ind_b); }else { b = llList2Vector(points,ind_b=1); c = llList2Vector(points,++ind_c); } } //llOwnerSay("Debug: "+llList2CSV([ind_a,ind_b,ind_c])); } // either the initial point list had fewer than 4 points, or test is within the convex hull: return TRUE; } default { touch_start(integer total_number) { // for debug, determine if this object is within the convex hull of all nearby objects named "Test Point" llSensor("Test Point","",PASSIVE,7.0,PI); } sensor(integer n) { llOwnerSay("Found "+(string)n+" test points."); list points; while(~--n) { points+=llDetectedPos(n); } integer inside = within_hull(llGetPos(),points); if(inside) { llOwnerSay("Within hull!"); }else { llOwnerSay("Out of bounds!"); } } } I'm pretty sure it works, but I didn't test it super rigorously.
  3. As long as we're bringing up the dead, you can also do it with a media face. Media 'knows' where you're touching if you've touched it once to let it grab your mouse. I know I posted a demo long time passing. . . but easier to find it in my inventory than on the forums so. . . Too complicated for a simple use-case like in the OP, but it's a fun proof-of-concept.
  4. Not to toot my own horn, but the tv script I wrote (see above) is a minimally viable example of doing exactly that (pause/restart, or skip back/forward all resync everyone.). As for how to do that with any other specific product. . . do they have a support group or anything?
  5. Something something, scripting forum isn't the place to ask for custom scripts etc. etc. but I was bored, so. . . (quote reduces spaminess)
  6. Since I haven't read the movie or watched the book in years, I looked it up. The Harry potter wiki says: On its face, seems like a rather simple idea, but there are a lot of fiddly nuances depending on exactly how you'd want it to work. I don't know of anywhere in-world that would magically have exactly what you're looking for.
  7. AVsitter uses notecards to store pose information; in the case of things that advertise 1000+ animations, that can take a lot of time to read in and process.
  8. llGetRegionList returns up to 100 avatars, in no sensible order; Sensor only up to 20 or so, and sorted by distance. In the (extremely unlikely) case that there are over 100 agents in the region, you may fail to find one even if it's right in front of you.
  9. not directly, you have to do math, but assuming the object has a flat face (like a cube), with sane texture mapping, the math wouldn't be too bad. for your use-case (I'm envisioning something like a dartboard) just converting the region coordinates to object coordinates should be sufficient? (hit_pos-object_pos)/object_rotation; for a cube, could then divide that by half the object's scale, (component wise, <a.x/b.x, a.y/b.y, a.z/b.z> ) then the coordinate that is almost exactly +- 1.0 would tell you the face, and the other two coordinates the position on the face in coordinates ranging from -1 to +1 with 0,0 being the center.
  10. modulus by 0 (and maybe also 1?) has bitten me a few times. You could argue it's divide by zero in disguise, but it's a good disguise to look for.
  11. It's priority 1, which is extremely low. Whatever it is, it's very probably not going to suddenly mess up some other animation.
  12. using linkset data can greatly simplify remembering handles: Instead of: key gHandleRequestStat; // global variable //... later in some event: gHandleRequestStat=llReadKeyValue("my_stat"); //... dataserver(key ID,string value) { if(ID==gHandleRequestStat) { /*...*/ } } consider: llLinksetDataWrite("Handle:"+(string)llReadKeyValue("my_stat"),"read:my_stat"); //... dataserver(key ID,string data) { string request = llLinksetDataRead("Handle:"+(string)ID); // semi-important ETA: delete the stored key after use! llLinksetDataDelete("Handle:"+(string)ID); // also in 'real code', check request!="" for sanity. if(0==llSubStringIndex(request,"read:")) { string stat = llGetSubString(request,5,-1); // set stat to data }// ...else ... }
  13. LL tries very hard to make sure new changes don't break old things, so whatever was done in the tutorial should still be valid. Everything you really need to know about notecard reading should be available on the wiki: https://wiki.secondlife.com/wiki/LlGetNotecardLine There's a new function for reading from a notecard called llGetNotecardLineSync, but I wouldn't recommend it to a beginner.
  14. The wiki example can be generalized a bit: // untested example: string generalCompass (vector direction) { list DIRS =["W","NW","N","NE","E","SE","S","SW","W"]; integer index = llCeil(3.5 - (4 * llAtan2(direction.y, direction.x) / PI)); // I'd clean up the above math for clarity, but too lazy to debug. Off the top of my head. . .: // list DIRS = ["N","NE","E","SE","S","SW","W","NW"]; // integer index = llRound(8*(llAtan2(direction.x,direction.y)/PI)); // llAtan2(x,y); returns clock-angles, whereas llAtan2(y,x); returns math angles. return llList2String(DIRS, index); } // What direction is the position X with respect to where this object is? // generalCompass(X-llGetPos()); // What direction is object 'ob' facing? (assuming it has standard orientation, which avatars do, but many don't: // generalCompass(llRot2Fwd(llGetObjectDetails(ob,[OBJECT_ROTATION]))); // What direction am I or the avatar I'm attached to facing? // generalCompass(llRot2Fwd(llGetRot()));
  15. Agreed. Anyway, the closest thing I know of to what you're asking for would probably be a slave auction board. It's usually portrayed as doms paying for subs, but one of the more popular ones had a section for the reverse last time I checked (years ago). Other than that, I think you'd just have to 'freelance' and find appropriate places to advertise your services.
  16. Indeed, putting a script that says something on a non-zero channel when touched into the hunt item is probably the best solution. But if you're willing to change the input from touching the object to touching the HUD when near the object and your avatar is facing it, llSensor could be viable, or raycast as was suggested earlier.
  17. Jump targets. See the first example in the wiki: https://wiki.secondlife.com/wiki/Jump
  18. (also at the risk of going off topic...) It used to be things were done by color and getting versions for each body included was a given. In my naive non-merchant understanding, don't color fatpacks make more sense? I'd presume there are more people who like different colors than people who use two or more different bodies on the regular.
  19. store the inventory key of the notecard and check against it, roughly: key kNC; // notecard's inventory key. //... changed(integer c) { if(c&CHANGED_INVENTORY) { key k = llGetInventoryKey("Notecard Name") if(k!=kNC) { kNC = k; handleNotecardRead = llGetNotecardLine("Notecard Name",0); } } }
  20. All the ones I've seen are of this variant, but they can be ~very clever about not making the position obvious. If you have such a device, write a simple particle script that sends a beam from an attachment to a known object in-world (a 'leash' should work, but make sure it's from a different device than the one that's doing the hiding). That may make the hidden position more obvious.
  21. perhaps use ⌚ or ⌛ instead? Those seem to be in the character set given by @Frionil Fang's quote.
  22. A few years ago I made a thing that needed a 'guided setup', there were like 5 different things the user needed to do (change permissions, set object description, input an email, etc.) that for the sake of clarity were asked of the user in-order. Implementing it with states for each step had a lot of duplicated code, but was rather easy to write and debug. a while later I had to re-write the system, and decided to use just 2 states (one for setup, and one for when it was running) to see the difference. and it turned out a lot messier, with a lot of checks on the 'state' global variable in each event, which just looked confusing. Moral of the story I guess, is that states aren't useful most of the time, but when they make sense, they're incredibly useful if only for code clarity. All the times I can think of using states have been some form of 'setup' state, where the script does things like requesting permissions and reading notecards, (IMO a separate setup state is best practice for anything requesting PERMISSION_DEBIT) and then a state for when it's operating normally. But any time something needs to have radically different reactions to events, states can offer a lot more clarity than global variable checks, even though almost everything a state change can do can be done without one*. *moving from a state with a touch event to one without can "disable" the mouse hover over effect for an object. CLICK_ACTION_DISABLED might now have the same effect, the wiki doesn't say so though.
  23. even with global variables, I think what Love's saying is that you might have accidentally done something like: string name = "Bad Value"; default { state_entry() { string name = "Good value"; // by writing 'string' at the begining of the line, we cause the global copy of name to not be written to. } touch_start(integer n) { llSay(0,name); // will say 'bad value' because of error in state_entry() } } Which is allowed in LSL, but almost never intended.
  24. llGetInventoryKey("animation name"); will give you the key of "animation name" if it's in the object's inventory, unless there are some permission issues I've forgotten about. You can in-fact start and stop an animation with its key rather than its name, but if you try and stop an animation with its key and it's neither a built-in animaiton nor in the prim's inventory, I think that makes a pop-up error.
×
×
  • Create New...