Jump to content

Fenix Eldritch

Resident
  • Posts

    770
  • Joined

Everything posted by Fenix Eldritch

  1. That is all my script will ever do. The point of the example I posted was to illustrate how the dispenser could tell the HUD who triggered the dispenser. That way, the HUD could be given the avatar's key, which it could use to request permissions from and then ultimately temp attach itself to the avatar. You were halfway there with your original script, but you had the code to attach in the wrong object (your wall mounted switch as opposed to the actual HUD). So you would need to move that code into the HUD and using the demo above as an example, that will help you pass the appropriate target info to the HUD.
  2. The LSL wiki will be where you want to go to read up on functions' documentation. If you are brand new to LSL coding (or programming in general), there are numerous tutorials there that can help you get acclimated (And we can provide additional answers). Generally speaking, a generic script can be written that would go into the food item. Basically, when the item is clicked, it does several things: Send a message to the avatar that clicked it which has information that would tell the HUD what meter to fill. llRegionSayTo on a private channel won't be seen by the target avatar, but all attachments (like the HUD) can potentially hear it if they are listening on the same channel and have an appropriate filter. Change it's alpha values to go invisible Set a global variable that the food item can check to see if it's been clicked - so it can reject future clicks until the timeout elapses and it is made clickable again. Start a timer which once it expires, resets the item: making it visible again and priming it to be clickable once more. And of course the HUD itself will need to have an active listen running to hear messages from the food items. This is just one of many possible approaches. Like Wulfie says, providing us with more info helps us give better explanations and examples.
  3. If I understand your question correctly, then no: a script can only manipulate the inventory of the same prim it resides in. It cannot do anything to the inventories of other prims (linked or not). You would need to have a dedicated script in the other prim whose inventory you wish to give out. You could set up a communication protocol such that one scripted object can talk to another and ask it to give out its inventory, but again, that requires both objects be scripted. I did recently submit a suggestion for a new function that could query information about other linked prim's inventories. I could write up another for the others like llGiveLinkInventory, llRemoveLinkInventory, etc. if people would find it useful. Edit: Oh wait... are you asking if it's possible to give inventory to/from an object that is itself already in inventory? If so, then the answer to that is definitely no. Scripted objects cannot run when they are in an inventory and you simply cannot touch the inventories of inventory items - they need to be rezzed.
  4. Generally a script will need to be told, or somehow rediscover the appropriate link numbers when it's all combined into a single object. One way is to give certain links in your object unique names. Then your script would have to have a bit of code that systematically inspects the name of every link in the object and if it finds a matching name, save the associated link number to a global variable. You then use that global variable to target the desired link. Something to be wary of: if your lid is comprised of multiple parts, then you will need to write the open/close script to also apply the correct rotation and offset to each lid part - and each part will likely need to have its own specific rotation/offsets for the open and closed positions. See llSetLinkPrimitiveParamsFast and LINK_TARGET for examples on how to move multiple parts at once.
  5. The normal is basically the directional vector perpendicular to the surface. So you can use that along with something like llAxes2Rot to orient an object relative to the surface. I used this snippet in my ray tracer renderer. list pRay = llCastRay (startPos,endPos,[RC_DATA_FLAGS,RC_GET_NORMAL]); vector pHit = llList2Vector(pRay,1); vector pNormal = llList2Vector(pRay,2); // DEBUG: show visualization of surface normal (rezzes prim with its +z axis perpendicular to normal) llRezObject("marker", pHit, ZERO_VECTOR, llAxes2Rot(pNormal%<1,0,0>%pNormal, pNormal%<1,0,0>, pNormal), 0); In this case, since I wanted the top of the prim to be parallel with the surface normal, I used that as the "up" directional vector for llAxestoRot and used it with some cross product formulas to calculate the forward and left directions as well.
  6. I was thinking about how this could be done... The straightforward approach is to request linked variants of the existing llGetInventory* functions. Buuut... we could also consolidate them into a single new function - which has the added advantage of being extendible in the future. Function signature: list llGetLinkInventoryInfo(integer link, list parms); Input Params: INVENTORY_ACQUIRE_TIME, string item INVENTORY_CREATOR, string item INVENTORY_KEY, string item INVENTORY_NAME, integer type, integer number INVENTORY_NUMBER, intger type INVENTORY_PERM_MASK, string item, integer category INVENTORY_TYPE, string name INVENTORY_DESCRIPTION, string name (oh hey, a new suggestion ) I'll draft up a proper feature request when I am at my PC later this evening. Edit: BUG-234184
  7. Hmm... I think you could run llGetObjectDetails with OBJECT_TOTAL_INVENTORY_COUNT, targeting each link the hard way (llGetLinkKey) in a loop. That might* tell you if any of the links have something in their inventories. Unfortunately you don't have the granularity to specifically count different inventory types, nor can you get their names. But I suppose it's a way to somewhat narrow things down. *Not able to get inworld and verify, I'm unsure if that can actually be applied to individual links in this manner.
  8. Some more info/context would be helpful. What does the routine do to each prim in the linkset? Like Quistess says, there are few LSL functions left that don't have linked equivalents... Prim inventory queries and manipulation come to mind as actions that still require a dedicated script in the target prim. Also, can you elaborate more on the script getting deactivated when transferred to another prim? How are you currently doing it when you observe this, manually dropping it in? Edit: ah, rereading the wiki page for llGiveInventory, I see that scripts intentionally arrive disabled when given to other objects. Why can't the target prims be scripted despite being in the same linkset?
  9. This won't even compile. When you have a dot immediately after a variable, without a space, the compiler will interpret it as an acceessor operator. These are used to reference individual elements of specific variable types like the XYZ of a vector or the XYZS of a rotation. IMPULSE is a float, so that operator doesn't apply (nor does it make sense to try and access the "0 component". Remove the ".0" from both instances in your script. Secondly, IMPULSE is a positive number. Applying that to your avatar will result in an increase in speed. If you want to reduce speed, use a negative number. Lastly, llApplyImpulse implicitly targets the object the script is in, which has to be physical (or in the case of avatars, a worn attachment). If you want to apply the impulse to your avatar, you must be wearing the object as an attachment.
  10. You're opening new listeners, but never closing them when the other is active. It is possible to have multiple listener running at once - one does not override another. This looked interesting so I threw together a single-script demo for this. It only uses one listener, and differentiates between hearing messages from the owner (via llDialog) and hearing messages from other instances of the HUD (which itself will broadcast the chosen dance when Sync mode is on). The assumption being that everyone in the region will have a copy of the same HUD with the same name. I didn't have an alt to test with, so I just rezzed two instances of this object, wore one and then move out of chat range from the other. /*Demo. 1. Rez two prims, link them together 2. Name Root "HUD Demo" 3. Name Child link "Sync" 4. Drop this script into object root 5. Make a copy of the Hud Object and leave it rezzed 6. Wear the other copy of this object 7. Move at least 10 meters away from the rezzed copy */ integer SYNC = FALSE; integer dChannel = 123; //used for both personal and synced messages default { state_entry() { llListen(dChannel, "", "", ""); } touch_start(integer total_number) { string buttonName = llGetLinkName(llDetectedLinkNumber(0)); if(buttonName=="Sync") { SYNC = !SYNC; //toggle HUD sync mode llOwnerSay("Sync toggled to: "+llList2String(["FALSE","TRUE"],SYNC)); return; } llDialog( llGetOwner(), "Select a dance", ["1","2","3","4","5","6","7","8","9"], dChannel ); } listen(integer channel, string name, key id, string message) { if(id ==llGetOwner()) //messages from the diloag will have owner's ID { llOwnerSay("heard llDialog from owner's own hud, playing anim: "+message); if(SYNC) { llOwnerSay("Sync is on, boradcasting chosen dance to region..."); llRegionSay(dChannel,message); } } else if(SYNC && name == llGetObjectName()) //messages from other HUDs will not have owner's ID, but will have HUD's name { llOwnerSay("heard llDialog from another Synced HUD, playing anim: "+message); } } }
  11. A few things to point out: Don't waste your time with OpenAI, ChatGPT, or other such things. They have been proven to be unreliable and will make up syntax and functions that do not actually exist. I would recommend you read through the LSL wiki introductory tutorials to get a better foundation on LSL and programming in general. It will be immensely helpful to you (we will happily answer any related questions you have along the way). Echoing what Rolig and Frionil have said, it's generally encouraged that people not put scripts in each of their prim buttons - especially if said scripts are performing essentially the same action. Rather, you can (and should) handle this functionality for all buttons with a single script in the HUD root. Frionil's sample script shows the basics on how to do that, by collecting the detected link and face numbers in the touch_start event. Your current approach of getting the button's texture UUID will potentially fail once the object is transferred to a new owner. This is because llGetTexture (and it's llGetLinkPrimitiveParams equivalent) only work if the object is full-perm for the current owner, otherwise they return NULL_KEY. I'm assuming that this project will be given/sold to others... if that's the case, then llGetTexture is not a viable option for learning the button's texture UUID. There are many different ways to do this, but one could be writing your HUD script to have the list of UUIDs defined within it internally and each button would reference a specific list entry. You could name each button as a number, which in turn would be used as the list index. Here is a little demo of this: /* Demo: 1. Link 3 prims together 2. Name them "0", "1", and "2" 3. Drop this scipt into the root */ list textures = [ //list of uuids, one for each button "example-uuid-1", "example-uuid-2", "example-uuid-3" ]; default { touch_start(integer n) { integer link = llDetectedLinkNumber(0); //get the touched link number string buttonName = llGetLinkName(link); //get the name of the touched link llOwnerSay("Clicked button: "+buttonName + ", using name as index to list: "+llList2String(textures, (integer)buttonName)); } }
  12. This relates to my earlier post when I pointed out that you need to make sure both scripts use the same number. This is because I noticed you were sending comChannel as one of the parameters in llMessageLinked. Since llMessageLinked doesn't use channels like llListen, I assumed you were using it as some kind of verification to the other scripts - and in posting you second script, it looks like I guessed correctly. Here's what's going on: Originally, both scripts independently used the same formula to calculate the same unique number: ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; Your first script puts this value into the comChannel variable and your second script puts it in the cha variable. When your first script issues the linked message, it sends comChannel as the second input parameter. Over in your second script, that materializes as the value of the num variable in the link_message event. So when your second script hears the link message, the first thing it does is use that same big formula to calculate the unique number. It then checks if that number (cha) is equal to the number passed to it from the link message (num). If they're not equal, then the script executes the return function and ends the event, effectively rejecting the link message. Previously this worked fine when both scripts used the same method (formula) to generate the unique number (both scripts have the same owner so the result will be identical). But once you hard-coded one script to use a specific value (-14523), the other needs to do the same otherwise you'll never get a match. In short, with the way you've written these scripts, comChannel in the first script and cha in the second script need to be assigned the same value. Doesn't matter if it's by using the same formula, or the same number, they just have to match.
  13. Thinking more about this... I'm not able to get inworld to verify right now, but I believe any push/impulse applied to an avatar does not transfer over to the physical object they're sat on... right? And since your vehicles are no-mod, cheaty movement enhancers can't be installed in to them. So that just leaves llPushObject as the only other function that can apply an impulse to a remote object and the likely candidate for a HUD. But from the caveats, this function is pretty hobbled on land where no-push is set: unless they're the land owner, objects can only push their owners' avatar and little else. So I'm left wondering what options are left that might allow an outside HUD/object to apply some kind of speed boost to a no-mod physical vehicle?
  14. It's also possible for a vehicle owner to get a boost of speed without any scripted assistance by grabbing and dragging the physical object/vehicle across the screen. This can be easily countered by setting the STATUS_BLOCK_GRAB_OBJECT to true.
  15. Correct. Both llTextBox and llListen take a UUID as one of their parameters and that it how those functions select their target to send the textbox to or listen to respectively. For those functions you could simply replace llGetOwner with llDetectedKey(0) which represents the UUID if the person who just triggered the touch event. The detected functions only work in a select few events like touch_start, but they are exactly for this kind of purpose. Note that in this case, the commChannel can continue to use the integer generated from the owner's key, as it's just used for internal communications with the link message. Heck, you could probably remove the line that updates it in the touch_start event and just give it a random number when you declare it. Just make sure you use the same number in the other scripts. You should however close your listen handler in the listen event so that you don't amass an ever increasing collection of listens as more and more people click the object. See llListenRemove.
  16. The irony is that the prototype for Second life, (then called Linden world) actually did support this kind of water.
  17. See llOwnerSay and the detected functions... either llDetectedName or the combo of llDetectedKey and llKey2Name or a URI as Quistess suggested.
  18. That's not how it works here. This forum is for people asking questions/advice and sharing ideas/techniques regarding scripts. If you want to try scripting this yourself, we can offer guidance, suggestions, examples, and even a little debugging if you're stumped. But if you want to commission someone to write the script for you, you should instead be asking in the Inwolrd Employment forum. You can request this thread be moved to the appropriate forum by reporting it and saying as much in the description.
  19. Echoing what Quistess said: you can't do this all in one script. You have two objects performing two different tasks, and each need to be scripted differently. Firstly, you have your wall-mounted switch (which I'll refer to as the dispenser). This object's job is to remain stationary and give out copies of the HUD object stored within its own inventory. This dispenser has no business attaching itself to users, so it doesn't need to request any permissions or anything associated with that. All this dispenser is supposed to do is rez the HUD and relay who triggered it to that HUD. Secondly you have your HUD object. This is the object that will be rezzed from the dispenser and then told who it should be attached to. Once the HUD is rezzed and has been told its target, its job is then to request permissions and temp-attach to the target. And then do whatever else the HUD is intended to do once attached to the target user. Here is a very small example of how to communicate between these two objects. Create a prim and drop the following script into it. This will be the dispenser. //Dispenser script example. key target; //targt avatar string objectName = "HUD"; //object to dispense integer chan = -5; //communication channel default { state_entry() { llSetObjectName("Dispenser"); //rename this object "Dispenser" } touch_start(integer total_number) { target = llDetectedKey(0); //get key of avatar who clicked on me llRezObject(objectName, llGetPos()+<0,0,1>, ZERO_VECTOR, ZERO_ROTATION, TRUE); } object_rez(key id) { llRegionSayTo(id, chan, (string)target); //send key of target avatar to HUD when it rezzes } } Create a second prim and drop the following script into it. This will be the HUD. Then take that hud into your inventory and drop it into the inventory of the dispenser. //HUD script example. integer chan = -5; //communication channel default { state_entry() { llSetObjectName("HUD"); //rename this object "HUD" llListen(chan, "Dispenser", "", ""); //preemptively setup listen } listen(integer channel, string name, key id, string message) { llOwnerSay("got message from "+llKey2Name(id)+", target user will be: "+llKey2Name(message)); //then do the request permission to temp-attach and whatnot... } on_rez(integer start_param) { //if rezzed manually by owner, start_param is 0 (FALSE), if rezzed by Dispenser, we programmed it to pass a start_param of 1 (TRUE) //use that to configure the HUD to be a temporary object that will delete if the target ignores the permission request llSetLinkPrimitiveParamsFast(LINK_SET, [PRIM_TEMP_ON_REZ, start_param]); } } Note how both scripts use the same communication channel, in this case -5. And that the HUD is explicitly listening only to objects named "Dispenser". That's why I added the commands to set each object's name right at the start. You can also do that manually, but be sure the names match what the script(s) expect. With the way this is setup, the HUD's listen filter is already active and running before it's even placed in the dispenser. This means it should be able to hear any messages sent to it the moment it's rezzed. It's strongly recommended you visit the wiki and read up on the documentation for these functions and perhaps look over some of the introductory LSL tutorials too.
  20. That is how llAttachToAvatarTemp works. When the script calls this function (and has sufficient permissions), the object that contains this script will temp-attach itself to the target. That's why your wall mounted switch disappears, it's attaching itself to the target instead of having the HUD attach. So what you need to do is setup a communication protocol between the dispenser object and the HUD object so that the dispenser can inform the HUD object who the HUD should request permissions from and temp-attach to. In short, you want the HUD object to call llAttachToAvatarTemp, not the dispensing object. The basic idea idea and sequence could be: User touches the dispenser Dispenser records the key of the user Dispenser rezzes HUD object HUD object starts listening from dispenser (would be prudent to set this listen filter up ahead of time so it's already active on rez) Dispenser communicates the key of the user to the HUD object (llRegionSayTo is a good option to talk directly to the HUD) HUD object hears the message and uses that to target the user to request permission and then temp-attach.
  21. Your script is calling llSetTextureAnim with "ALL_SIDES", which, as the name implies, will make the animation play on all sides of the target prim. If you want just the "walls" of a prim cylinder, then you would need to use the correct side index: in this case 1. Judging from the picture, I suspect you didn't correctly rename the texture asset to follow the format expected by the script. Failing do to so will cause the script to still update the texture, but not apply the animation. So my guess for the reason why you didn't see anything on the cylinder's side is because the current texture repeats/offsets for that face just happened to result in showing the gap between frames. Now... it's not really possible to have multiple repeats of a textureAnim across the same face. Like Quistess says, you would likely need to create a special animation texture for that. For something like this, I would suggest you build the texture such that you have one frame per horizontal row. That will work best since you only get one repeat's worth of texture to wrap around the cylinder's side. Alternatively, you could construct a custom mesh cylinder with geometry and UV mapping that passively produces the repeats, but uses the same material slot (i.e "face" as LSL would see it for the purposes of llSetTextureAnim).
  22. Updating a script (saving and recompiling) will always result in wiping all of that script's memory. Calling llResetScript will similarly wipe all of that script's memory. There is no way around that, it is simply not possible for a script to "retain" things in memory following a reset/recompile. What happens afterward depends on how the script is written. The code within the state_entry event will always execute when a script is reset/recompiled. So it may be that your script is simply re-populating variables there. And even if your script isn't populating variables in the state_entry, it may be that it's sending out signals to other scripts and getting responses back which it in turn uses to populate variables. Again, it really depends on how your script is written. We would need to see actual examples to further assess. Not in relation to scripts. Prims have a collection of "attributes" that do persist through the removal/reset of scripts (again, assuming a script doesn't' alter those in the state_entry upon reset). Such things like scale, particles, applied texture, color, etc.. Recently, LL added a new feature called "LinksetData" in which a root prim now has access to a small personal Key Value Pair datastore. This is independent from scripts, but I suspect that's not what you're referring to in this case.
  23. This can be solved with some clever prim manipulation - no need to set planar mapping or use complicate script calculations. Make a square prim with 1:1 texture ratio. Then modify the prim's slice begin and slice end parameters to shave of the top and bottom until you recreate the desired shape. Modifying the prim's shape in this way is different for normal scaling in that it does not alter the aspect ratio of the prim face. So a regular texture rotation wil not distort the texture because it's still technically 1:1
  24. Seems I missed the last portion of your previous post. That code probably isn't working because "StartFireParticles ()", is not the correct way to call a function - the space between the function and the () is the issue. But also, unless StartFireParticles() returns a list, that probably isn't going to do what you want either. You cannot call user defined functions that exist in other scripts - a script only knows about what is within itself. You could have it be triggered via chat commands, either from yourself, or another script - but then you'd need to alter the particle script to support listening for said chat commands.
×
×
  • Create New...