Tattooshop Posted March 28, 2020 Share Posted March 28, 2020 (edited) Hey. how in theory to simulate a grenade explosion, pushing avatars away in a certain range? I mean pushing itself. Edited March 28, 2020 by Tattooshop Link to comment Share on other sites More sharing options...
Rolig Loon Posted March 28, 2020 Share Posted March 28, 2020 In theory? llPushObject(kAv,6000.0*llGetObjectMass(kAv)*(vAvPos - llGetPos()),ZERO_VECTOR,FALSE); and trigger that in a sensor event when kAv is detected within your target range. But that will only work if the region allows pushing or if the object is pushing the owner. If you are working in an Experience, you could of course auto-attach a temporary object an then move it (and the avatar) rapidly away from the grenade, with all the appropriate noise and particle FX. 1 Link to comment Share on other sites More sharing options...
Mollymews Posted March 29, 2020 Share Posted March 29, 2020 another way is when the grenade explodes have it rez a transparent physical object, using the rotation and velocity parameters of llRezObject to throw the rezzed object at the target avatar. Being physical, the avatar will get bumped/moved when the object collides with them http://wiki.secondlife.com/wiki/LlRezObject 2 1 Link to comment Share on other sites More sharing options...
Rolig Loon Posted March 29, 2020 Share Posted March 29, 2020 7 minutes ago, Mollymews said: when the grenade explodes have it rez a temp_on_rez transparent physical object otherwise it may end up three regions away and you may be yelled at for littering. 🙄 2 1 Link to comment Share on other sites More sharing options...
Mollymews Posted March 29, 2020 Share Posted March 29, 2020 yes Rolig, i forgot about that bit 1 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 29, 2020 Author Share Posted March 29, 2020 20 hours ago, Rolig Loon said: In theory? llPushObject(kAv,6000.0*llGetObjectMass(kAv)*(vAvPos - llGetPos()),ZERO_VECTOR,FALSE); and trigger that in a sensor event when kAv is detected within your target range. But that will only work if the region allows pushing or if the object is pushing the owner. If you are working in an Experience, you could of course auto-attach a temporary object an then move it (and the avatar) rapidly away from the grenade, with all the appropriate noise and particle FX. 18 hours ago, Mollymews said: another way is when the grenade explodes have it rez a transparent physical object, using the rotation and velocity parameters of llRezObject to throw the rezzed object at the target avatar. Being physical, the avatar will get bumped/moved when the object collides with them http://wiki.secondlife.com/wiki/LlRezObject Hello! Thank you both very much! :) So now I am trying llPushObject and thats what I got but it says "Type mismatch"... And what is vAvPos here? :D integer vAvPos; default { state_entry() { llSensor("", NULL_KEY, AGENT, 3.0, PI); } sensor(integer detected) { llPushObject(llDetectedKey(0), 6000.0*llGetObjectMass(llDetectedKey(0))*(vAvPos - llGetPos()), ZERO_VECTOR, FALSE); } } Thank you again very much! 💖 Link to comment Share on other sites More sharing options...
Rolig Loon Posted March 29, 2020 Share Posted March 29, 2020 Oh, well, you do have to define AvPos = llDetectedPos(0); Most of that second argument in llPushObject is my way of creating a plausible fudge factor for the magnitude of the push. llGetObjectMass() gives me a way to scale the push to the mass of the person that the object is supposed to push. And the factor of 6000 is simply an empirical scale factor that seems to work for me. It pushes most people a pleasing distance. YMMV. And then, of course (AvPos - llGetPos()) is the vector along which the push is to be applied. 1 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 29, 2020 Author Share Posted March 29, 2020 4 hours ago, Rolig Loon said: Oh, well, you do have to define AvPos = llDetectedPos(0); Most of that second argument in llPushObject is my way of creating a plausible fudge factor for the magnitude of the push. llGetObjectMass() gives me a way to scale the push to the mass of the person that the object is supposed to push. And the factor of 6000 is simply an empirical scale factor that seems to work for me. It pushes most people a pleasing distance. YMMV. And then, of course (AvPos - llGetPos()) is the vector along which the push is to be applied. Awesomeness!! works great! but for some reason it repels only one avatar (the one who is closer). But how to make it to repel everyone in the range? default { state_entry() { llSensor("", NULL_KEY, AGENT, 5.0, PI); } sensor(integer detected) { llPushObject(llDetectedKey(0), 6000.0*llGetObjectMass(llDetectedKey(0))*(llDetectedPos(0) - llGetPos()), ZERO_VECTOR, FALSE); } } Link to comment Share on other sites More sharing options...
Rolig Loon Posted March 29, 2020 Share Posted March 29, 2020 (edited) 5 minutes ago, Tattooshop said: But how to make it to repel everyone in the range? You have to pay attention to more than just llDetectedKey(0). A sensor can detect up to 16 avatars within range. So just loop through all detected avatars from 0 to the maximum detected and shove them all. http://wiki.secondlife.com/wiki/LlSensor#Examples Edited March 29, 2020 by Rolig Loon 1 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 13 hours ago, Rolig Loon said: You have to pay attention to more than just llDetectedKey(0). A sensor can detect up to 16 avatars within range. So just loop through all detected avatars from 0 to the maximum detected and shove them all. http://wiki.secondlife.com/wiki/LlSensor#Examples Thanks a lot! I learned a new trick! Now it repels even physical objects of small mass! But as before, it is not possible to make this work for several objects and avatars. What is my mistake? default { touch_start(integer total_number) { llSensor("", NULL_KEY, (AGENT | PASSIVE), 5.0, PI); } sensor(integer detected) { while (detected--) { llPushObject(llDetectedKey(0), 6000.0 * llGetObjectMass(llDetectedKey(0)) * (llDetectedPos(0) - llGetPos()), ZERO_VECTOR, FALSE); } } } Link to comment Share on other sites More sharing options...
KT Kingsley Posted March 30, 2020 Share Posted March 30, 2020 You should be using the variable detected in each of the llDetected*** functions, rather than just 0. This tells the llDetected*** function which of the detected objects you're interested in. 2 1 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 2 hours ago, KT Kingsley said: You should be using the variable detected in each of the llDetected*** functions, rather than just 0. This tells the llDetected*** function which of the detected objects you're interested in. Thanks a lot! in combination with this grenade thrower script and explosion particles system and sounds, a good grenade was obtained! default { state_entry() { llSetTimerEvent(3); } sensor(integer detected) { while (detected--) { llPushObject(llDetectedKey(detected), 6000.0 * llGetObjectMass(llDetectedKey(detected)) * (llDetectedPos(detected) - llGetPos()), ZERO_VECTOR, FALSE); llSleep(1); llDie(); } } timer() { llSensor("", NULL_KEY, (AGENT | PASSIVE), 5.0, PI); } } Link to comment Share on other sites More sharing options...
KT Kingsley Posted March 30, 2020 Share Posted March 30, 2020 I see a problem with that script: the llDie() statement is inside the loop. The loop will execute once for the highest number detected object and then die before it can push any of the other detected objects. Also, the llSleep function will be executed for every iteration of the loop. I think what you want is: sensor(integer detected) { while (detected--) { llPushObject(llDetectedKey(detected), 6000.0 * llGetObjectMass(llDetectedKey(detected)) * (llDetectedPos(detected) - llGetPos()), ZERO_VECTOR, FALSE); } llSleep(1); llDie(); } 1 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 This way is much better! Thank you! 👍 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 18 hours ago, Rolig Loon said: You have to pay attention to more than just llDetectedKey(0). A sensor can detect up to 16 avatars within range. So just loop through all detected avatars from 0 to the maximum detected and shove them all. http://wiki.secondlife.com/wiki/LlSensor#Examples 2 hours ago, KT Kingsley said: I see a problem with that script: the llDie() statement is inside the loop. The loop will execute once for the highest number detected object and then die before it can push any of the other detected objects. Also, the llSleep function will be executed for every iteration of the loop. I think what you want is: sensor(integer detected) { while (detected--) { llPushObject(llDetectedKey(detected), 6000.0 * llGetObjectMass(llDetectedKey(detected)) * (llDetectedPos(detected) - llGetPos()), ZERO_VECTOR, FALSE); } llSleep(1); llDie(); } There is a ridiculous problem. I can’t get the grenade script to work from the time of the throw. -- I rez a grenade. -- I put the script there. and the script starts working, the timer starts and I have to very quickly grab the grenade and pick it up in my inventory until it explodes and put it in the Thrower object. But the timer counts down from the moment when I scripted it. And the grenade explodes "ahead of time". How to make the script or timer reset and the countdown start from the moment of the throw? Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 string EXPLODE3 = "fd5e5c93-691c-eadb-ee27-8972af741823"; iParticles() { llParticleSystem([PSYS_PART_MAX_AGE,1.50, PSYS_PART_FLAGS, 291, PSYS_PART_START_COLOR, <0, 0, 0>, PSYS_PART_END_COLOR, <1, 1, 1>, PSYS_PART_START_SCALE,<1.01000, 1.01000, 0.00000>, PSYS_PART_END_SCALE,<1.91139, 2.00179, 0.00000>, PSYS_SRC_PATTERN, 2, PSYS_SRC_BURST_RATE,0.00, PSYS_SRC_BURST_PART_COUNT,4, PSYS_SRC_BURST_RADIUS,0.30, PSYS_SRC_BURST_SPEED_MIN,0.10, PSYS_SRC_BURST_SPEED_MAX,2.06, PSYS_SRC_ANGLE_BEGIN, 3.14, PSYS_SRC_ANGLE_END, 0.00, PSYS_SRC_MAX_AGE, 0.0, PSYS_SRC_TEXTURE, "74e8631c-33a9-bc1a-03d3-ede886272a21", PSYS_PART_START_ALPHA, 0.79, PSYS_PART_END_ALPHA, 0.00, PSYS_PART_START_GLOW, 0.06, PSYS_PART_END_GLOW, 0.00]); } default { state_entry() { llParticleSystem([]); llSetTimerEvent(3); } on_rez(integer num) { llResetScript(); } sensor(integer detected) { while (detected--) { llPushObject(llDetectedKey(detected), 6000.0 * llGetObjectMass(llDetectedKey(detected)) * (llDetectedPos(detected) - llGetPos()), ZERO_VECTOR, FALSE); } llSleep(1); llTriggerSound(EXPLODE3, 1.0); llTriggerSound(EXPLODE3, 1.0); llTriggerSound(EXPLODE3, 1.0); llDie(); } timer() { iParticles(); llSensor("", NULL_KEY, (AGENT | PASSIVE), 5.0, PI); } } Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 I managed to do everything quite quickly, so the problem was solved. but if there is any way to do this through a script, please share it! Thank you all again! Link to comment Share on other sites More sharing options...
KT Kingsley Posted March 30, 2020 Share Posted March 30, 2020 (edited) How does the thrower object work? Does it rez the grenade with a velocity, using llRezObject or llRezAtRoot? Or is it something like a physical catapult? One thing you could try is to have the timer start when the grenade is rezzed, in the on_rez event, rather than when the script is saved or reset, in the state_entry event: state_entry() { llParticleSystem([]); } on_rez(integer num) { llSetTimerEvent(3); } //etc... Edit: I just saw your link to the thrower script, and it does use llRezAtRoot, so I think my suggestion above should do the trick. Edited March 30, 2020 by KT Kingsley Deleted commented out llRestScript call to avoid confusion. 1 Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted March 30, 2020 Share Posted March 30, 2020 (edited) 29 minutes ago, KT Kingsley said: How does the thrower object work? Does it rez the grenade with a velocity, using llRezObject or llRezAtRoot? Or is it something like a physical catapult? One thing you could try is to have the timer start when the grenade is rezzed, in the on_rez event, rather than when the script is saved or reset, in the state_entry event: state_entry() { llParticleSystem([]); } on_rez(integer num) { // llResetScript(); llSetTimerEvent(3); } //etc... Edit: I just saw your link to the thrower script, and it does use llRezAtRoot, so I think my suggestion above should do the trick. As someone who's made a small bunch of stuff for combat, a script reset should be unnecessary and would only prolong the "initialization period" of the grenade. That specific example would also never start a timer. The script will exit the event before it can set the timer, and the timer would disappear even if the lines were swapped. Edit: Oh, I literally didn't even spot the comment-slashes. Edited March 30, 2020 by Wulfie Reanimator 1 Link to comment Share on other sites More sharing options...
KT Kingsley Posted March 30, 2020 Share Posted March 30, 2020 Oh, and so as not to start the timer when you rez the grenade from your inventory to edit it, you could test if the on_rez parameter is not 0 (the llRezAtRoot functions in the thrower script set a parameter of either 1 or 10, depending on the mode). So: on_rez(integer num) { if (num) llSetTimerEvent(3); } 1 Link to comment Share on other sites More sharing options...
KT Kingsley Posted March 30, 2020 Share Posted March 30, 2020 1 minute ago, Wulfie Reanimator said: As someone who's made a small bunch of stuff for combat, a script reset should be unnecessary and would only prolong the "initialization period" of the grenade. That specific example would also never start a timer. The script will exit the event before it can set the timer, and the timer would disappear even if the lines were swapped. In that example I did comment out the redundant llResetScript call. I'll edit my post to delete it altogether, to avoid confusion. 1 Link to comment Share on other sites More sharing options...
KT Kingsley Posted March 30, 2020 Share Posted March 30, 2020 And, I just noticed, you'll need a no_sensor event in the grenade script for when your aim is off (or you're just playing around) and the grenade lands more than 5 metres away from an avatar. 1 1 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 1 hour ago, KT Kingsley said: And, I just noticed, you'll need a no_sensor event in the grenade script for when your aim is off (or you're just playing around) and the grenade lands more than 5 metres away from an avatar. Woah! This is super cool! 😎 Yes, no_sensor event was really missing! I'm not sure that I did everything right but it works great for now! Thanks a lot! 💖 string EXPLODE3 = "fd5e5c93-691c-eadb-ee27-8972af741823"; iParticles() { llParticleSystem([PSYS_PART_MAX_AGE,1.50, PSYS_PART_FLAGS, 291, PSYS_PART_START_COLOR, <0, 0, 0>, PSYS_PART_END_COLOR, <1, 1, 1>, PSYS_PART_START_SCALE,<1, 1, 0>, PSYS_PART_END_SCALE,<4, 4, 0>, PSYS_SRC_PATTERN, 2, PSYS_SRC_BURST_RATE,0.00, PSYS_SRC_BURST_PART_COUNT,20, PSYS_SRC_BURST_RADIUS,0.30, PSYS_SRC_BURST_SPEED_MIN,0.10, PSYS_SRC_BURST_SPEED_MAX,5.00, PSYS_SRC_ANGLE_BEGIN, 3.14, PSYS_SRC_ANGLE_END, 0.00, PSYS_SRC_MAX_AGE, 0.0, PSYS_SRC_TEXTURE, "74e8631c-33a9-bc1a-03d3-ede886272a21", PSYS_PART_START_ALPHA, 0.80, PSYS_PART_END_ALPHA, 0.00, PSYS_PART_START_GLOW, 0.05, PSYS_PART_END_GLOW, 0.00]); } default { state_entry() { llParticleSystem([]); } on_rez(integer num) { llSetTimerEvent(3); } sensor(integer detected) { while (detected--) { llPushObject(llDetectedKey(detected), 6000.0 * llGetObjectMass(llDetectedKey(detected)) * (llDetectedPos(detected) - llGetPos()), ZERO_VECTOR, FALSE); } llSleep(1); llDie(); } no_sensor() { iParticles(); llTriggerSound(EXPLODE3, 1.0); llTriggerSound(EXPLODE3, 1.0); llTriggerSound(EXPLODE3, 1.0); llSleep(1); llDie(); } timer() { iParticles(); llSensor("", NULL_KEY, (AGENT | PASSIVE), 5.0, PI); llTriggerSound(EXPLODE3, 1.0); llTriggerSound(EXPLODE3, 1.0); llTriggerSound(EXPLODE3, 1.0); } } 1 Link to comment Share on other sites More sharing options...
Tattooshop Posted March 30, 2020 Author Share Posted March 30, 2020 I’ll just notice that I duplicated llTriggerSound and particles in no_sensor by mistake, because the particles and sound seem to go even without it. Link to comment Share on other sites More sharing options...
Tattooshop Posted April 2, 2020 Author Share Posted April 2, 2020 (edited) @Rolig Loon I apologize for pulling you into this topic again. But is it possible to somehow start the process without a sensor with a timer, since it is already here? I tried to move the line llPushObject(llDetectedKey(detected), 6000.0 * llGetObjectMass(llDetectedKey(detected)) * (llDetectedPos(detected) - llGetPos()), ZERO_VECTOR, FALSE); to timer event but I didn’t succeed. Edited April 2, 2020 by Tattooshop Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now