Jump to content

SOLVED Object Sensor for Help!


drusilladarkwillow
 Share

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

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

Recommended Posts

edit: I had gotten help inworld from a friend. She helped me to build a new script to work the way that I want it to.

 

I have made an object rezzer script that also has an inventory counter inside of it. It's written to also rez the object on a certain rotation. What I can't seem to get it to do is to rez another object when the first object is no longer in range. I have tried plugging in bits from a modify script that I had found to no avail and I've tried parts of the code for a visitor counter but with my limited LSL abilities, I'm not able to rewrite it correctly.

 

I need help with getting it to scan within a 5 meter range for the object in the inventory (only one item in it, it's no copy to me) and to rez out another one when none is in range. I've been on every LSL library that I know of and every sensor based topic I have found thus far is in reference to a visitor counter which doesn't help me. Help please! Can provide code of what I have already if needed.

Edited by drusilladarkwillow
Link to comment
Share on other sites

It's never a bad idea to post whatever code you might have already.

As for rezzing -- since you said "it's no-copy to me," a script can't rez multiple copies of it either. You must have copy permissions for the object in inventory.

As for the sensor, the Wiki sums up what "info" to give to a function: aaed89e58f.png

Since you want to check for a specific object, the easiest way to do that is to sense based on the names of nearby objects.

For example: llSensorRepeat( "Object name", PASSIVE, 5.0, PI, 2.0 );

That would cause a sensor to trigger every 2.0 seconds within 5.0 meters in any direction to the object, as long as it detected a nonphysical object named "Object name".

To actually do something when something is found, your script needs to have a sensor and no_sensor event. (no_sensor is for when nothing was detected.) These are very simple, especially because you only said you want to do something when nothing is in range (nothing detected). So in this case, you only need a no_sensor event. d651151662.png

Or in plain code:

default
{
    // All of your other code is somewhere up here

    no_sensor()
    {
        llRezObject(...);
    }
}

 

Edited by Wulfie Reanimator
Link to comment
Share on other sites

@Wulfie Reanimator I know that the script can't make more copies of it. I'm putting copies in it. I'm selling items created by a farming system. I have a script that will rez out another object from inside of the inventory but it also won't allow me to edit it so that I can change the object rotation upon rez. This is what I currently have: 

string inventory;
string object;
vector relativePosOffset = <0.0, 0.0, 0.2>;
vector relativeVel = <0.0, 0.0, 0.0>;
rotation relativeRot = <0.707107, 0.0, 0.0, 0.707107>;
integer startParam = 0;


float scanDistance = 2.0;
float   SCAN_INTERVAL    = 5.0;

integer items_contained;
string name;

CountItems()
    {
    items_contained = llGetInventoryNumber( INVENTORY_ALL );
  --items_contained; 
    }
SayCount()
    {
    name = llGetObjectName();
    llSetText(name + "\n" + "Has " + (string)items_contained + " items.", <0.0,1.0,0.0>, 1 );
    }
    
    
default
{
    touch_start(integer count)
    {
        object=llGetInventoryName(INVENTORY_OBJECT,0);  //get name of the 1st object in inventory
        vector myPos = llGetPos();
        rotation myRot = llGetRot();
        vector rezPos = myPos+relativePosOffset*myRot;
        vector rezVel = relativeVel*myRot;
        rotation rezRot = relativeRot*myRot;
        
        llRezObject(object, rezPos, rezVel, rezRot, startParam);  //rez the 1st object
    }

    
    state_entry()
    {
    llSetTimerEvent(0.5);
    }
    on_rez(integer total_number)
    {
    CountItems();
    SayCount();
    llSetObjectDesc("Has " + (string)items_contained+ " items.");
    }
    timer() 
    {
    CountItems();
    SayCount();
    llSetObjectDesc("Has " + (string)items_contained+ " items.");
    }
    
}

Link to comment
Share on other sites

OK. First, you have a script which should rez the first object in the prim's inventory every time you "touch" the object. Does that work?

  • It would be a good idea to check what object name you get from object=llGetInventoryName(INVENTORY_OBJECT,0); You can get an empty string from that. Or, if there is some other object in the prim's inventory, you might get it.
  • items_contained = llGetInventoryNumber( INVENTORY_ALL ); is doing what, exactly? That will count scripts, textures, notecards, or anything else in the prim. You probably want INVENTORY_OBJECT.
  • Once you get the sensor / no sensor events reporting properly on whether there is an object around, this should work.
  • After you rez an object, wait a few seconds before the next sensor scan, to allow the rez to take place. On a busy sim, rezzing can take a while.

 

Link to comment
Share on other sites

@animats Yeah, I want it to count the inventory inside so that I know when it's empty upon glance and I also know that the state is probably wrong for what I want. All I really did was combined scripts together. With my scripting knowledge, all I can do is edit a script, I can't actually write one on my own.

Edited by drusilladarkwillow
Link to comment
Share on other sites

OK. To practice on this, first get a llSensorRepeat going. Put this in the "state_entry" function of "default" state.

llSensorRepeat("Your object name", "" , PASSIVE, 2.0, PI, 5.0 );

That will check for an unscripted object called "Your object name" being anywhere within 2 meters, making the check every 5 seconds.

Then, add a no_sensor function inside the "default" state:
 

no_sensor()

{    llOwnerSay("No object found."); }

Now, your object should say "No object found." to you every 5 seconds. Then create a new prim and name it "Your object name", and put it very close to the prim running the script. The "No object found" messages should stop. Move the prim more than 2m away, and the messages should start again.

Once you have that working, the sensor is working OK. So now you can do, in the "no sensor" function, what you were doing in "touch_start". Then, each time you take the newly rezzed object away, a new one should appear. Practice this with an ordinary prim before trying it with your no-copy objects.

Edited by animats
Link to comment
Share on other sites

@animats  The problem with using the object name, it gets changed when the same thing is in there so I'll still will probably have to keep changing the script to get it to notice that the second item is no longer there since it's name now has a 1 after it. I also don't want the object to tell me when it's empty. I'm at my shop almost every day, I can just look at it and see. I don't want another thing sending me IM's. My vendors already do that. What will be inside of the rezzers isn't as important for me to know when it's empty no matter where I am but when I get there to see it. Also the objects inside of my rezzer are scripted. They're food items for the farming system. I have a script that I can toss to you so that you can see the functions that I want, all I want more from that freebie script is to be able to set the rotation so that you can actually see what it is better from where I have it placed out within my shop.

Link to comment
Share on other sites

it would look something like this, but this doesnt f**cking work

string inventory;
string object;
vector relativePosOffset = <1.0, 0.0, 0.2>;
vector relativeVel = <0.0, 0.0, 0.0>;
rotation relativeRot = <0.707107, 0.0, 0.0, 0.707107>;
integer startParam = 0;
float scanDistance = 2.0;
float   SCAN_INTERVAL    = 5.0;
integer items_contained;
string name;
integer rezcount;
string objname;

integer CountItems()
{ return  items_contained = llGetInventoryNumber( INVENTORY_ALL );
  // --items_contained; 
}
SayCount()
{  name = llGetObjectName();
   llSetText(name + "\n" + "Has " + (string)items_contained + " items.", <0.0,1.0,0.0>, 1 );
}

rezzit()
{   object = llGetInventoryName(INVENTORY_OBJECT,0);  //get name of the 1st object in inventory
    vector myPos = llGetPos();
    rotation myRot = llGetRot();
    vector rezPos = myPos+relativePosOffset*myRot;
    vector rezVel = relativeVel*myRot;
    rotation rezRot = relativeRot*myRot;        
    llRezObject(object, rezPos, rezVel, rezRot, startParam);  //rez the 1st object
    ++rezcount;
    llOwnerSay("rezcount: " + (string)rezcount +"\nObj: " + object );
}
default
{
    touch_start(integer count)
    {  rezzit();
    }   
    
    object_rez(key id) // as soon as something is rez'd , turn on sensor
    {  if( rezcount == 1) { objname = object; }
       else { objname = object + " 1"; }
       llOwnerSay("Sensor for:..." + objname );
       llSensorRepeat( objname , "" , (PASSIVE|SCRIPTED), 10.0, PI, 10.0 );
       
    }
    sensor( integer detected )
    {   while(detected--)
        {  llOwnerSay(llDetectedName(detected));
        }     
    }
    no_sensor() //  when item is taken, if any are left in inv, rez another
    {  if( CountItems() )
       rezzit();
    }
    
}

 

Link to comment
Share on other sites

This is hard to do right. Here's a working version. It's quite common to see rezzers that will rez two copies of an object in the same place. Here's one that doesn't have that problem.  It makes an llSensorRepeat call, and if it finds an object, gets its position with llDetectedPos. It checks for an object at the rez point. If there isn't one, it creates one.

string objname = "Test object";
vector REZPOS = <0,0,0.5>;                                  // rez object here, relative to object
float REZTOL = 0.20;                                        // further from this and it's not what we rezzed

doRez()
{
    llRezObject(objname, <0,0,0.5>+llGetPos(),
            ZERO_VECTOR, ZERO_ROTATION,0);
}

default
{
    state_entry()
    {
        llSensorRepeat("",NULL_KEY, PASSIVE, llVecMag(REZPOS)*1.1, PI, 5.0);
    }
    
    on_rez(integer info)
    {   llResetScript(); }
    
    sensor(integer num_detected)
    {   integer i;
        integer found = FALSE;                                      // check for an object at the rez point
        for (i=0; i<num_detected; i++)
        {   float distfromrez = llVecMag(llDetectedPos(i) - (llGetPos() + REZPOS));
            if (distfromrez < REZTOL) { found = TRUE; }           // that's our object  
        }
        if (!found) { doRez(); }                                // if no object at rez point, make another one.     
    }
    
    no_sensor()
    {   doRez(); }
}

 

 

Link to comment
Share on other sites

On 2/1/2019 at 11:19 AM, Hintswen Guardian said:

Eh I still prefer my way, doesn't use a sensor at all. I sent OP the script directly :)

@Hintswen Guardian Could you shortly post a short description what your approach is? Is it working with listeners and communicating the object position? I am always interested in learning about different approaches to a problem. 

Link to comment
Share on other sites

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