Jump to content

Kaluura Boa

Resident
  • Posts

    179
  • Joined

  • Last visited

Everything posted by Kaluura Boa

  1. Hmmm... Since the changes I suggested can't affect the rest of the script, you must have done something else.
  2. That's quite easy. This script uses llOwnerSay() everywhere... except in the function say_message() where it reverts to --the ugly-- llWhisper(). Change that line and your leak is plugged say_message(string message){ llOwnerSay(message); llSetColor(<0, 1, 0>, ALL_SIDES); llSleep(0.5); llSetColor(<1, 1, 1>, ALL_SIDES);} btw, I would also change the llShout() into llRegionSay() in the function transmit(). That would greatly improve the range of the walkie-talkie. transmit(string message){ llRegionSay(transmit_channel, message); llSetColor(<1, 0, 0>, ALL_SIDES); llSleep(0.5); llSetColor(<1, 1, 1>, ALL_SIDES);}
  3. Sign me in too for llSetMemoryLimit()! I know a certain number of LSO scripts which will love the speed of Mono but without the memory penalty... PRIM_POS_LOCAL... Gaaaahhhh! How long have we been waiting for this one? I'm a little more puzzled by llSetContentType(). To me, it means we'll be able to inject a lot of crap into the internal viewer from inside SL (altho I wonder how many ppl actually use that poor crippled thing) but, on the other hand, we still won't able to just simply write in red "Access denied" to outside browsers accessing our prims. Hmmm... I have serious doubt about the usefulness of that thing.
  4. Sure, the wording was very bad and misleading. I changed it a bit. Of course, if somebody is unhappy about the changes I made, try to do better. Wikis are meant to be edited by their readers, right?
  5. The most simple way is to store in a global variable the state of the blade. So the script will only initiate the shrinking if the blade is not already shrunk... and vice-versa. (Note: Use the icon of a clipboard with a "C" to insert a script.) integer isSHRUNK = TRUE; // Assuming the blade is shrunk // when the script is compiled.vector Offset = <0.0, 0.0148, 0.3134>;init(){ llListen(73, "", llGetOwner(), "");}default{ state_entry() { init(); } on_rez(integer param) { init(); } listen(integer channel, string name, key id, string msg) { if (msg == "knife_retract") { if (! isSHRUNK) { llMessageLinked(LINK_SET, 0, "shrink", id); llSetPos(llGetLocalPos() - Offset); isSHRUNK = TRUE; } } else if (msg == "knife_deploy") { if (isSHRUNK) { llMessageLinked(LINK_SET, 0, "grow", id); llSetPos(llGetLocalPos() + Offset); isSHRUNK = FALSE; } } }} Personal advice: Do not use strings to send link messages if you are not directly interested in the content of these strings. Use the integer parameter. It's faster, uses less memory and there's no lower/upper case issues. Besides, my radar seems to detect a script in every prim. If I'm right, check llSetLinkPrimitiveParamsFast() in the wiki. (It's better to take good habits since the beginning...)
  6. (Entschuldigung für die Fehler... aber sei dankbar, daß ich auf Deutsch zu schreiben versuche.) Du solltest eine andere Viewer probieren wie, zum Beispiel, Imprudence oder Phoenix/Firestorm. Klick hier um herunterzuladen. Danach wirdst du wissen, ob das Problem von der Viewer kommt oder von deinem System... und vielleicht wirdst du auch andere Fehlermeldungen bekommen, die das Problem erklären können. Du sprichst über VFS aber du dürftest niemals Meldungen darüber sehen weil dieses Ding sehr tief in der Viewer steht. Letzte Lösung: Du kannst auch versuchen alles, das mit SL zu tun hat, zu entfernen, und auch alle verschiedenen übrigen Ordner manuell zu löschen und danach eine frische Aufstellung zu machen. (Hoffentlich wird was ich geschrieben habe ein bißchen Meinung haben.)
  7. First, you must know that it's virtually impossible to change the key of an object in-world.You can make it cross borders, attach and drop, the region can undergo rolling restarts, the key will stay the same. (I'm not 100% sure but I think to remember you can even TP with the object attached to your AV.) Any way, it's (relatively) safe to give the key of your server to whatever will need to talk to it. A mail will always work. I know of a few servers which have been using the same key for years. Still, I'd use llHTTPRequest() for speed reasons and revert to mail only when it fails, to get the new URL of the server. You don't want to use an external link but you should consider a fake DNS on Google App Engine. (Just a little script to install outside of SL which will manage names and URL.) As along as you use it only to get the URL of your server, it's very reliable (and free). That's the method I've been using for all my in-world servers since... hmmm... since http_in was released. This avoid the insane delay you get with mails and you don't have to worry about if your key will change or not. All about fake DNS on GAE and LSL from the forums archives: Click here!
  8. A bit of binary maths... integer up_left = CONTROL_ROT_LEFT|CONTROL_FWD;if ((held & change & up_left) == up_left){ llOwnerSay("up left");} Or more verbosely: if (((held & up_left) == up_left) && ((change & up_left) == up_left)) That will do the trick.
  9. Assuming that I understand correctly, you want to rotate all the child prims around the root, i.e. relatively to it. So, just do it! In other words, have a rotation and apply it. For example: rotation swivel = llEuler2Rot(<0.0, 0.0, PI/4.0>); // 45° on Z axis And then: integer i = (my_list != []); // Faster llGetListLength() while (i >= 3) { i -= 3; llSetLinkPrimitiveParamsFast(llList2Integer(my_list, i), [PRIM_POSITION, llList2Vector(my_list, i + 1) * swivel, PRIM_ROT_LOCAL, swivel * llList2Rot(my_list, i + 2)]); }  That should do it.
  10. Short answer: No. Long answer: Noooooooooooo. The best you can do is to detect if the dedicated voice anims are played, meaning that the AV is talking. Altho, all I know about these anims is that they exist and are used by some voice gestures in the library. I cannot garanty that they are ever played. I don't use voice, my accent sounds better with a keyboard.
  11. I said "assuming there is no typo". Anyway, I fixed the function and made a real script around my functions. It works, even for numbers greater than 99. [05:42] Object: 160.565100 --> ã?:9 --> 160.565100[05:43] Object: 150.431700 --> Ù(h™ --> 150.431700[05:43] Object: 120.982200 --> »¥l~ --> 120.982200[05:43] Object: 149.425500 --> Ø'=S --> 149.425500[05:43] Object: 115.898900 --> ¶``& --> 115.898900[05:43] Object: 238.102100 --> ıal' --> 238.102100[05:43] Object: 117.986400 --> ¸¥F: --> 117.986400 (Those numbers are weird. I do not know why they all end up with "00". llFrand() should not do that.) It is however true that if you do not use numbers greater than 99.999999, my functions will use only the 100 first chars of 'Base256Char'. We can do better with 3 chars only but the range of the compressable numbers falls to 0 to 7.999999. Here is the script (Garantied without typo and working): string Base256Chars = "0123456789abcdefghijklmnopqrstuvwxyz!\"#$%&'()*+™-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅ";string uuCompress(float f){ integer k = (integer)f; f -= (float)k; k = (k & 0x7) << 21; // from 0 to 7 string flt = (string)f; integer b = 14; integer i = 2; for (; i <= 6; i += 2) { k = k | ((integer)llGetSubString(flt, i, i + 1) << b); b -= 7; } string result; for (b = 16; b >= 0; b -= 8) { i = (k & (0xFF << b)) >> b; result += llGetSubString(Base256Chars, i, i); } return result;}float uuDecompress(string zz){ integer k = 0; integer b = 16; integer i = 0; for (; i <= 2; ++i) { k = k | (llSubStringIndex(Base256Chars, llGetSubString(zz, i, i)) << b); b -= 8; } float flt = (float)((k & 0xE00000) >> 21); string result = "0."; for (b = 14; b >= 0; b -= 7) { result += llGetSubString("0" + (string)((k & (0x7F << b)) >> b), -2, -1); } return flt + (float)result;}default{ touch_start(integer total_number) { float ff = llFrand(8.0); string comp = uuCompress(ff); llOwnerSay((string)ff + " --> " + comp + " --> " + (string)uuDecompress(comp)); }} Some testing in-world: [07:14] Object: 5.265731 --> éßâ --> 5.265731[07:14] Object: 4.209079 --> È*V --> 4.209079[07:15] Object: 7.435775 --> ĭğĎ --> 7.435775[07:15] Object: 0.858818 --> l¯i --> 0.858818[07:15] Object: 3.041920 --> ¤9× --> 3.041920[07:15] Object: 6.091103 --> ąLÆ --> 6.091103 It works! Some binary babble (if you understand that kind of language): To encode a number from 0 to 99 in binary, we need only 7 bits. So we split the "tail" behind the decimal point in 3 parts and we shift them to fill the 21 lowest bits of an integer (32 bits). The integer part of the number is shifted into the 23-21 bits. So we have an integer with 24 significant bits that we split/shift in 3 numbers of 8 bits (from 0 to 255) which give us indices to concatenate 3 chars from 'Base256Chars'. Decompression simply works the other way around. From the indices of the 3 chars, we re-build the integer with 24 significant bits that we can then split/shift to re-write the float.
  12. Altho I fail to see the point, you can compress a float with a base 256 algorithm. Here are 2 functions to convert a float to a 4-char string and back: This should work (assuming there are no typo). string Base256Chars = "0123456789abcdefghijklmnopqrstuvwxyz!\"#$%&'()*+™-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅ";string uuCompress(float f){ integer k = (integer)f; string result = llGetSubString(Base256Chars, k, k); f -= (float)k; string flt = (string)f; integer i = 2; for (; i <= 6; i += 2) { k = (integer)llGetSubString(flt, i, i + 1); result += llGetSubString(Base256Chars, k, k); } return result;}float uuDecompress(string zz){ string result; integer i = 1; for (; i <= 3; ++i) { integer k = llSubStringIndex(Base256Chars, llGetSubString(zz, i, i)); result += llGetSubString("0" + (string)k, -2, -1); } return (float)llSubStringIndex(Base256Chars, llGetSubString(zz, 0, 0)) + (float)("0." + result);}default{ touch_start(integer total_number) { float ff = llFrand(256.0); string comp = uuCompress(ff); llOwnerSay((string)ff + " --> " + comp + " --> " + (string)uuDecompress(comp)); }} Note that these functions handle only positive numbers from 0 to 255.999999. (Handling negative numbers is possible with a reduction of the range of the supported numbers.)
  13. The first thing that comes to my mind is that push is disabled on the parcel where you are doing your tests. In that case, the only thing a script can push is other objects and its owner. There is no way around enabling push on the parcel first... and that cannot be done by script.
  14. Sorry, I can't help you with any version of Windows. I'm a Linux guy. The post from Ansariel hereabove has a link about how to do it for XP. (I recognize the Fisherprice windows.) Google is your friend for the other versions. Just search for "change DNS Windows 7" (for example) and you'll get more than you'll ever need to know.
  15. After having sent my previous post, I made my homework... and managed to log in. Gory technical details: My /etc/resolv.conf contained only the IP of my router as nameserver. It worked for everything which accesses Internet except SL v2.7.1. Even the previous v2.6.0 I had worked this way! I explicitely wrote the 2 IPs of OpenDNS (subliminal ad) --which is also set directly in my router-- and it worked. End of story. As for switching to Basic mode, no can do! I only have Advanced mode available. And this v2 will go back in the depths of its closet. I could detail all that I hate about it but it suffices to say that I still see v2.0, minus the "Speak" button, plus that ridiculous mini-floater with parcel information, and I still don't know if I should cry or laugh about the detachable tabs. Besides, the shadows are now bugged while they were working fine in v2.6. Totally useless! I'll keep on using Imprudence which works, suits my needs and desires, and I'm waiting for Kokua.
  16. So, I just installed the latest v2 (Linux version), started it, restored my graphics settings that v2 loves to delete with every new install, clicked "Log in" and... Login failed. DNS could not resolve host. I tried several times. Since I can see the new blurry login pictures, it's obvious the viewers accesses the outside world. And since I can rant in this forum, my Internet connection seems to work. But no, always the same error. The sim I try to access is online, my regular AV is in it, logged in with Imprudence. I tried the Beta Grid (Aditi), no difference. Any idea about what to do with this huge failure called v2 once I'll stop laughing?
  17. I tried to retrieve why I didn't like llRotBetween() and now I know. It introduce some parasite rotation on one axis which leads to object to go upside down when the vectors used in the formula are opposite like <1.0, 0.0, 1.0> and <-1.0, 0.0, 1.0>... but not <1.0, 0.0, 0.0> and <-1.0, 0.0, 0.0>. In other words, it's quite unreliable and I'm also starting to wonder if the vector returned by llWind() has always z == 0. If not, that explains the upside down bug. As for llRotLookAt(), I think it's a bit overkill if the object doesn't use physics. llSetRot() is well enough to follow the wind.
  18. Second, I'd remove llGetLocalRot() from your formula. But first, I wouldn't use llRotBetween() which doesn't work well in every situation. default{ state_entry() { llSetTimerEvent(1.0); } timer() { vector wind = llWind(ZERO_VECTOR); llSetRot(llEuler2Rot(<0.0, 0.0, llAtan2(wind.y, wind.x) + PI>)); }} My formula over here point the X axis of the prim toward the wind and I'm sure the prim will never turn upside down.
  19. I wouldn't go as far as using binary trees. To me, optimization in LSL rhymes with "the least code as possible". Still, I agree with Void that you should avoid manipulating strings if you're not directly interested by the result. Use llListFindList() and work with integers. Much faster! As for "else if" vs. "if", there is another possibility: To use the keyword "return". I find it very useful. It works as well in an event as in a function --with or without returned value. some_event(some_params) { integer choice = llListFindList(list_of_choices, [param]); if (choice == something) { do_stuff(); return; // Skip the rest! } if (choice == something_else) { do_more_stuff(); return; // Skip the rest! } if (choice == last_choice) { do_something(); // return; // Useless here. } } Some zealots will disagree and chant very loudly "Everything should have only one entry and one exit" but you just have to ignore the voices that don't come from inside your head... 
  20. Lot of things to say... Sorry if I lack of diplomacy sometimes but my first reaction when I saw your post was: What a mess! First, you must use the special function of the editor to insert a script (The clipboard with a kind of square C.) or else things get messy. Second, keep your curly brackets under control. Always use them even when not mandatory... but don't add superfluous ones. Any other approach is meant to lose yourself, the compiler or everybody else. That was for the form. Next, the script. Don't use LINK_SET unless that's what you really need. It targets all the scripts in the object unnecessarily. You may want to look at the new function llLinkParticleSystem() that would eliminate all the link messages. So you can store your particles parameters in a list, change what you want and re-apply. I didn't check if your script even compiles but I can already say it doesn't work. At least, the dialogs don't. They use a channel to which the script doesn't listen. Next, when you start copying the same line over and over. It's time to think of a user function. Any way... I made an agnostic script which deals only with the dialogs and the rate/size values. It's up to you to do what you want with them.  integer CHANNEL = -67754;string SPC = " ";list RATE_BUTTONS = ["LOW", "2", "3", "4", "5", "6", "7", "8", "HIGH"];list SIZE_BUTTONS = ["1", "2", "3", "4"]; // Max particle size == 4mstring MAIN_TITLE = "MAIN MENU";string SIZE_TITLE = "Blink SIZE";string RATE_TITLE = "Blink RATE";integer MAIN = 0;integer SIZE = 1;integer RATE = 2;integer CurrentDialog;key OwnerKey;list uuReorderButtons(list buttons){ integer i = (llGetListLength(buttons) % 3); // First, make sure we have only full lines of 3 buttons if (i) { i = 3 - i; for (; i > 0; --i) { buttons += SPC; } } // Next, invert the order of the lines i = llGetListLength(buttons); if (i > 3) { integer k = i / 3; i -= 3; for (; k > 0; --k) { buttons = llList2List(buttons, i, i +2) + llList2List(buttons, 0, i - 1); } } llOwnerSay(llDumpList2String(buttons, "|")); return buttons;}uuMainDialog(){ CurrentDialog = MAIN; llDialog(OwnerKey, MAIN_TITLE, [size_TITLE, RATE_TITLE], CHANNEL);}uuSizeDialog(){ CurrentDialog = SIZE; llDialog(OwnerKey, SIZE_TITLE, [MAIN_TITLE, SPC, SPC] + uuReorderButtons(SIZE_BUTTONS), CHANNEL);}uuRateDialog(){ CurrentDialog = RATE; llDialog(OwnerKey, RATE_TITLE, [MAIN_TITLE, SPC, SPC] + uuReorderButtons(RATE_BUTTONS), CHANNEL);}uuLastDialog(){ if (CurrentDialog == MAIN) { uuMainDialog(); } else if (CurrentDialog == SIZE) { uuSizeDialog(); } else if (CurrentDialog == RATE) { uuRateDialog(); }}default{ state_entry() { OwnerKey = llGetOwner(); llListen(0, "", OwnerKey, "x"); // Filter, plz! llListen(CHANNEL, "", OwnerKey, ""); } listen(integer channel, string name, key id, string msg) { if (channel == 0) { uuMainDialog(); return; // Skip the rest! } if (channel == CHANNEL) { if (msg == SPC) { uuLastDialog(); //Re-open current dialog. return; // Skip the rest! } // // Navigation in the dialogs // if (msg == MAIN_TITLE) { uuMainDialog(); return; // Skip the rest! } else if (msg == SIZE_TITLE) { uuSizeDialog(); return; // Skip the rest! } else if (msg == RATE_TITLE) { uuRateDialog(); return; // Skip the rest! } // // Real content of the dialogs // if (CurrentDialog == SIZE) { integer k = llListFindList(SIZE_BUTTONS, [msg]); if (k != -1) { ++k; vector size = <k, k, 0>; // Do what you want from here... llOwnerSay("Selected size: " + (string)size); } } else if (CurrentDialog == RATE) { integer k = llListFindList(RATE_BUTTONS, [msg]); if (k != -1) { integer rate = 9 - k; // Do what you want from here... llOwnerSay("Selected rate: " + (string)rate); } } } }} It compiles and works... but if it was my script, I'd re-open the main dialog after a selection and I'd add a close button.
  21. Just a little precision: The "wonderful CAT airships" use llMoveToTarget(). I scripted them so I'm sure of it. (And thanks for the "wonderful"... It's always appreciated.)
  22. It can be done without adding a real hinge prim. Here is my little script to put into the linked door: vector Hinge;vector Door;rotation CloseRot;float OpenAngle;float Steps = 400.0; // Speed (More means slower and vice-versa.)// llSLPPF() is VERY efficient...integer isOpened = FALSE;uuPivot(integer open){ float step = OpenAngle / Steps; if (open) { float aa = 1.0; for (; aa <= Steps; aa += 1.0) { rotation rot = llEuler2Rot(<0.0, 0.0, step* aa>) * CloseRot; llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, Hinge + (Door * rot), PRIM_ROT_LOCAL, rot]); } } else { float aa = Steps - 1.0; for (; aa >= 0.0; aa -= 1.0) { rotation rot = llEuler2Rot(<0.0, 0.0, step* aa>) * CloseRot; llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, Hinge + (Door * rot), PRIM_ROT_LOCAL, rot]); } }}default{ state_entry() { // Door: Dimple 0.2 to whatever vector scale = llGetScale(); Hinge = (<0.0, 0.0, scale.z * -0.5> * llEuler2Rot(<PI_BY_TWO, (0.2 - 0.5) * PI, 0.0>)); // Hinge pos calculated according to dimple and sphere radius. CloseRot = llGetLocalRot(); // Door must be closed to save/reset the script Door = (llGetLocalPos() - Hinge) / CloseRot; // Door pos relatively to Hinge pos OpenAngle = PI_BY_TWO - (PI / 10.0); // PI/2 minus a little something isOpened = FALSE; } touch_start(integer total) { isOpened = !isOpened; uuPivot(isOpened); }} In not too mathematical words: The script calculates the postion of the hinge using the bottom dimple and the size and rotation of the door, then it calculates the position of the door relative to this virtual hinge. It writes the rotation of the closed door on a little paper. After that, you just need to add a little rotation in the formula to make the door... rotate. This also needs the door to move but llSLPPF() is your friend in here, with the new PRIM_ROT_LOCAL. (I send you the object in-world.)
  23. Void pointed you in the right direction... Here is the full script. I assumed the messages "Sitting" and "Standing" are the triggers to start/stop reading. key kQuery;integer iLine = 0;string thenote = "New Note";integer doREAD = FALSE;default{ link_message(integer sender, integer num, string msg, key id) { if (msg == "Sitting") { iLine = 0; // Read from the beginning doREAD = TRUE; // Reading allowed kQuery = llGetNotecardLine(thenote, iLine); } else if (msg == "Standing") { doREAD = FALSE; // Stop reading } } dataserver(key query_id, string data) { if (query_id == kQuery) { if (data == EOF) { if (doREAD) // Don't restart unless allowed { iLine = 0; kQuery = llGetNotecardLine(thenote, iLine); } } else if (doREAD) // Don't go on unless allowed { llSay(0, data); llSleep(5.0); ++iLine; kQuery = llGetNotecardLine(thenote, iLine); } } }} If there is no typo, that should work...
  24. @Void with a delay... No, this is not a typo. Invisiprim texture plus transparency at 100%. Of course, the invisiprim trick does not work any more so the prims have no effect in-world but it has an effect on the map apparently.
  25. Mystery solved! No need for script. Just apply once the invisiprim texture, set transparency to 100%. This has no effect on prims or avatars in-world but it will punch holes on the map into prims that would appear otherwise. Apparently, there is no need to use a texture with alpha to have holes. The only thing I do not know is how "deep" these holes are. Since prims are visible below, they must not reach the ground.
×
×
  • Create New...