Jump to content

Hand greanade


Tattooshop
 Share

You are about to reply to a thread that has been inactive for 1478 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

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. 

  • Thanks 1
Link to comment
Share on other sites

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

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.

  • Thanks 1
Link to comment
Share on other sites

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? :D

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

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 by Rolig Loon
  • Thanks 1
Link to comment
Share on other sites

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! :D

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

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! :D

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

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();
    }
  • Thanks 1
Link to comment
Share on other sites

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. :D

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

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

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 by KT Kingsley
Deleted commented out llRestScript call to avoid confusion.
  • Thanks 1
Link to comment
Share on other sites

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 by Wulfie Reanimator
  • Thanks 1
Link to comment
Share on other sites

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);
    }
  • Thanks 1
Link to comment
Share on other sites

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.

  • Thanks 1
Link to comment
Share on other sites

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);
    }
}

 

  • Like 1
Link to comment
Share on other sites

@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 by Tattooshop
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1478 days.

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
 Share

×
×
  • Create New...