Jump to content

Susie Chaffe

Resident
  • Posts

    30
  • Joined

  • Last visited

Everything posted by Susie Chaffe

  1. llGetUnixTime for dialog channel - I am stealing that idea 🤩
  2. A long long time ago, the Lindens ran an inventory garbage collector routine...and my lost and found filled with many a missing 'precious'. I wonder if that it still possible.
  3. Interesting if not particulary helpful. 2x Midnight Mania boards at a well known store that uses the Caspervend system. Both boards announced they were delivering. One prize received....on prize "Cannot create requested inventory". So, intermittant, irrational, and so SL!
  4. As of today this is still happening - I have even had an inworld vendor fail to deliver - Live Chat are blaming it on the Firestorm viewer - but people on the official viewer are having the same problems
  5. Nothing that technical....they just forgot to feed the hamster that drives the power wheel
  6. It is the asset servers https://twitter.com/SLGridStatus
  7. Sandboxs Goyer, Bricker and Colborne all got double rolled
  8. A list of sounds built into second life can be found here http://wiki.secondlife.com/wiki/Client_sounds A lot of scripts simply use the uuid for a sound rather than include a sound item in the objects inventory. The same applies to textures. The only item that has to be placed in object inventory is an animation.
  9. This has not shown up in the forums for a while so I thought it maybe time for a reminder for anyone brave enough to put up with the current state of region crossings. Because llMoveToTarget only accepts region coordinates, it is frequently assumed that it can only be used within a single region. Not true. Given a target outside of it's current region an object will travel far enough into an adjacent region to trigger a CHANGED_REGION event. At this point a new target can be calculated and the object can proceed on its merry way. Any distance can be covered as long as it is broken down into steps .The maximum distance that can be moved in one hop is 64 metres - but based on experience I would recommend a slightly lower value. Below is a sample tour script that demonstrates one method of inter sim travel. The script also attempts to maintain an almost constant velocity throughout each move. I have included a short sample tour from Blake Sea Spyglass to Barbarossa infohub. There is rez zone at the end of the pier in Spyglass where you can create or rez a tour disc. slurl: http://maps.secondlife.com/secondlife/Blake%20Sea%20-%20Spyglass/145/213/22 Note. This is a rework of a script that appeared in the legacy scripting archives somewhere around 2005 - thanks to the original creator whoever you are. //Tour Gadget using llMoveToTarget - Susie Chaffe 2008-2013 integer DEBUG = FALSE; //--------------------- Target Variables ---------------------- vector gTargetLocal; // Target in Region coordinates vector gTargetRC; // Target Region Corner vector gCurrentPos; // Current position in Region coordinates vector gCurrentRC; // Current Region Corner //--------------------- llMoveTo Control Variables ------------- integer targetID; vector gMoveTo; // Next target vector float maxStepSize = 60.0; // Avoid using the 64metre limit of llMoveToTarget float range = 0.5; // at_target condition float speed = 5.0; // // -------------------- Notecard Reader Variables -------- string gNotecard; // name of route notecard in the object's inventory integer gLine = 0; // current line number key gQueryID; // id used to identify dataserver queries list gLstData; // List to hold notecard line for parsing to commands string gCommand; //--------------------- User Functions --------------------------- gNextLine() { ++gLine; gQueryID = llGetNotecardLine(gNotecard, gLine); } waypoint() { llSetStatus(STATUS_PHYSICS | STATUS_PHANTOM, TRUE); gTargetLocal = (vector)llList2String(gLstData, 2); //Local xyz gTargetRC = (vector)llList2String(gLstData, 3); //Region Corner gCurrentPos = llGetPos(); gCurrentRC = llGetRegionCorner(); if (gTargetRC == gCurrentRC) gMoveTo = gTargetLocal; else gMoveTo = gTargetLocal + (gTargetRC - gCurrentRC); vector vectorAngle = gMoveTo - gCurrentPos; float distance = llVecMag(vectorAngle); //Calculate Distance if(distance <= range) { llTargetRemove(targetID); llStopMoveToTarget(); gNextLine(); return; } else { if (distance > maxStepSize) distance = maxStepSize; gMoveTo = gCurrentPos + llVecNorm(vectorAngle)*distance; targetID = llTarget(gMoveTo, range); llLookAt(gMoveTo,1,1); llMoveToTarget(gMoveTo,distance/speed); } } //----------------------Create Personal Transport Device------------------------- makePTD() { llSetLinkPrimitiveParamsFast(LINK_THIS,[ PRIM_TYPE, PRIM_TYPE_SPHERE, 0, <0.0, 1.0, 0.0>, 0.0, ZERO_VECTOR, <0.0, 1.0, 0.0> , PRIM_SIZE, <0.1, 0.5, 0.5> , PRIM_ROTATION, <0.0, 0.70711, 0.0, 0.70711> , PRIM_TEXTURE, 0, "5748decc-f629-461c-9a36-a35a221fe21f", <1.0, 1.0, 0.0>,ZERO_VECTOR, 0.0 , PRIM_COLOR, 0, <0.5, 0.0, 0.0>, 1.0 , PRIM_BUMP_SHINY, 0, PRIM_SHINY_MEDIUM, PRIM_BUMP_NONE]); llSetClickAction(CLICK_ACTION_SIT); llSitTarget(<-0.76916, 0.004, -0.09061>, <0.0, -0.70711, 0.0, 0.70711>); llSetPos(llGetPos() + <0.0,0.0,0.75>); llSetText("Sit to Start \n Tour \n \n ", <1.0, 1.0, 1.0>, 1.0); } //------------------------------------------------------------------------------- default { on_rez(integer start_param) { llResetScript(); } state_entry() { makePTD(); } changed(integer change) { if (change & CHANGED_LINK) { llSleep(0.5); if (llAvatarOnSitTarget() != NULL_KEY) { llSetText("", ZERO_VECTOR, 0.0); state Tour; } } } } state Tour { on_rez(integer start_param) { llResetScript(); } state_entry() { llSetStatus(STATUS_PHYSICS | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE); llSetStatus(STATUS_ROTATE_X, TRUE); gNotecard = llGetInventoryName(INVENTORY_NOTECARD, 0); gQueryID = llGetNotecardLine(gNotecard, gLine); } dataserver(key query_id, string data) { if (query_id == gQueryID) { if(data != EOF) { // Delete Comments Routine by Void Singer integer comment = llSubStringIndex (data, "//"); if (~(comment = llSubStringIndex( data, "//" ))) data = llDeleteSubString( data, comment, -1); data = llStringTrim( data, STRING_TRIM ); if (data) { if(DEBUG) llOwnerSay((string) gLine + " : " + data); llToUpper(data); gLstData = llParseString2List(data, ["|"], []); gCommand = llList2String(gLstData, 0); if("W" == gCommand) waypoint(); else gNextLine(); } else gNextLine(); } else { llSetStatus(STATUS_PHYSICS | STATUS_PHANTOM, FALSE); llUnSit(llAvatarOnSitTarget()); llSleep(1.0); llDie(); } } } not_at_target() { float thisStep = llVecDist(llGetPos(),gMoveTo); llMoveToTarget(gMoveTo,thisStep/speed); } at_target( integer number, vector targetpos, vector ourpos ) { llTargetRemove(targetID); waypoint(); } changed(integer change) { if (change & CHANGED_REGION) { gCurrentRC = llGetRegionCorner(); waypoint(); } else if (change & CHANGED_LINK) { if (llAvatarOnSitTarget() == NULL_KEY) { llSleep(0.5); llDie(); } } } } //============================================================================Sample Tour - copy and paste into a new notecard: W|Blake Sea - Spyglass|<145,212,40.0>|<290048,269568,0> W|Blake Sea - Spyglass|<152,110,40.0>|<290048,269568,0> W|Blake Sea - Half Hitch|<116,152,35.0>|<290048,268800,0> W|Blake Sea - Half Hitch|<72,122,35.0>|<290048,268800,0> W|Barbarossa|<175,19,24.0>|<289792,268800,0> W|Barbarossa|<175,19,21.0>|<289792,268800,0>
  10. I wrote a menu handler for rezzing items out of an inventory storage box. Its a little long winded but it will handle any number of items and deal with the 24 character limit on buttons. Feel free to adapt as needed. I won't try and post the code in this message ...just follow this link https://wiki.secondlife.com/w/index.php?title=User:Susie_Chaffe
  11. A little late coming to the party - the example you used is restricted to 2 pages This script should handle any number of items and is customisable to a certain extent. It is a cut down and adapted version of one I use for populating a dance hud. Replace // Dialog Based Object Rezzer Script// Susie Chaffe 2013// Free to use modify and mangle as you see fit // No Limit on Number of Object Names// Handles 24 character limit by creating alised object names// Has the option to create custom buttons / submenus if required// Is a little long winded for the sake of clarity //======================= SYSTEM VARIABLES ==========================// vector vRezPos = <0.00, 0.00, 1.00>;integer dialogChannel;integer dialogHandle;integer iInvType = INVENTORY_OBJECT;integer iPageIdx = 0;list lstShortName; //======================= CUSTOM FUNCTIONS ==========================// // Create Short name for Long Object Names and add to a look up list// Note that only the first 12 characters will normally show on the menu button// You can use a shorter substring if you preferstring AliasName(string sLongName){ string sShortName = (llGetSubString(sLongName,0,23)); lstShortName += [sShortName,sLongName]; return sShortName;} // Reorder Buttons as shown in listlist order(list buttons){ return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);} // Dynamic menu dialog functiondoDialog(key av){ // Standard Buttons that will appear on every page - normally navigation buttons list lstStatic = ["<< PREV","< MAIN >","NEXT >>"]; integer iBtnSlots = 12-llGetListLength(lstStatic); // Optional extra buttons that will only appear on the first page // Can be used to create sub-menus if required // list lstExtraBtn = []; // **Use this if you no extra buttons list lstExtraBtn = ["-CONTENTS-"]; // ** This is just an example integer iAdjSlots = llGetListLength(lstExtraBtn); // Dynamic buttons - read from inventory object names integer iTotalNames = llGetInventoryNumber(iInvType); // Calculate menu last page index integer iMaxPageIdx = (llFloor((float) (iTotalNames + iAdjSlots) / (float) iBtnSlots)); // First & Last Page Navigation Toggle if (iPageIdx < 0 ) iPageIdx = iMaxPageIdx; else if (iPageIdx > iMaxPageIdx) iPageIdx = 0; // Build the button list list lstDialog = []; lstShortName = []; integer idxSlot = iPageIdx*iBtnSlots; integer i; // First menu page that has extra buttons if((0 == iPageIdx) && ([] != lstExtraBtn)) { for(i = idxSlot; (i < idxSlot+iBtnSlots-iAdjSlots) && (i <= iTotalNames-1 ); i++) { string sItemName = llGetInventoryName(iInvType,i); if(24 < llStringLength(sItemName)) sItemName = AliasName(sItemName); lstDialog += [sItemName]; } //Add the Extra button(s) lstDialog += lstExtraBtn; } // Other Pages or First Page if no extra buttons else { for(i = idxSlot; (i < idxSlot+iBtnSlots) && (i <= iTotalNames-1 + iAdjSlots); i++) { string sItemName = llGetInventoryName(iInvType,i-iAdjSlots); if(24 < llStringLength(sItemName)) sItemName = AliasName(sItemName); lstDialog += [sItemName]; } } // Add Static Btns to the end of the Dyanamic List lstDialog += lstStatic; // Menu message string msg = " \n Choose an Option: " + "Page " + (string) (iPageIdx+1) + " of " + (string) (iMaxPageIdx + 1); //Open a Listen dialogChannel = (integer)llFrand(DEBUG_CHANNEL)*-1; dialogHandle = llListen(dialogChannel, "", "", ""); // Call Function and set a time out for the listen llDialog(av, msg , order(lstDialog), dialogChannel); llSetTimerEvent(30.0);} close_menu(){ llSetTimerEvent(0); llListenRemove(dialogHandle);} //=============================== RUN TIME =========================================// default{ touch_start(integer total_number) { key id = llDetectedKey(0); close_menu(); doDialog(id); } listen( integer channel, string name, key id, string msg ) { close_menu(); if(msg == "< MAIN >") { iPageIdx=0; doDialog(id); return; } else if(msg == "<< PREV") { iPageIdx--; doDialog(id); } else if(msg == "NEXT >>") { iPageIdx++; doDialog(id); } else if(llGetInventoryType(msg) == 6) { llRezObject(msg, llGetPos() + vRezPos, ZERO_VECTOR, llGetRot(), 0); } else if(~llListFindList(lstShortName, [msg])) { integer idx = llListFindList(lstShortName, [msg]); llRezObject(llList2String(lstShortName,idx+1), llGetPos() + vRezPos, ZERO_VECTOR, llGetRot(), 0); } // Example of Extra Button else if(msg == "-CONTENTS-") llSay(0, "There are " + (string) llGetInventoryNumber(iInvType) + " items in this container"); } timer() { close_menu(); }} //=============================================================================================//
  12. Mordicub region offline for well over an hour aleady - is anyone else having issues.
  13. I needed a dialog menu that has extra command buttons on the first page but not on the rest. I went searching in the library and the forums, but everthing I found was horribly complex. I came up with the following function which seems to work ok. It handles static buttons on every page, special buttons on first page and cycles through pages. I am open to comments and constructive critism to make it better. I don't script all that often these days Before anyone points out I havn't removed the listen, it was deliberate to aid clarity. The code below is a complete script, just copy and paste. // Dialog function to handle extra command buttons on first page of menu // GLOBALS integer chDialog; integer iPageIdx; list lstAlpha = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R"]; // USER FUNCTIONS list order_buttons(list buttons) { return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10); } dialogUser(key av) { // Buttons that will appear on every page - normally navigation buttons list lstStatic = ["<< PREV","MAIN","NEXT >>"]; integer iSpaces = 12-llGetListLength(lstStatic); // Extra buttons that will appear only on the first page list lstExtraBtn = ["Special 1","Special 2","Special 3"]; integer iAdjSpaces = llGetListLength(lstExtraBtn); // Dynamic buttons - read from list modify script to read from inventory integer iDynLen = llGetListLength(lstAlpha); // Calculate menu last page index integer iMaxPageIdx = (llFloor((float) (iDynLen + iAdjSpaces) / (float) iSpaces)); // Keep pages within limits if (iPageIdx < 0 ) iPageIdx = iMaxPageIdx; else if (iPageIdx > iMaxPageIdx) iPageIdx = 0; // Build the button list list lstDialog = []; integer idxSlot = iPageIdx*iSpaces; integer i; if((0 == iPageIdx) && ([] != lstExtraBtn)) { for(i = idxSlot; (i < idxSlot+iSpaces-iAdjSpaces) && (i <= iDynLen-1 ); i++) lstDialog += [llList2String(lstAlpha,i) ]; lstDialog += lstExtraBtn; } else for(i = idxSlot; (i < idxSlot+iSpaces) && (i <= iDynLen-1 + iAdjSpaces); i++) lstDialog += [llList2String(lstAlpha,i-iAdjSpaces) ]; lstDialog += lstStatic; // Finally give the user a dialog using order_buttons function to make it sort properly llDialog(av, " \n Choose an Option", order_buttons(lstDialog), chDialog); } // STATES default { state_entry(){ chDialog = ( -1 * (integer)("0x" + llGetSubString((string)llGetKey(),-7,-1)) ); llListen( chDialog, "", NULL_KEY, "" ); } touch_start(integer num_detected) { dialogUser(llDetectedKey(0)); } listen( integer channel, string name, key id, string msg ) { key k = id; if(msg == "<< PREV") { iPageIdx--; dialogUser(k); } else if(msg == "NEXT >>") { iPageIdx++; dialogUser(k); } else if(msg == "MAIN") { iPageIdx=0; dialogUser(k); } else llOwnerSay("You chose : " + msg); } } <\lsl>
  14. Ouch! Thank you Kaluura - those are very telling results. They clearly show what would happen if you tried to run a looped circuit (think monorail or tram). For any degree of accuracy the movement will have to be recalculated for every step using a fixed point as reference.
  15. Yes its a polygon - that is currently the only way to approximate a curve with the current toolset. failed ............yes and no The primary objective was to produce a visually smooth turn rather than a sharp right angle.....it does. The assumed result that it would finish where it was intended to... is a fail. The magnitude of error is not massive and can be corrected by reference to a fixed point following the turn. I had the opportunity to bring this question up at Simon Linden's office hour yesterday. It was mentioned that "drift" had been noticed even in simple lateral motion...though this is difficult to repro. There was some suggestion that region time dilation might be affecting the movement during a given frame. Like many things in SL...half the fun is working out how to get around its shortcomings As for the bad computation....thats why I asked for help :matte-motes-smile:
  16. All my previous vehicles have used physical motion, but with the arrival of llSetKeyframedMotion I thought I would experiment a little. Linear motion is good, and region crossings present no unusual problems. Turns are ugly...the strength/damping effect of llRotLookAt on non-physical objects is relatively ineffective. I have tried to smooth the turns by creating a keyframe list from interpolated points on an arc. This is in the form of a function that will eventually be called from a command in a route notecard. The gTurnLR is simply a hack to get it working for testing The script works...but there is a certain amount of drift by the time the object reaches its final point. I had ascribed this to rounding errors, but now I am not so sure. There is quite a variance in results. I plan most turns to be 90 degrees..but this script will make an object complete a circle. If you want to test, you will need a mesh enabled viewer so you can set a normal prim to a convex hull, and access to a region running Magnum. I struggle with rotations...so I am open to any suggestions on refining this script, or taking a completely different approach to the problem. integer gTurnLR; //-1 for clockwise (right turn) 1 for anticlockwise (left turn) list glstFrames; //list of keyframes makeKeyFrames(vector vStepPos, rotation qStepRot) { glstFrames = []; float fRadius = 10.0; //radius of turn integer iSteps = 24; //variable depending on radius of turn - experiment! float fTime = 1.0; //KeyFrame step time interval rotation vRotArc = llEuler2Rot( <0.0, 0.0, (TWO_PI/iSteps)*gTurnLR>); // step angle -radians vector vPosOffset = <0.0, fRadius*gTurnLR, 0.0>; // radius of turn integer i; for(i=0;i< iSteps ;i++) // iSteps/4 for a 90 degree turn { vector vKeyFrame = vStepPos; // http://wiki.secondlife.com/wiki/Rotation vStepPos = vStepPos + (vPosOffset - vPosOffset * vRotArc) * qStepRot; qStepRot = vRotArc * qStepRot; vKeyFrame = vStepPos - vKeyFrame; //relative to last frame glstFrames += [vKeyFrame, vRotArc, fTime]; } } default { touch_start(integer total_number) { gTurnLR = -1; //clockwise turn - actual value from route notecard makeKeyFrames(llGetPos(),llGetRot()); llSetKeyframedMotion(glstFrames, [KFM_MODE, KFM_FORWARD]); } } Grr...trying to edit a post is "challenging"
  17. I still remember when that "window of opportunity" appeared and many us went rushing around making as many megas as we could. When the window closed then came the frustration. Why on earth didn't I make that 43.7x16.2x0.02 prim - :matte-motes-tongue:
×
×
  • Create New...