Jump to content

Fenix Eldritch

Resident
  • Content Count

    313
  • Joined

  • Last visited

Everything posted by Fenix Eldritch

  1. As far as I'm aware, there is only one function that can remove inventory items: llRemoveInventory() - but its scope is confined to the prim in which the host script resides. This means the function can't target other prims in the linkset. That is a considerable limitation, but if you reeaaallly want to force it, there may be a workaround. It's not pretty though. Hypothetically speaking, I suppose you could accomplish this by writing your script in such a way that it would initiate a "delete everything plus myself last" loop when it receives a specific message command. Then use llRemoteLoadScriptPin to inject copy of that script into each linkset of the object. Then send the aforementioned signal (like llMessageLinked or something similar). When all scripts hear the signal, they begin the deletion loop and should in theory, clean themselves up last. But that's a lot of effort compared to the viewer's menu command. Is there a particular reason why you're aiming for a scripted solution? Edit: Whoops, I completely misread how llRemoteLoadScriptPin works. See Wulfie's post below.
  2. llDetectedKey (and related functions) only work within a small subset of events - as per the wiki page specifications: So trying to use it in the run_time_permissions event won't work. If you want to reference the user's key that you detected in the touch_start event, you must store it in a global variable.
  3. The problem is in your run_time_permissions event. You are trying to start the nextDance animation, but that variable has not yet been populated. run_time_permissions(integer perm) { if (perm & PERMISSION_TRIGGER_ANIMATION) { if (lastDance != "") llStopAnimation(lastDance); llStartAnimation(nextDance); lastDance = nextDance; } } When you reset your script, your code immediately requests animation permission, which queues up the above event and the first IF statement passes. At this point in time, no variables have been updated, so lastDance and nextDance are still empty. So the second IF test fails. However, that only prevents "llStopAnimation(lastDance)" from being executed. The other two lines after that are not part of the IF statement, so they will still run and that's why your script complains - it's trying to start an animation called "" but that doesn't exist. Did you mean to group those two lines within the second IF statement?
  4. This is kinda a kludge, but if you have Copy/Trans permissions on the animation asset, could you send a copy to the NPC via llGiveInventory (along with a chat of the asset's name) ? When the NPC receives the inventory item and name, it can then operate on its own local copy and discard when finished.
  5. I thought face numbers were defined by the order of the material slots on the source model? I haven't come across a situation where that order is not the same in the resulting uploaded mesh. And I have several character displaying 8-face meshes where the order would be readily apparent if they weren't what I expected... Have I just been lucky? Or is this specifically relating to uploading meshes with more that 8 material slots and letting the uploaded cut them up in 8-face parts however it pleases?
  6. Most frequently on my home parcel/workshop. I like to have some of my in-progress projects setup for visitors to mess around with.
  7. Does this imply that you do not have edit permissions on the copy you bought? If you can't edit the script, there there is no way to alter its behavior. On the other hand, if you can edit the script, but aren't allowed to publicly post it, then see below. A single script can only rez objects from its inventory one at a time. But you can call the function multiple times in succession to rez as many instances as you need (land impact allowing). Rezzing an object via the LSL functions llRezAtRoot or llRezObject causes the script to sleep for 0.1 seconds, so there will be a very slight delay between rezzing. Regarding the other point, there are two ways you can delete an object via script, either calling llDie, or setting the prim property PRIM_TEMP_ON_REZ to true. Temporary prims will delete themselves after about a minute. This property can also be set via the build tool by clicking the checkbox marked as such. If the objects being rezzed by your script keep self deleting, then it's possible they already have this temporary property set. In which case, you must edit that object and replace it in the rezzer's inventory with a non-temp version. And generally speaking, be careful not to cause prim litter by rezzing many objects that don't auto-delete. If you're doing this on land that is not your own, you could be abuse reported for griefing. Make sure you understand what you're aiming to do.
  8. I suppose it would queue up another dataserver event which would then execute after the current one finishes (assuming the key was valid).
  9. Not through LSL. However, your viewer/client has the ability to customize text color for various different chat sources. Should be in one of the Preferences tabs. Note that the color change would only be seen by you, since it's a local viewer setting.
  10. Yep - because your HUD script, as currently written, only sends one message (the vanish signal) to the receiver. If you want to toggle it off/on, you need to add additional logic to the HUD script so that each time you click, it will alternate between sending the vanish signal, and a reappear signal. And in that regard, I would second Rolig's suggestion to consider using llSetLinkAlpha in the receiver instead of setting the texture to a full alpha image. By toggling the alpha parameter, you can make the target object/face invisible or visible without needing to keep track of the original texture.
  11. It was an attempt to think of a possible workaround in the event that you didn't have edit access to the menu script. llDialog works by sending out the button text from the user and the script listens for that to act on. If that listen filter was broad enough, there is a slim chance that you could inject your own message from another script. But that depends on the menu script having a less restrictive (read: less secure) filter setup. Anyway it is moot since you do have edit access to the menu script after all. You will be making much more work for yourself in trying to slam two different scripts together. Since you already have edit access to the main menu script, I would advise you work towards adding your code to the menu script instead of using a secondary script. But before you can do that, you NEED to have an understanding on how the menu script is working in the first place. Study its touch_end event to see how it reacts to a user click. Step through each line of the code to follow where it goes. Understand how the menu script keeps track of the light's state and how it modifies it. When you understand all that, I believe it should become clearer how you can incorporate you additional code to the script. I'm guessing Sunbleached wants to have two different outcomes depending on what part of the vehicle is clicked. I suspect the current menu works when any part of the vehicle is clicked on - and they want to suppress that menu only when the specific prim/face to toggle the light is clicked. A simple branch (or short circuit return out of the touch_end event) would likely do the job. Providing they understand what the script is doing in the first place and map out what they want to do as you rightfully suggested.
  12. I was operating under the assumption that you had access to the menu script and were trying to augment it with the manual light switch code. If you do have access to the script, study how the menu controls the light status (it will most likely be a global variable) and use the same hooks in your manual trigger code - and of course, add the code to the menu script. If on the other hand you do not have access to the menu script and are adding this functionality with a completely separate script, that changes things considerably. There will be an obvious disconnect between the two systems. Without knowing how the menu works, it may not be possible to make them coexist nicely. It might be possible, but you need to provide more information on how the existing script works. For example, is the menu using llDialog?
  13. Yes it will still work. Clicking on a scripted object is divided into three stages: the touch_start event triggers once, right as the user initially presses the mouse button the touch event triggers continually as long as the user is holding down the mouse button (in other words it will loop) the touch_end event triggers once, right after the user lets go of the mouse button All this means is that your existing menu code apparently triggers at the end of a click, and your new code as currently written will trigger right at the start of a click. There's nothing necessarily "wrong" with that, though from a user experience, it may or may not feel intuitive - but that's subjective. You could just as easily put the new code in the touch_end event along with the other stuff. Or not - It's entirely up to you. In order to work with llDetectedLinkNumber, you need to know what the desired number is, similar to what you have done with the face index when using llDetectedTouchFace. The way I usually do is is to give the target child-prim a unique name and then run a loop to scan each item in the linkset for that name. Once found, store the index in a global variable and test against that where needed. The drawback to this is that you must re-run that loop if a new prim is linked or unlinked from the set - because it's then possible the target link index might change. However, Rolig's example above bypasses that completely. Instead of saving the link number in a global variable, she just checks if the child-prim that was just clicked has a name equal to whatever unique one you setup earlier. If so, continue on with the other stuff. If not, do nothing since it wasn't the desired child-prim. I never considered doing it that way before, so thanks for that, Rolig!
  14. Oh yes, there are many examples of these kinds of vehicles throughout SL. There's even a wiki page on it. A few that come to mind are Yavapods Transit system in Bay City (boats in the canals, a trolley along the main road, and a few buses/taxis) Trams in the Paleo Quest Various mainland railroad groups Most of them have the same thing in common: a list of waypoints that they would navigate to through some means. In recent history, the concept of LSL Key Frammed movement has been implemented and is of particular use for these kinds of vehicles as it is a less laggy solution. Really well suited for following set paths that don't change much.
  15. On its own, a change like this would likely be trivial as far as resources are concerned. I imagine a single if-statement in your touch_start event would suffice. You'd check if llDetectedLinkNumber and llDetectedTouchFace return the desired link and face index respectively and if so, toggle the light as demonstrated by Rolig's example.
  16. Sounds like you'd want to look at the blending parameters. The wiki page has a section on it. And I believe the Particle Laboratory inworld might also have some demos or visual explanations you could study.
  17. After you save/compile the script in the object, make sure that the "Running" checkbox is in fact checked. I have seen instances where it was turned off without my realizing it. Also, how far away from the object is your camera? Because sometimes sounds in SL tend to have a steep falloff as your viewport gets further away from the source. As a test, zoom your camera right up to the object and listen if you can hear the sound. Combine that with the other diagnostic instrumentation suggested by the others.
  18. Accidental duplicate thread. See this thread which has several replies (including one from the original poster)
  19. I don't think you'd need to split this into two scripts, you could use a function to work on the parsing and call it as needed. A great example of this can be seen in Rolig's dialog code in the script library: Once your scanner has populated the list of names, call Rolig's function to build the dialog.
  20. The timescale parameters govern how long it takes in seconds for whatever associated attribute to take hold. So yes, smaller values generally make them more responsive. I find this quote from the Linden Vehicle tutorial helpful: As for the difference between the friction and motor decay parameters... Friction timescale is how long it takes friction to bring the vehicle to a stop - whether that's movement along the XYZ axes (linear) or rotating about its reference frame (angular). So a small value for your angular friction timescale would mean its rotations would quickly succumb to friction and therefore stop turning. See this section. Motor decay on the other hand is how long it takes the effectiveness of the motor to degrade to zero without any other intervention. Both of these parameters can be used together in different ways to achieve similar behaviors. Again, the Linden tutorial gives some examples:
  21. Shoot, you're absolutely right. I got carried away in my extrapolations. I now recall other instances that clearly disprove my claim: a valid key by itself in a conditional will also evaluate as true so an implicit "==true"wouldn't make sense in that case. Thanks for the correction! Edited to add: The wiki page for IF statement has a neat table that I hadn't noticed before. It shows under what conditions the different variable types will evaluate as true. (I should have checked there in the first place ) Type Condition integer True if it is not zero. float True if it is not zero.[1] string True if its length is not zero. key True only if it is a valid key and not NULL_KEY. vector True if the vector is not ZERO_VECTOR. rotation True if the rotation is not ZERO_ROTATION. list True if the length is not zero.
  22. 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.
  23. 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.
  24. 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.
×
×
  • Create New...