Jump to content

Quistess Alpha

Resident
  • Posts

    3,873
  • Joined

  • Last visited

Everything posted by Quistess Alpha

  1. ^^ Agreed. as a general 'LSL principal' I'd rather have functions that provide some "general and obvious use" rather than something with a known specific implementation. I could see something like llStridedListStatistics, maybe being nice, do all the operations, and also be able to them on groups of n entries, either within the group or between groups. Ex. list result = llStridedListStatistics(LIST_STAT_SUM,2,FALSE,[1,2,3,4,5,6]); // expect [1+3+5,2+4+6]; list result2 = llStridedListStatistics(LIST_STAT_SUM,2,TRUE,[1,2,3,4,5,6]); // expect [1+2,3+4,5+6]; and leave specific implementation to the devs.
  2. Indeed, prim-text is always a fixed size (regardless of distance!), dependent on the viewer's settings, leaving only a few options for 'large text': Single-use texture with your text on it. One of various script-tools to splice together a 'texture atlas' font texture onto different faces of specially designed meshes, for example Furware text or xyzzy. Media-on-a-prim and LSL "webhosting" to display a formatted XHTML webpage on a face of an object. Each have some pretty serious pros and cons.
  3. For sake of argument, how do you know the LSL compiler doesn't ~already optimize basic operations?
  4. I hadn't even considered how easy it might be to abuse SL for a cryptomining scheme. . . Is that why breedables are so awful?
  5. Uhm, name one specific case/algorithm where this function would provide significant improvement. We already have https://wiki.secondlife.com/wiki/LlListStatistics
  6. Yes, if a physical object (an avatar) and a non-physical object (a 'spinning thing') occupy the same space, the physical thing gets 'pushed' away. the trick/problem is the non-physical thing has to not 'move through' the avatar. if for example a thing "spins" by setting its rotation +20 degrees every 0.2 seconds, for a sufficiently far away avatar, the object could push it forward for 0.2 seconds, then push it backwards for 0.2 seconds, effectively 'passing through' because it was "moving" too fast with not enough resolution.
  7. Doesn't seem significant at least: default { state_entry() { llSetScale(<3.0,0.25,1.0>); // force new prim equivalency system: llSetLinkPrimitiveParams(LINK_THIS,[PRIM_PHYSICS_SHAPE_TYPE,PRIM_PHYSICS_SHAPE_CONVEX]); // previous times I've tried this, rotating twice by 180 degrees led to bad results. rotation z90 = llAxisAngle2Rot(<0,0,1>,PI_BY_TWO); llSetKeyframedMotion( [ z90,2, z90,2, z90,2, z90,2 ], [KFM_MODE, KFM_LOOP, KFM_DATA, KFM_ROTATION]); } }
  8. Not static if they're also physical. (which is rare and often a mistake, but a completely valid state of being)
  9. Yeah, the taxonomy of physicality in SL is weird and doesn't translate to english very well. "physical" objects can be pass-through able and not-physical objects stop physical things (unless those physical things are pass-through able)! Turns out you also need a fairly significant mass to push avatars: default { state_entry() { llSetStatus(STATUS_PHYSICS,FALSE); llSetPhysicsMaterial(DENSITY|GRAVITY_MULTIPLIER,0,0,0,10000.0); llSetScale(<3,0.2,1.0>); llSetStatus(STATUS_ROTATE_X|STATUS_ROTATE_Y,FALSE); llSetStatus(STATUS_PHYSICS|STATUS_ROTATE_Z|STATUS_BLOCK_GRAB,TRUE); llMoveToTarget(llGetPos(),0.2); llTargetOmega(<0,0,1>,1.0,1.0); } }
  10. IIRC KFM moved objects can still be knocked off-course by avatars (among other physical actors). You could try making it physical, setting gravity to 0, llMoveToTarget its current position, and llSetStatus lock its rotation in the axes it's not spinning.
  11. Sounds are never 'inherently' looped like animations can be. If you want just a single go when you start typing, something like: integer isTyping; integer doAnimation; float ANIM_LENGTH = 5.0; string ANIM = "myAnimation"; string SOUND = "mySound"; default() { state_entry() { llSetTimerEvent(0.2); } timer() { integer typing = llGetAgentInfo( llGetOwner() ) & AGENT_TYPING; if(typing!=isTyping) { isTyping=typing; llResetTime(); if(typing) { llPlaySound(SOUND,isTyping); }else { llStopSound(); // wiki suggests this might not do anything for sounds not started with llLoopSound. } doAnimation=isTyping; llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION); }else if( isTyping && doAnimation && (llGetTime()>ANIM_LENGTH) ) { llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION); doAnimation = FALSE; } } run_time_permissions(inteegr perm) { if(perm&PERMISSION_TRIGGER_ANIMATION) { if(doAnimation) { llStartAnimation(ANIM); }else { llStopAnimation(ANIM); } } } } (untested) might work.
  12. No, the script has to stop it early, or a new animation needs to be uploaded.
  13. Reading back a bit more carefully, if your object and avatar are close enough to accidentally repel eachother, setting the follower to phantom might help, llSetStatus(STATUS_PHYSICS|STATUS_PHANTOM, TRUE); just be careful about physical+phantom objects with gravity, especially if you're in a skybox.
  14. Actually it is, it just becomes less obvious because move to target is usually strong enough to overpower/out-way most anything else. The caveat about llMoveToTarget moving slightly faster downwards goes away if gravity is 0.
  15. llSetHoverHeight() or llGroundRepel() ETA: Setting gravity to 0 often solves a lot of problems for things that don't need gravity; llSetPhysicsMaterial( GRAVITY_MULTIPLIER, 0, 0, 0, 0);
  16. "Technically" you can pray to the linden tree and hope LL will feel like getting involved, since: Anything that could move parts of that to 'enforcement by design' rather than 'enforcement by complaint' would probably do everyone good though.
  17. There are some places on mainland where subdivision has been disabled entirely, (Bay City, Horizons, Nautilus, north east west Zindra, I think there's also a city on the old teen grid) They do generally look a bit nicer than most mainland, but part of that is just because they're so expensive to get into. Making your parcel not look bad isn't easy on the wallet or the clock.
  18. and llVecMag() to turn the vector into an absolute speed, or just square the velocity if you're comfortable working with quadrances. float min_speed = 25.0; // 5 meters per second. float prev_speed; stop_particles(){} start_particles(){} default { state_entry() { llSetTimerEvent(0.2); } timer() { vector vel = llGetVelocity(); float v = vel*vel; if(v<min_speed) { stop_particles(); // stopping particles that are off shouldn't cause any bad effects. }else if(speed_prev<min_speed) // but re-starting particles that are already on might. { start_particles(); } prev_speed = v; } }
  19. list gPosIncrements = [0.025, 0.1, 0.25 ]; list gRotIncrements = [1, 5, 25]; vector gTextColor = <0,1,0>; integer gChanListen = 475; integer gNIncrements = 3; integer gIndexIncrement; float gPosIncrement; float gRotIncrement; integer gHandleListen; string gsMain = "Poseball menu"; list glMain = ["Edit Position","Edit Rotation"]; string gsPos = "Edit position:"; list glPos = ["-X","-Y","-Z","+X","+Y","+Z","-increment","[BACK]","+increment"]; string gsRot = "Edit Rotation:"; // N.B. button names must be distinct; add a space. list glRot = ["-X ","-Y ","-Z ","+X ","+Y ","+Z ","-increment ","[BACK]","+increment "]; list gAxes = [<1,0,0>,<0,1,0>,<0,0,1>]; do_menu(string text, list l, key ID) { text += "\n Position Increment: "+llDeleteSubString((string)(gPosIncrement),5,-1); text += "\n Rotation Increment: "+(string)((integer)(gRotIncrement)); llDialog(ID,text,l,gChanListen); } default { state_entry() { llSetClickAction(CLICK_ACTION_SIT); llSitTarget(<0,0,-0.25>,ZERO_ROTATION); gNIncrements = llGetListLength(gPosIncrements); if(gNIncrements != llGetListLength(gRotIncrements)) { llOwnerSay("Warning, unequal list lengths!"); } gPosIncrement = llList2Float(gPosIncrements,gIndexIncrement); gRotIncrement = llList2Float(gRotIncrements,gIndexIncrement); } touch_start(integer n) { key ID = llDetectedKey(0); if(ID==llAvatarOnSitTarget()) { do_menu(gsMain,glMain,ID); } } changed(integer c) { if(c&CHANGED_LINK) { key ID = llAvatarOnSitTarget(); if(ID) { llListen(gChanListen,"",ID,""); do_menu(gsMain,glMain,ID); llSetAlpha(0.0,ALL_SIDES); llSetText("", <0,0,0>, 0.0); llRequestPermissions(ID,PERMISSION_TRIGGER_ANIMATION); }else { llListenRemove(gHandleListen); llSetAlpha(1.0,ALL_SIDES); llSetText(llGetObjectDesc(),gTextColor,1.0); } } } run_time_permissions(integer perms) { if(perms&PERMISSION_TRIGGER_ANIMATION) { llStopAnimation("sit"); llStartAnimation(llGetInventoryName(INVENTORY_ANIMATION,0)); } } listen(integer Channel, string Name, key ID, string Text) { list lText = [Text]; integer i = llListFindList(glMain,lText); if(0==i) // position { do_menu(gsPos,glPos,ID); }else if(1==i) // rotation { do_menu(gsRot,glRot,ID); }else { string s = gsPos; list l = glPos; integer r; // set TRUE for rotation i = llListFindList(glPos,lText); if(i==-1) { i = llListFindList(glRot,lText); r = 1; s = gsRot; l = glRot; } if(i==-1) { llSay(0,"parsing error!"); do_menu(gsMain,glMain,ID); return; } if(i==6) { gIndexIncrement*= (--gIndexIncrement>=0); // decrement, but floor at 0. gPosIncrement = llList2Float(gPosIncrements,gIndexIncrement); gRotIncrement = llList2Float(gRotIncrements,gIndexIncrement); do_menu(s,l,ID); }else if(i==7) { do_menu(gsMain,glMain,ID); }else if(i==8) { ++gIndexIncrement; if(gIndexIncrement>=gNIncrements) gIndexIncrement = gIndexIncrement-1; gPosIncrement = llList2Float(gPosIncrements,gIndexIncrement); gRotIncrement = llList2Float(gRotIncrements,gIndexIncrement); do_menu(s,l,ID); }else { vector axis = llList2Vector(gAxes,i%3); integer dir = ((i/3)*2)-1; // integer division, convert to -/+ 1. if(r) // rotation { rotation prev = llList2Rot(llGetLinkPrimitiveParams(2,[PRIM_ROT_LOCAL]),0); llSetLinkPrimitiveParamsFast(2,[PRIM_ROT_LOCAL, llAxisAngle2Rot(axis,dir*gRotIncrement*DEG_TO_RAD)*prev]); }else { vector prev = llList2Vector(llGetLinkPrimitiveParams(2,[PRIM_POS_LOCAL]),0); llSetLinkPrimitiveParamsFast(2,[PRIM_POS_LOCAL, prev+ (dir*gPosIncrement*axis) ]); } do_menu(s,l,ID); } } } }
  20. Yeah looking more closely at the comments, the llSAO version was not by ziggy, it was an edit by Chloe in 2013. Maybe she shoulda called it ZHAO III
  21. Generating a random number with a specific probability in 'dice format' is not too hard: integer n; // n = 1d20 +4 n = (integer)llFrand(20) +5; // (integer)llFrand(n) ranges from [0,n-1] so add 1 extra. // 3d6 +2 integer l; for(n=0;l<3;++l) { n+=(integer)llFrand(6); // under counts by 1. } n+=5; // n == 3d6+2 at this point. Adding a UI and making those numbers and rolls 'mean something' in the context of an interactive system is something entirely different. (integer)llFrand(n) works well enough in most situations, but if you need something "better" there's a whole rabbit hole of pseudo-random number generation theory to fall into. One method that sometimes "feels better" than actual random number generation in some contexts is to take a few copies of the list 1,2,3...n added together and llListRandomize it. then step through and re-randomize when you reach the end.
  22. Not true. ZHAO II (ETA- a version of ZHAO dating from around 2013) uses llSetAnimationOverride, but ZHAO I did not https://www.outworldz.com/cgi/freescripts.plx?ID=1016
  23. you can set a poseball to 'anyone can move' permission in the build menu. . .
  24. IMO the beauty of a poseball is that it is easy to edit and move around while you're sitting on it instead of using a menu for adjustments. As others mentioned there are a lot of poseball scripts already out there, here's one I happened to dig out of my inventory I used for a test of an animation system that I never really finished. The idea was the controller would use llGiveInventory() to give the animations to the poseball, and the poseball would delete any old animation it had. I commented out a few lines to make it more generally useable: // config vars: vector gText_color = <1,1,1>; //string gControllerName = "Poseball Controller"; // script managed vars: string gText; string gAnim; integer gNewSit = TRUE; // whether the sitter just sat down or was already sitting. //integer gHandleListen; default { state_entry() { llSitTarget(<0,0,0.15>,ZERO_ROTATION); llSetClickAction(CLICK_ACTION_SIT); gAnim = llGetInventoryName(INVENTORY_ANIMATION,0); } on_rez(integer i) { //llListen(i,"",llList2Key(llGetObjectDetails(llGetKey(),[OBJECT_REZZER_KEY]),0),""); gText= llGetObjectName(); llSetAlpha(1.0,ALL_SIDES); llSetText(gText,gText_color,1.0); } /*listen(integer Channel, string Name, key ID, string Text) { // expected format: "<position>;<rotation>" llSetRegionPos((vector)Text); Text = llDeleteSubString(Text,0,llSubStringIndex(Text,";")); llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROTATION,(rotation)Text]); }*/ touch_start(integer total_number) { integer alpha = !(integer)llGetAlpha(0); llSetAlpha(alpha,ALL_SIDES); llSetText(gText,gText_color,alpha); } changed(integer c) { if(c&CHANGED_LINK) { if(llGetNumberOfPrims()==1) { gNewSit = TRUE; }else { llRequestPermissions(llGetLinkKey(llGetNumberOfPrims()),PERMISSION_TRIGGER_ANIMATION); } } if(c&CHANGED_INVENTORY) { if(llGetNumberOfPrims()==2) { llRequestPermissions(llGetLinkKey(2),PERMISSION_TRIGGER_ANIMATION); }else if(gAnim) { //llRemoveInventory(gAnim); //gAnim = llGetInventoryName(INVENTORY_ANIMATION,0); } } } run_time_permissions(integer perms) { if(perms&PERMISSION_TRIGGER_ANIMATION) { if(gNewSit) { llStopAnimation("sit"); gNewSit=FALSE; }else { llStopAnimation(gAnim); //llRemoveInventory(gAnim); } gAnim = llGetInventoryName(INVENTORY_ANIMATION,0); llStartAnimation(gAnim); } } }
×
×
  • Create New...