Jump to content

raycast


Excalihooves
 Share

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

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

Recommended Posts

Hello i need help on a script its a raycast that increases in range like an fragmentation grenade. so the range starts at 0m then increases to 10m. the raycast doent need to pick up anything that standes inbetween the two variables, like for instance if it 3m out if some one would stand inbetween those points is uneffected. im very new to this and i need advice plz help me fix this problem atm im using a for loop

state explode {
    state_entry() {
        
    }
     object_rez(key id)
    {
        llRegionSayTo( id , -789123 , llGetKey() );
    }
    timer(){
         for(aoe = 0.0; aoe <= 10.0; aoe += 0.1){
             llSensor("","",AGENT,aoe,PI);
             if(aoe != 0){
                 jump break;
                }
            }
              for(dmg = 100.0; dmg <= 0.0; dmg -= 0.1){
                damage - 0.1;
                 if(dmg != 100){
                 jump break;
                }
            }
            @break;
            
             llSetObjectDesc((string) damage);
        }
    }

 

 

Edited by Excalihooves
Link to comment
Share on other sites

The script you posted doesn't use a cast ray at all.  It uses a simple sensor (but you haven't shown us the sensor event that has to receive and interpret the results).  A sensor will always detect the closest 16 objects within its range.  You can always filter the results to ignore specific ones, or ones that lie outside of a subrange that you are interested in, but you'd do that after the sensor returns the results of the full scan.

It's not at all clear what your timer event is meant to do, since you've shown it out of context and the variables are evidently global variables that you define and load elsewhere.

Link to comment
Share on other sites

And you're asking for scripting advice in the library. This part of the forum is kinda for posting finished scripts that you want to donate to the community... <-<; Wrong forum section. ;>->

And sensor isn't the same as raycast, as Rolig mentioned. I thought they were the same at first, so don't feel too bad about it, tho. xD

EDIT: Yay, they put it in the right place! Now everyone can see it!

Also, for grenades, I've found it's actually best (at least if you're using messaging for damage with a meter, as opposed to oldskool prim collisions) to just use llWhisper on a secret channel to tell the meter to take damage.

That way everyone within ten meters of the grenade gets hit (whisper has a range of ten meters). ^-^ I've found it's better than using a sensor to determine hits, especially since it's area-of-effect. It's cool for gas grenades too, using a timer to whisper the damage message every few seconds for a specified time. This way people take damage while within range of it, but can at least try to escape taking most of it. xD

*has done a lot of combatty explodey scripting*

My first attempts at grenades had them going off after a timer and rezzing prim shrapnel. While realistic, it's just too impractical. I've found that simply creating the illusion of these things happening is enough, and usually works best. You can use a particle blast for a shrapnel visual effect, and just call out damage to your combat meter.

I'm considering posting my homemade meter and some weapon scripts up, at least stripped-down basic versions, because an awful lot of people seem interested in this kinda stuff. If I do, I'll post them in the Library to share. ^-^ I know it can be tough getting the cool stuff to work when you're new to scripting, so hey.

Edited by Berksey
  • Like 2
Link to comment
Share on other sites

to check specific areas with cast ray use something like this...?

 vector start = llGetPos();
 vector end = start ; (zero meters)


integer filter =  RC_REJECT_PHYSICAL | RC_REJECT_NONPHYSICAL | RC_REJECT_LAND ; // avatars only?

list results = llCastRay(start, end, [RC_REJECT_TYPES,  filter, RC_MAX_HITS, 4] );

 

and to increase range to 10m,

 vector start = llGetPos() + <10.0, 0.0, 0.0>;  (10 meters on X axis)
 vector end = start;

 

cast ray is best used to detect things in a straight line from the prim the script is in, unlike

sensor, which detects in a circle or portions thereof :)

your sensor code above merely increases the range of the sensor, but will still detect people

standing at 3m .... you need to parse the target's distance from the prim to decide who to affect?

// ************** in a timer or where-ever, put your sensor,

 llSensor("", "", AGENT_BY_LEGACY_NAME, 10.0, PI);   // Detect any avatars within a 10 metre radius sphere

// use the sensor event to check **********************

 

 sensor(integer number_detected)
     {    integer i = 0;
          do
          {  llOwnerSay(llDetectedName(i) + " is " + (string) llVecDist(llGetPos(), llDetectedPos(i) ) + "m away.");

          // if avatar is at 10 meters, you could add code here to affect them...tho between 9.5m & 10.0m would be

          // easier to detect as it would be rare to have someone EXACTLY at 10m away?
          }
          while(++i < number_detected);
     }
     no_sensor()
     {  llOwnerSay("No avatars in range.");
     }

Edited by Xiija
  • Like 1
Link to comment
Share on other sites

52 minutes ago, Xiija said:

you need to parse the target's distance from the prim to decide who to affect?

Yes, but as I said earlier, all that parsing takes place after the sensor has detected everyone within the complete range.  So if there are, say, 20 people within 15m of the sensor, but you only care about the few who are between 10 and 15 m away, you have a problem.  The sensor can only detect the closest 16 people, so those 16 will be in the sensor results.  When you parse the results to get the ones between 10 and 15m away, you'll probably miss ALL of them, because they were not among the original 16 closest ones.

You're right, though, that the OP does not want a cast ray for the project he seems to be describing.  A cast ray is for detecting specific targets in a straight line from the source, not targets within a volume of space.

  • Like 2
Link to comment
Share on other sites

I would use llGetAgentList, and do something like this to detect everyone between 10 and 20 metres:

default {
	collision_start(integer num_detected) {
		float fMinDist = 10.0;
		float fMaxDist = 20.0;
		vector vPos = llGetPos();
		list lInRange;
		key kAv;
		list lAvs = llGetAgentList(AGENT_LIST_PARCEL, []);
		integer max = -llGetListLength(lAvs);
		if(max){
			do{
				kAv = llList2Key(lAvs, max);
				float fDist = llVecDist(vPos, llList2Vector(llGetObjectDetails(kAv, [OBJECT_POS]), 0));
				if(fDist > fMinDist && fDist <fMaxDist){
					lInRange +=[kAv];
				}
			}
			while (++max);
		}

		max = -llGetListLength(lInRange);
		if(max){
			llOwnerSay("The following avatars are in range:");
			do{
				llOwnerSay(llGetUsername(llList2Key(lInRange, max)));
			}
			while (++max);
		}
		else{
			llOwnerSay("No one in range");
		}
	}
}

 

  • Like 5
Link to comment
Share on other sites

Yeah I tried using raycasting for primless ranged weapons at one point, but sensor just worked a lot better. You can even narrow the sphere into a thin beam-like cone, and use it like a tripwire for boobytraps (using sensor repeat). xD Raycasting just never seemed to suit my purposes, even after wading through all the filters and getting them in order.

I like Innula's example up there a lot. That's like using radar!

I can see that being extremely useful for things like spellcasting, actually. Healing only people on your own team, or only incinerating people on the opposing team is a practical application I can think of right off.

Edited by Berksey
Link to comment
Share on other sites

ok ive fix the grenade from the suggestion but it one detect the avat between two point

 

 

 

 

 

key agent;

key kAv;
                       
vector pos;

vector vPos;

vector vel;

float fDist;

float rng = 0;

float MinDist = 0.00;
 
float MaxDist = 0.25;
 
integer bit;

integer i;

integer hits=0;

integer hex;

integer max;

list rc;

list lInRange;

list lAvs;

default

{

    state_entry()

    {

        //llVolumeDetect(TRUE);

    }

    collision_start(integer n)

    {
        llSetStatus(STATUS_PHYSICS,0);
        for(rng = 0.00; rng <= 10.00; rng += 0.25){   //increases range in for loop
        llOwnerSay("loop");
        }
        llSensor("","",AGENT_BY_LEGACY_NAME,rng,PI);
        MinDist + rng;
        MaxDist + rng;
    }
    sensor(integer n)
    {    
            llOwnerSay("sensor firing");
            agent=llDetectedKey(i);
            pos=llDetectedPos(i);
            vel=llDetectedVel(i);
            bit=llGetAgentInfo(agent);
            kAv = llList2Key(lAvs, max);
            vPos = llGetPos();
            max = -llGetListLength(lAvs);
            lAvs = llGetAgentList(AGENT_LIST_PARCEL, []);
            fDist = llVecDist(vPos, llList2Vector(llGetObjectDetails(kAv,[OBJECT_POS]),0));
            rc=llCastRay(llGetPos(),pos,[RC_MAX_HITS,1,RC_REJECT_TYPES,RC_REJECT_PHYSICAL]);
            if(llList2Key(rc,0)==agent||llList2Integer(rc,-1)<=0)
            {   
            if(bit&0x0020&&hits==0)
            {
                hex=(integer)("0x" + llGetSubString(llMD5String((string)llDetectedKey(i),0), 0, 3)); 
               // llRezObject("",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,hex);
                ++hits;
                llOwnerSay(""+llKey2Name(agent));
            }
            else
            {
                if(fDist > MinDist = 5 && fDist < MaxDist = 5.25){
                    llRezObject("shrapnel",pos+(vel*.2),ZERO_VECTOR,ZERO_ROTATION,1);
                    llOwnerSay("5m check");
                }
                if(fDist > MinDist && fDist< MinDist){
                }
                llRezObject("shrapnel",pos+(vel*.2),ZERO_VECTOR,ZERO_ROTATION,1);
                llOwnerSay("0ver 5m check");
            }
        }
    llDie();
    }
    no_sensor()
    {
        llDie();
    }
}

 

the two points are MinDist and MaxDist

 

Link to comment
Share on other sites

5 hours ago, Berksey said:

It's late for me, so the best I can do right now is offer you some spaghetti sauce, lol.

That script will need it.  9_9  It's got overkill in it:  a sensor, llCastRay, and llGetAgentList, plus a bit of encryption. All it really needs is llGetAgentList.  The entire job can be done in the collision_start event.  Detect collision, get list (which contains the UUID and position of each detected agent), and filter the list to see which agents are within your specified range.  llCastRay and llSensor don't tell you anything more than you already know from llGetAgentList.

 

Link to comment
Share on other sites

Yeah, the scattershot approach doesn't usually work well with scripting, cos different functions will either criss-cross, cancel each other out, or, at very least, make the script take longer to do what you want it to do.

If you really and seriously want to sense people on detonation and hit them with prim shrapnel, you can get decent effects by rezzing a physical sphere at an offset from the detected avatar, making sure it's big enough to hit the avatar as it rezzes. It'll push the avatar a bit when it collides, and the collision event in the sphere's script can deal damage or create effects. I've found it works better than rezzing an object and trying to send it towards the detected avatar, at least when I've tried to make working prim shrapnel. My formula was to rezz a 5 meter diameter sphere one meter away from the detected target, five times in a row XD.

I had tried previously to simply explode multiple small shrapnel prims outward at high velocity, but they always rezzed one after the other, and they take time to do it... it had pretty much the same effect as the method above, but there were fewer proper direct hits.

So while in RL the scattershot approach might work for grenades, in LSL (and SL grenades) it's not so great.

I highly recommend looking into making and using a combat meter for this stuff, again. Not only does it work a lot easier for dealing damage and so forth, and lets you focus more on special effects to create the appearance of RL stuff instead, it also means you can create an entire combat/play experience for those who are into it, without having it make a mess all over the place and interfere with users who aren't participating in the combat play. Put on the meter, good to go. Less mess, less potential grief, and probably lighter on server resources too, for what that might be worth to you.

And still, it just makes better sense to me to use the functionality of this magical programming platform of ours to create the virtual effect of a grenade than to try and effectively replicate one a-la RL physics.

So, if you're working on this for the sake of learning, keep at it. A lot of us learned just the same way, pasting bits together and trying to see the bigger picture as it develops. If, however, you just want to make a nicely-working hand grenade for realistic combat play, maybe do what I did when I got serious about it, and try out the advice above. The prim blast approach is a bit messy and takes longer to work than instantaneously whispering "ordnance" to an attachment to everyone within range of the grenade and letting their meters sort it out. Efficient deployment and execution is the main thing. The rest is Hollywood magic and window dressing.

DISCLAIMER:

For learning this stuff, there's nothing whatsoever wrong with trying things just to see if you can do them. Please don't take any of the above as anything other than advice offered in the spirit of saving you some unnecessary work and frustration. If you're doing this project to understand the functions you're trying to use, keep at it until it works. Be stubborn, but open to receiving help. Read and use the wiki, a lot. And keep posting in here so you can benefit from the collective experience of the people here, because they'll elevate your scripting skills a hundredfold if you let them. ^-^

Edited by Berksey
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2550 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...