Jump to content

Fenix Eldritch

Resident
  • Posts

    771
  • Joined

Everything posted by Fenix Eldritch

  1. If the variable is expected to contain a boolean (or something that can be interpreted as such), it's not uncommon to place that alone in the if-statement without the "==" operator. The if-statement will understand that an implicit comparison to the boolean TRUE value is being made. In this specific example, the for loop is effectively performing comparison test and adding the result of the comparison to c. Recall that TRUE is equivalent to 1 and FALSE equivalent to 0. So let's substitute the values. For the first iteration, the line becomes: c += (25.0 == 25.0); Since 25.0 is equal to 25.0, the comparison succeeds and is evaluated as 1, which is then assigned to the c variable. This will happen once more, as only two of the possible list values are equal to 25.0. Ultimately when we get out of the loop, c=2, which since it's not 0, would be equivalent to TRUE. If I recall correctly, any positive integer value will be interpreted as TRUE in LSL. When we get to the final line, the if-statement will evaluate and substitute any variables in the conditional with their current values. So "if(c)" is the same as "if(2)", which is the same as "if(TRUE)". And because of the implicit comparison I mentioned earlier, this is effectively the same as saying "if(TRUE==TRUE)". So this test passes and the code will execute the last command. That last command is "result = 100.0 / (float)c;" Which is another shorthand as well. If-statements that contain only one command afterward can be formatted to one line as shown above. It is the same as: if (c) { result = 100.0 / (float)c; } Edit: my original post misread the code and I thought variable m was assigned to be 100.0. If that had been the case, then c would have come out of the loop equaling 0 which would have been the same as FALSE, and the last command would have not been executed. But since that's not the case and c=2, the final command is executed and we have a result of 50.0 (percent). Edit2: crossed out some incorrect reasoning. See Wulfie's post below.
  2. If you've already gotten it all working when an avatar sits on the object, then you can take that working code and move it into a touch_start event instead of the changed event.
  3. Heh, I chose that expression deliberately because that's what I felt the result of using physics enabled linksets would probably look like. Allow me to back track a bit to further illustrate my reasoning. And I feel I should point out that these are just my own observations. Don't take what I say as the final word - I'm just one point of view. Physical objects/vehicles are able to make updates to their position/orientation in a much faster and smoother way when compared to the other LSL functions. They can be acted upon by outside forces like gravity, friction, collisions, or internal (scripted) forces like impulses and motors. This all happens very "naturally" and the user doesn't need to get bogged down in the gory details thanks to the physics engine doing that heavy lifting. For example, the user doesn't have to worry about scripting the vehicle to angle up as it rolls over an obstacle, it will naturally do that. This is all well and good for typical applications like an independent self contained object. But when you want to make multiple objects move in tandem, then the physics engine starts working against you... Because you effectively have multiple vehicles flying in extremely tight formation. Remember, physical objects can just as easily be shoved by outside forces. They can drift. They can get snagged. They can lag. They can be swatted aside by a powerful enough collision which could come form someone taking a potshot at you, or from bumping into another part of the multi-linkset mega object. And when that invariably does happen, you have to detect that and force the errant part back into formation. But since it's physical, it could just as easily disrupt the entire multi-linkset in the process. And then they have to try and get back into formation. You no longer have a set of vehicles flying in formation, you have a swarm - all pushing and shoving against each other to try and get back into place. I suppose you could selectively turn out-of-place parts phantom while they try to get back into formation, but that's not my main point... the point is that you have to constantly monitor and correct the relative positions of every linkset and that gets expensive real fast. Because you're not just using a lot of script resources, you're also impacting the physics engine (phantom objects with physics enable still must be processed by the physics engine). So it's a double whammy to the server. Even if you just had the "root" linkset physical, you'd still have the issue of it moving much smoother than the other linksets. They would also not be able to update as fast as the root, which could lead to internal collisions as the "root" bumps into the other parts. That could in turn cause the "root" to skew and slide against other parts and thus cause the whole collective to move in odd unpredictable ways as the other parts try to follow the leader. Or, more likely, there would be a massive desynchronization between where the "root" is and where the other linksets think the "root" is. Lastly, region crossings for physical vehicles is dicey enough (though it has been getting better to be honest) - I can only imagine the chaos of trying to keep multiple physical parts crossing at the same time in formation. For these reasons, I personally feel that trying to move multiple linksets as one is better fulfilled by sticking to non-physical movement. You avoid so many headaches and uncertainties and have a near guarantee of where the parts will be and how they will move. I believe it makes the whole endeavor much more manageable at the cost of whatever fluidity of moment physical status may have initially appeared to grant. Whew. Ok, regarding your other questions, the best place to start would be reading up on the LSL functions from the wiki. Try setting up small proof of concept tests. Start with just getting a "root" to move around under your control via non-physical movement. Once you have that down, move on to working on the follower script and a communication relay between the root and a child linkset. As you go, keep your scope limited to moving within a single region. Only after you've got it working well in that scope should you move on to look at taking region crossing into account. I did a little googling and actually managed to find the original MultiMove script I was thinking about created by Jesrad Seraph. You can see version 3 in the archives here. There are supposedly newer versions up to v5, but I had trouble actually finding them. These scripts are using the OLD methods and don't utilize the newer LSL functions. But if nothing else, they could give you a starting point on how to approach the equations for calculating offsets of child linksets. Please do not use them as is - only as a reference. They use a number of helper sciprts, but in today's LSL envrionment, you can definitely accomplish the same feat with a single script in each object. Edit: and if you'd rather not do the scripting, then you can try hiring someone in the Wanted or Inworld Employment forums.
  4. If by "physicalizing" you mean turning on physics status for each linkset, then yes, I would strongly advise against that. Trying to move multiple linksets as one unit is hard enough, but if you try to do that while they have physics enabled, it would be worse than herding cats on speed. When I referred to the old method as non-physical, that was only in regards to not using the phyiscs engine as most traditional single linkset vehicles do. The objects themselves are still solid and in the case of mesh, would still have a physics shape for you to walk around on. But they would not use the physics status. Scripted positioning would be how they move and how they maintain their relative positioning. While this does mean the parts would easily move through most objects, you could create a simplistic form of collision detection with llCastRay to check for approaching obstacles and have that affect the craft's ability to proceed.
  5. Personally, I'd not worry about upcalling to compensate for some of SL's oversized avatars. If you're looking to follow a real world scale, go ahead and do just that. In the end, it'll help keep things consistent as you build. And avatars can very easily change their shape to a smaller more realistic scale to explore your build.
  6. Reminds me of the old non-pyhsical "Multi-Move" systems. Adding to what Qie said, from what I recall, two things contributed to their caterpillar-like movements: the 0.2 second delay imposed by llSetPos and the ripple effect of communication relays from the "root" linkset if the overall thing was larger than the llShout distance. This is because it would be the "root" that would be sending out commands for the other parts to move themselves - and have some parts echo the commands to linksets outside the root's shout range. There have since been new LSL functions added for positioning objects that do not have a forced delay. llSetRegionPos is one option, and allows for an overflow of ten meters outside the current region. That should be enough to get the piece to cross the region threshold if it's using relative movements and continue on without much hassle. llSetLinkPrimitiveParamsFast is another option, which you can use to set the position and orientation all at once, through I'm not immediately sure how well it would perform for crossing regions boundaries. It's probably fine, but I can't say off the top of my head for sure. Regarding the actual communication, llRegionSay is very handy as it allows you to broadcast on a channel to everything in the current region. But as the name implies, it's got a hard limit of only being able to reach anything within the same region. This would pose problems for crossing region borders. For that, you might be stuck using a chat relay system still - as least as far as I'm aware. Edit: Also, even if you had everything communicating and operating in perfect synchronization, you still might get some hiccups due to the overall status of the region's health. Multi-Move solutions were notoriously resource heavy, with each linkset having multiple scripts - likely to try to get around the 0.2 second delay. Now that we don't need to resort to that, things might be a little better on that front.
  7. By all means, use it as an example and tweak/rewrite to suite your specific needs. It's one of the best ways to lean.
  8. How long do you want to hold on to the data? If it's for a short period, you could do as Wulfie suggests and keep the list in the script's memory, clearing it out periodically or as it gets too close capacity. The LSL wiki contains several example scripts for what you describe, known as "greeters". Some of them even employ compression to store lots and lots of avatar keys at once. Rolig's high capacity greeter is a great example. Another option would be to use the Key-Value-Pair database that comes with each Experience as a way to store data within Second Life. Though that requires some extra setup and it very likely overkill for the application of a humble greeter.
  9. Generally speaking, you would want to maintain a list of potential animations for each given state. This can be done several ways, like a list in the script's memory, or a notecard in the item's inventory which the script will read from (or both depending on how you intend the AO to be used/configured). Then you would need to decide how it will switch between the different animations. Will the user be able to select it via HUDs/Dialog boxes? Or will the script automatically cycle through the animations after a timer or some other criteria? Either way, the basic approach is to pick from your list and set it as the currently active animation via something like llSetAnimationOverride. When it comes time to cycle to a new animation for that state, simply call llSetAnimationOverride again with a new animation to update it in place.
  10. A function lacking some feature is not necessarily a bug. For example, llSetAnimationOverride does not include ability to override the typing state. I wouldn't call that a bug. The function is working as designed. That design can potentially be expanded or enhanced via feature requests, but not bug reports. By a similar token, it could simply be that llGetObjectDetails was not originally designed to work with inventory items. Filing a bug report against that would likely result in it being closed with a "working as designed" reason. A feature request to expand that design would have a better chance at augmenting the function.
  11. That's not a bug. The caveats section on the wiki page for llGetObjectDetails explicitly states it does not return data about inventory items. Edit: Not a bug, but perhaps a deficiency. It would definitely be useful for inventory operations to be able to get some info on inventory objects. Perhaps a suggestion to expand the function to cover inventory items or add a sister function like llGetInventoryObjectDetails which uses a relevant subset of flags. Since inventory items are wrappers, I wonder how much work it would take to add a new flag specifically for inventory items like INVENTORY_ADD_TIME... I might look into drafting up a feature request...
  12. First up, kudos to you for being conscientious about sharing the limited resources scripts have to play with! You can get a generalized reading on how much time the server spends processing a script via llGetObjectDetails and the OBJECT_SCRIPT_TIME constant. This assumes the object only has one script in it, otherwise it's an average for all scripts running in the thing you targeted. Speaking to your specific example, depending on the details, there are lots of ways you could approach this effect. For example, instead of using the timer for every single flicker, you could instead have a custom routine that simulates the flicker by turning the light off, sleeping for a small amount of time, then turning the light back on. You could repeat this sequence a few more times in the routine to have a short burst of flickering. Then, you would start a timer on a longer delay to call this routine whenever you wanted to initiate a burst of flickering. In fact, you could randomize the timer at the end of each flicker routine to make it look more natural instead of flickering at constant intervals. Of course, I'm just assuming your lamp would be on most of the time, and flickering every so often. If you intend to flicker you lamp constantly, another approach could be to use texture animation to simulate the visual effect in the client. This would be by far the least laggy from the server's perspective since texture animations are done one the viewer and you could skip and timer based updates altogether. The drawback here is that you'd need to make a custom texture cell animation to get the feel of a flicker when played. And if you are doing other things like enabling/disabling actual light sources, those would still need a timer - and would likely not say in sync with the client side animations. Just to give you some ideas.
  13. The wiki page for llDialog has a snippet of code you can use to trim the button string to be under 24 bytes: llBase64ToString(llGetSubString(llStringToBase64(theString), 0, 31)); So you could use that on your string before putting it into the targets list.
  14. That is correct. However, be careful to note that there are two similarly named functions: llRegionSay and llRegionSayTo, which do different things. llRegionSay will act like llSay, but for the whole region. llRegionSayTo will speak across the whole region as well, but is directed only to the target specified by uuid. No one else will hear it, even if they're listening on the same channel. I was advocating for the use of llRegionSayTo which will target a specific avatar or object. [wiki page] You listener looks ok, so as you said, the remaining problem is getting the channels set up right. Getting to objects to communicate on a generated private channel can get complicated fast. One approach is to have both objects run the same code to generate the same number based off of a public value (like the owner's key). However, the whole point in my suggestion to use llRegionSayTo was to avoid doing that altogether. By using llRegionSayTo, you can safely use the same command channel across all instances of this product. Because of the targeted nature of the communication, only the target will actually hear the message on the channel. Try this in your HUD (pick a static cmcChannel number for this test and use the same in your listener) : llRegionSayTo( llGetOwner(), cmdChannel, button ); As mentioned previously, if you direct a message to an avatar via llRegionSayTo and use a non-zero channel, then the viewer won't display it in chat - but all of the avatar's worn attachments will be able to hear the message. With this, you can indirectly target your mesh attachments by supplying the uuid of the current owner, That will act as a per-avatar filter. Edit: I just looked back at my previous post and noticed I typed out "cmdchannel" instead of "cmdChannel". That was a typo on my part and if you copied it from my post, could have been why you got your syntax error. The compiler would see that as some new undefined variable. Sorry!
  15. Assuming you're within the same scope as the button variable, I would think you should have no problem doing exactly that. The button variable is a string after all, so the following should work (and alleviate the need for that large if-then-else block entirely) : string button = llGetLinkName(llDetectedLinkNumber(0)); llSay(cmdchannel, button); If it's not compiling, what error are you seeing? Additionally, I would again suggest you consider using llRegionSayTo instead of llSay. This makes the HUD speak directly to the target you specify and no one else. You can potentially avoid all the hassle with generating unique channels and instead rely on llRegionSayTo to target the avatar - which would in turn have all its attachments hear the command as per the description on the wiki page. The corresponding listen handler in the attachments should have some filters to be safe, like only accepting messages form the name of the HUD object (as that would most likely remain constant). If you're still having problems with the relay, post a sample of the attachment's listener too.
  16. Instead of transmitting your HUD's message via llSay, consider using llRegionSayTo instead. In addition to specifying a channel and message, you would also supply a target UUID/key of the thing you want to send the message to. In your case it could be the avarar's key. This is useful because any text sent to an avatar in this manner (and on a non-zero channel) is heard by all its attachments. So you could use this to isolate any cross talk from other HUDs in the area - as other avatars (and their attachments) would not be targeted, even if you used the same channel. Edit: our other recommendations regarding script count still stands and I hope you consider them as well. Good luck.
  17. Ah, I didn't realize the size calculation on script rezz was such a performance hit. Thanks!
  18. Wulfie, I'm curious, why would this be preferable to a mono version? Assuming the helper script is small, wouldn't it (if nothing else) be preferable to use mono for the potentially smaller allocation size and potential bytecode sharing? Or have I forgotten something?
  19. I don't think Fritigern intended to be rude, but was instead trying to point out that using one script per button is a practice that's generally ill-advised. While it's always good to reduce your memory footprint, the sheer number of scripts (even idle ones) does have an impact on the server. The wiki mentions that each idle script in an object adds 0.001 to 0.003 milliseconds per frame of script time usage. Script time is a precious recourse that we must all share with each other. And it's also the first resource to dry up when the sim starts having other problems. So it's really important that we all try to reduce script counts where possible to help each other out. That's precisely why LL has been adding more and more of the linked function variants, so that we can do more with fewer scripts. In your specific scenario, you mention your buttons are just sending their names to the main HUD and then the HUD relays that name to the attachments. If all you're sending is the button name, you could simplify your code by doing something like this in the main HUD script: touch_start(integer total_number) { llSay(target_channel, llGetLinkName(llDetectedLinkNumber(0)); //says link name on target_channel } That would just send the name of whatever prim in the linkset was clicked. No need for an intermediary script to tell the HUD's main script what was clicked, as with this, it can find out on its own.
  20. There isn't very much to this script to begin with... It only contains two short events: a timer and a link_message event. That right away indicates this is a helper script that won't work on its own - it needs to work in conjunction with the main hoverboard script. Looking through that, you can see there is only one occurrence of the keywords "idle" and "get_on" that are spoken via llMessageLinked. These occur when the user sits on or stands up from the hoverboard. So this stuff is part of the vehicle's startup and shutdown procedures. All the link_message event does is start a timer when it hears "get_on". When it hears "idle", it resets the helper script, thereby killing the timer. The timer event has two nested IF-Else clauses. The first one checks whether the vehicle's physics is enabled or not. If physics is NOT enabled, it drops down into the inner IF-ELSE test. But if physics IS enabled, it just sets the value of the "stuck" integer variable to 0. The inner IF-ELSE test looks at the value of the stuck variable. Again, we only get here if the previous test passed, meaning the vehicle's physics is currently disabled. If the stuck variable is less than 1 (note the script initializes it to 0 so it always will be less than 1 at the start), then make the vehicle physical and increment the stuck variable by 1. On the other hand, if the stuck variable is not less than 1 (in other words, greater than or equal to 1), the move the vehicle up along the z axis by half a meter and then make the vehicle physical. If it turns out the vehicle was physical already, then none of the above happens, instead it just sets the value of the stuck variable to 0. As far as I can tell, I think the point of this helper script is to bump the vehicle upwards a little before enabling its physics. But the way this is all written is (in my opinion) very poor. I think this whole script is completely unnecessary. It's wasteful, because that timer will continue to run as long as the vehicle is in use and only stops when you get off. But after the initial bump and/or setting the physics, it does nothing of consequence. I really think you could just remove this helper script altogether.
  21. Unfortunately no such function exists. If you want to read the description of a child prim from another linkset, you're going to need to get creative. Mollymews's suggestion to use the root prim to temporarily hold a copy of the child prim's description data is one option - though if you are using multiple child prims worth of data you'll need to create a system to shuffle them around. Another options is to setup a communication relay between the attachment and the scanner. Basically, when your scanner object detects an avatar, it will direct a chat message to that avatar's attachment (since you already have the uuid) with something like llRegionSayTo. Meanwhile, the attachment's script will have a listener setup to listen for the scanner's message and when heard, it will grab the contents of the child prim's description (Mollymew's code could also be used here) and then llRegionSayTo that right back to the scanner object (which would also need a corresponding listen setup).
  22. If you are looking to hire someone to write the script for you, head over to the Inworld Employment forum. The LSL Scripting forum is more geared towards scripting discussions and providing assistance to those trying to write their own scripts. If you'd like to take another try at writing it yourself, we can give you some pointers - but we won't write the whole thing for you here. Your project can be made simpler by breaking it down into smaller parts and focusing on each one at a time. Then, as you get more familiar with it, you can combine the different parts into a single script to achieve your overall goal. The LSL wiki has lots of documentation you can read to help you along: The touch_start event is typically used to make scripted objects respond to being clicked on. The script can contain a variable (integer) that holds the total score value - which can be incremented/decremented depending on the result from the voting interaction. The llDialog() function is typically used to create a pop-up window with a message and clickable buttons. This can be used to send a voting prompt to target avatars. It must be used in conjunction with a listen event in order for the script to actually get the response. There are multiple ways you can alter the text used for the voting prompt. As before, the script would have a variable (string) that holds the text. You could use the llListen() function to setup a listener which will make the script react when it hears chat spoken (you can set up filters to make it only listen to the owner of the object). Or you could use the llGetNotecardLine() function to read text from notecards stored within the object's inventory. Though it's an indirect get, as this queues a dataserver event - in which the actual data will be retrieved. The script can also have another variable (list) which stores the keys/UUIDs of any avatar that has voted and check against that to see if they try to vote again before the cool down period elapses. Depending on how many people are likely to vote during a given period, you may need to implement a form of compression on the stored keys, otherwise your script may run out of memory and crash. This page lists some user created functions that can be used to compress/decompress keys. I've listed the major goals of your project in order of complexity: The first two are fairly straightforward. The next two start getting more complex quickly and depend on other concepts and functions - but the examples on their respective wiki pages should give you a good starting point. The last part may be the most tricky, as it involves more complex logic. But as you'll come to see, there are many, many ways to approach and solve a problem when it comes to programming. You mention you tried doing this yourself, but were unsuccessful. What did you try? How familiar with programming in general are you? If this is you first go at at it, it can seem daunting. But breaking things down into smaller pieces and definitely help with that. Start out small and build up from there.
  23. I could maybe understand if it was the animation's key that caused this... like if there was an old assumption that animation uuids would be within a defined range and anything outside that is considered a problem and thus triggers recovery code to purge all animations (just to be safe). But to have the trigger be the host object's key being lower than the avatar's key.. I can't imagine what tangled relation those two must have in the code.
  24. The only formatting code I'm aware of that works in the profiles would be the one to convert URLs to display text: [http://www.secondlife.com SecondLife] You can also use this with the Viewer URI Namespace to make all sorts of interesting links - some of which can open up other GUI panel for example. But be aware that they won't resolve when looking at web profiles. It only appears to work on the Legacy Profile floaters. Fortunately, I've heard that Linden Lab is going to be bringing those back. Other formatting code like bold, italic, underline, left/right/center alignment, etc are not supported as far as I'm aware. Though you can fake it in some instances by using unicode characters.
×
×
  • Create New...