Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discussion: Greeter and automatic notecard giver script

Benz Bingyi
Registered User
Join date: 21 May 2007
Posts: 48
05-24-2007 14:45
This is a script that will greet and give avatars a notecard without them touching anything.
Notecards will only be given once because a list is being created with avatars who allready recieved the notecard.
This can be resetted when you reset the list whit the command: reset list



CODE

string welcome;

// Global variables
list visitor_list;
float range = 15.0; // in meters
float rate = 1.0; // in seconds


// Functions
integer isNameOnList( string name )
{
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
if( llList2String(visitor_list, i) == name )
{
return TRUE;
}
}
return FALSE;
}

init()
{
welcome = llGetObjectDesc();
llOwnerSay( "Visitor List Maker started...");
llOwnerSay( "The owner can say 'help' for instructions.");
llSensorRepeat( "", "", AGENT, range, TWO_PI, rate );
llListen(0, "", llGetOwner(), "");
}
// States
default
{
state_entry()
{
init();
}
on_rez( integer param )
{
init();
}
touch_start( integer num )
{
welcome = llGetObjectDesc();
}

sensor( integer number_detected )
{
integer i;
for( i = 0; i < number_detected; i++ )
{
if( llDetectedKey( i ) != llGetOwner() )
{
string detected_name = llDetectedName( i );
if( isNameOnList( detected_name ) == FALSE )
{
llInstantMessage( llDetectedKey( i ), welcome + detected_name);
visitor_list += detected_name;
llOwnerSay ( detected_name + " has been added to your visitors list at " + llGetRegionName() );
llGiveInventory(llDetectedKey(0), "Benz Shop low priced lots of flexi items.");
}
}
}
}

listen( integer channel, string name, key id, string message )
{
if( id != llGetOwner() )
{
return;
}

if( message == "help" )
{
llOwnerSay( "This object records the names of everyone who" );
llOwnerSay( "comes within "+ (string)range + " meters." );
llOwnerSay( "Commands the owner can say:" );
llOwnerSay( "'help' - Shows these instructions." );
llOwnerSay( "'say list' - Says the names of all visitors on the list.");
llOwnerSay( "'reset list' - Removes all the names from the list." );
llOwnerSay ( "TO change the greeting - change the object description and touch the object" );
}
else
if( message == "say list" )
{
llOwnerSay( "Visitor List:" );
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
llOwnerSay( llList2String(visitor_list, i) );
}
llOwnerSay( "Total = " + (string)len );
}
else
if( message == "reset list" )
{
visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
llOwnerSay( "Done resetting.");
}
}
}
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Original Thread
05-31-2007 09:48
/15/56/186186/1.html
_____________________
i've got nothing. ;)
Destiny Niles
Registered User
Join date: 23 Aug 2006
Posts: 949
05-31-2007 14:13
Any reason for using the for loop and not the llListFindList function?
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
05-31-2007 15:09
Just an observation that running a sensor scan every second is laggier than waiting for avatars to collide with a prim--perhaps one that's llVolumeDetect(TRUE) phantom.
Eben Slade
If the wind stops, row!
Join date: 17 May 2007
Posts: 146
06-16-2007 18:16
Great script, just one problem... When cut and pasted directly, it gives the notecard to the *owner* and not the visitor.
Tetria Watts
Registered User
Join date: 15 Aug 2006
Posts: 5
06-18-2007 00:54
From: Benz Bingyi

<..snip..>
string detected_name = llDetectedName( i );
if( isNameOnList( detected_name ) == FALSE )
{
llInstantMessage( llDetectedKey( i ), welcome + detected_name);
visitor_list += detected_name;
llOwnerSay ( detected_name + " has been added to your visitors list at " + llGetRegionName() );
llGiveInventory(llDetectedKey(0), "Benz Shop low priced lots of flexi items.";);
}
<..snip..>


the llGiveInventory should be using llDetectedKey(i) since 0 always gives the nearest key, that'll
solve the giving problem, otherwise looks functional to me.
Chaos Bikcin
Registered User
Join date: 10 Jun 2007
Posts: 296
11-05-2007 17:16
this script does not work :(
_____________________
www.felonhall.com
Dayna Bedrosian
Registered User
Join date: 27 May 2008
Posts: 4
12-18-2008 09:42
I have had problems with it as well. I have tried to tweak it. It seems that the detect works fine, but actually delivering a notecard is where it fails. What I am would like to do is combine these two scripts. To where when the owner of the prim click it, it will dispense the notecards in its contents in a folder without having to list every notecard. I would greatly appreciate all the help with this. As I am a bit stumped.

Here are the two scripts I am working on. The Original one.
From: someone

string welcome;

// Global variables
list visitor_list;
float range = 15.0; // in meters
float rate = 1.0; // in seconds


// Functions
integer isNameOnList( string name )
{
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
if( llList2String(visitor_list, i) == name )
{
return TRUE;
}
}
return FALSE;
}

init()
{
welcome = llGetObjectDesc();
llOwnerSay( "Visitor List Maker started...";);
llOwnerSay( "The owner can say 'help' for instructions.";);
llSensorRepeat( "", "", AGENT, range, TWO_PI, rate );
llListen(0, "", llGetOwner(), "";);
}
// States
default
{
state_entry()
{
init();
}
on_rez( integer param )
{
init();
}
touch_start( integer num )
{
welcome = llGetObjectDesc();
}

sensor( integer number_detected )
{
integer i;
for( i = 0; i < number_detected; i++ )
{
if( llDetectedKey( i ) != llGetOwner() )
{
string detected_name = llDetectedName( i );
if( isNameOnList( detected_name ) == FALSE )
{
llInstantMessage( llDetectedKey( i ), welcome + detected_name);
visitor_list += detected_name;
llOwnerSay ( detected_name + " has been added to your visitors list at " + llGetRegionName() );
llGiveInventory(llDetectedKey(0), "Benz Shop low priced lots of flexi items.";);
}
}
}
}

listen( integer channel, string name, key id, string message )
{
if( id != llGetOwner() )
{
return;
}

if( message == "help" )
{
llOwnerSay( "This object records the names of everyone who" );
llOwnerSay( "comes within "+ (string)range + " meters." );
llOwnerSay( "Commands the owner can say:" );
llOwnerSay( "'help' - Shows these instructions." );
llOwnerSay( "'say list' - Says the names of all visitors on the list.";);
llOwnerSay( "'reset list' - Removes all the names from the list." );
llOwnerSay ( "TO change the greeting - change the object description and touch the object" );
}
else
if( message == "say list" )
{
llOwnerSay( "Visitor List:" );
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
llOwnerSay( llList2String(visitor_list, i) );
}
llOwnerSay( "Total = " + (string)len );
}
else
if( message == "reset list" )
{
visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
llOwnerSay( "Done resetting.";);
}
}
}


From: someone

list gInventoryList;

list getInventoryList()
{
integer i;
integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
list result = [];
llSetText("Click box for Student Folder", <255,255,0>, 1);
for( i = 0; i < n; i++ )
{
result += [ llGetInventoryName(INVENTORY_NOTECARD, i) ];
}
return result;
}

default
{
state_entry()

{
llSay(0, "Sentence it says upon rez.";);
gInventoryList = getInventoryList();
}

touch_start( integer n )
{
integer i;

for( i = 0; i < n; i++ )
{
llSay(0, "Sentence goes here";);
llGiveInventoryList(llDetectedKey(i), "Folder Name", gInventoryList );
}
}

changed( integer change )
{
if ( change == CHANGED_INVENTORY )
gInventoryList = getInventoryList();
}
}
Dayna Bedrosian
Registered User
Join date: 27 May 2008
Posts: 4
12-18-2008 09:58
I have had problems with it as well. I have tried to tweak it. It seems that the detect works fine, but actually delivering a notecard is where it fails. What I am would like to do is combine these two scripts. To where when the owner of the prim click it, it will dispense the notecards in its contents in a folder without having to list every notecard. I would greatly appreciate all the help with this. As I am a bit stumped.

Here are the two scripts I am working on. The Original one.
From: someone

string welcome;

// Global variables
list visitor_list;
float range = 15.0; // in meters
float rate = 1.0; // in seconds


// Functions
integer isNameOnList( string name )
{
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
if( llList2String(visitor_list, i) == name )
{
return TRUE;
}
}
return FALSE;
}

init()
{
welcome = llGetObjectDesc();
llOwnerSay( "Visitor List Maker started...";);
llOwnerSay( "The owner can say 'help' for instructions.";);
llSensorRepeat( "", "", AGENT, range, TWO_PI, rate );
llListen(0, "", llGetOwner(), "";);
}
// States
default
{
state_entry()
{
init();
}
on_rez( integer param )
{
init();
}
touch_start( integer num )
{
welcome = llGetObjectDesc();
}

sensor( integer number_detected )
{
integer i;
for( i = 0; i < number_detected; i++ )
{
if( llDetectedKey( i ) != llGetOwner() )
{
string detected_name = llDetectedName( i );
if( isNameOnList( detected_name ) == FALSE )
{
llInstantMessage( llDetectedKey( i ), welcome + detected_name);
visitor_list += detected_name;
llOwnerSay ( detected_name + " has been added to your visitors list at " + llGetRegionName() );
llGiveInventory(llDetectedKey(0), "Benz Shop low priced lots of flexi items.";);
}
}
}
}

listen( integer channel, string name, key id, string message )
{
if( id != llGetOwner() )
{
return;
}

if( message == "help" )
{
llOwnerSay( "This object records the names of everyone who" );
llOwnerSay( "comes within "+ (string)range + " meters." );
llOwnerSay( "Commands the owner can say:" );
llOwnerSay( "'help' - Shows these instructions." );
llOwnerSay( "'say list' - Says the names of all visitors on the list.";);
llOwnerSay( "'reset list' - Removes all the names from the list." );
llOwnerSay ( "TO change the greeting - change the object description and touch the object" );
}
else
if( message == "say list" )
{
llOwnerSay( "Visitor List:" );
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
llOwnerSay( llList2String(visitor_list, i) );
}
llOwnerSay( "Total = " + (string)len );
}
else
if( message == "reset list" )
{
visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
llOwnerSay( "Done resetting.";);
}
}
}


From: someone

list gInventoryList;

list getInventoryList()
{
integer i;
integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
list result = [];
llSetText("Click box for Student Folder", <255,255,0>, 1);
for( i = 0; i < n; i++ )
{
result += [ llGetInventoryName(INVENTORY_NOTECARD, i) ];
}
return result;
}

default
{
state_entry()

{
llSay(0, "Sentence it says upon rez.";);
gInventoryList = getInventoryList();
}

touch_start( integer n )
{
integer i;

for( i = 0; i < n; i++ )
{
llSay(0, "Sentence goes here";);
llGiveInventoryList(llDetectedKey(i), "Folder Name", gInventoryList );
}
}

changed( integer change )
{
if ( change == CHANGED_INVENTORY )
gInventoryList = getInventoryList();
}
}
Cappy Frantisek
Open Source is the Devil!
Join date: 27 Oct 2006
Posts: 400
12-18-2008 12:22
God another notecard giver. Gets a quick MUTE from me. I hate spam!
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
12-18-2008 12:25
From: Dayna Bedrosian
..It seems that the detect works fine, but actually delivering a notecard is where it fails. .

That's a bug on this line:

llGiveInventory(llDetectedKey(0), "Benz Shop low priced lots of flexi items.";);

It should be using ...llDetectedKey(i) .
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
Another Greeter/Counter
12-18-2008 12:27
Here's my version of a script that does sort of what you want. It isn't necessarily as efficient as it might be, but it works well and is low lag because I only scan every 20 seconds (although you could certainly scan more often). It greets visitors and offers a notecard and (because I set this one up as a freebie vendor) an object, and it gives repeat visitors the option of clicking for a notecard if they wish. It also keeps track of the total number of visitors and an unduplicated headcount for statistical purposes.

CODE

// ------------------------------------------
// GreetCounter
// Rolig Loon 04-12-08
// This script looks around every 20 seconds and, if an avatar is detected,
// sends a greeting and gives a notecard. It then adds the avatar's name to
// a list and will not give either the greeting or the notecard to that
// avatar again, unless the avatar touches the object that contains the script.
// The owner can request the list on channel 27 with the command "list." The
// list automatically resets when the number of encounters reaches 250 or when
// the owner says "reset" on channel 27.
//
string notecard = "GreetCounter Instructions"; // Name of the notecard you want to give out
string object = "GreetCounter 1"; //Name of the object you want to hand out
float scanrange = 2.5; // How far away ( in meters) should the detector look for a visitor?
// ---------- Don't mess with things below this line ---------
//
integer SomebodyNear = 0;
list visitor_list = [];
list temp_visitor = [];
integer TouchOn = 0;
string detected_name = "";
string setdate= "";
string settime= "";
string cleardate = "";
integer clear = 0;
integer count = 0;
integer totalcount = 0;
integer isNameOnList( list list_name, string name )
{
integer len = llGetListLength( list_name );
integer i;
for( i = 0; i < len; i++ )
{
if( llList2String(list_name, i) == name )
{
return TRUE;
}
}
return FALSE;
}
clearlist()
{
visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
llOwnerSay("Visitor lists reset.");
}
default
{
state_entry()
{
list hold = llParseString2List(llGetTimestamp(),["T", "."],[]);
setdate = llList2String(hold,0);
settime = llList2String(hold,1);
llSetTimerEvent(20.0);
}
on_rez(integer x)
{
llResetScript();
}
timer()
{
llSensor("",NULL_KEY,AGENT,scanrange,PI);
}
sensor( integer number_detected )
{
llListen(27,"",llGetOwner(),"");
integer j;
for (j=0; j < number_detected; j++)
{
if (SomebodyNear == 0 || (SomebodyNear == 1 && isNameOnList(temp_visitor,
llDetectedName(j)) == FALSE))
{
// This loop if new visitor or returning visitor
integer i;
for( i = 0; i < number_detected; i++ )
{
string detected_name = llDetectedName( i );
if( isNameOnList( visitor_list, detected_name ) == FALSE )
{
// This loop if new visitor
visitor_list += detected_name;
temp_visitor += detected_name;
SomebodyNear = 1;
llSay(0,"Welcome, " +detected_name +"!");
llGiveInventory(llDetectedKey(i),notecard);
llGiveInventory(llDetectedKey(i),object);
++count;
++totalcount;
}
else
{
// This loop if returning visitor
++totalcount;
SomebodyNear = 1;
temp_visitor += detected_name;
TouchOn = 1;
llWhisper(0, "Welcome back, " + detected_name + "! If you are looking for
a copy of GreetCounter or the instructions, just click on this kiosk.");
llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, TRUE] );
llSleep(5.0);
llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, FALSE] );
}
integer len = llGetListLength( visitor_list );
if(len > 250)
{
clearlist();
cleardate = llGetDate();
clear = 1;
}
}
}
}
}
touch_start(integer num_detected)
// Give greeting and notecard on touch if this is a repeat encounter
{
if(TouchOn == 1)
{
llSay(0,"Thank you, " +detected_name + ". Here is the information you requested.");
llGiveInventory(llDetectedKey(0),notecard);
llGiveInventory(llDetectedKey(0),object);
TouchOn = 0;
}
}
listen( integer channel, string name, key id, string message )
{
integer len = llGetListLength( visitor_list );
if (llToLower(message) == "list")
{
llOwnerSay("Most Recent Visitors:" );
if (clear == 1)
{
llOwnerSay("(This list was reset on " +cleardate + ".)");
}
integer i;
for( i = 0; i < len; i++ )
{
llOwnerSay( llList2String(visitor_list, i) );
}
llOwnerSay("Total (unduplicated) = " + (string)count + " since the last system reset
on " + setdate + " at " + settime + " (GMT).");
llOwnerSay("Total (including repeats) = " + (string)totalcount + " since the last
reset.");
}
else if (llToLower(message) == "reset")
{
count = 0;
totalcount = 0;
clearlist();
setdate = llGetTimestamp();
clear = 0;
}
}
no_sensor()
{
SomebodyNear = 0;
temp_visitor = [];
}
}
// ------------------------------------------
Dayna Bedrosian
Registered User
Join date: 27 May 2008
Posts: 4
12-18-2008 13:02
Thanks for the help. I am going to try and see if I can get it to work for what I am trying to do. Basically I am making a HUD that will give out Note Cards to people in "x" meters from where I am in a folder when I touch the Prim in my HUD.

May be with altering this script a little bit. To where it does not give me the inventory, but people within "x" meters of it.

From: someone

list gInventoryList;

list getInventoryList()
{
integer i;
integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
list result = [];
llSetText("floating text", <255,255,0>, 1);
for( i = 0; i < n; i++ )
{
result += [ llGetInventoryName(INVENTORY_NOTECARD, i) ];
}
return result;
}

default
{
state_entry()

{
llSay(0, "Sentence it says upon rez.";);
gInventoryList = getInventoryList();
}

touch_start( integer n )
{
integer i;

for( i = 0; i < n; i++ )
{
llSay(0, "Sentence goes here";);
llGiveInventoryList(llDetectedKey(i), "Folder Name", gInventoryList );
}
}

changed( integer change )
{
if ( change == CHANGED_INVENTORY )
gInventoryList = getInventoryList();
}
}
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
12-18-2008 13:13
In that case, you'll need something like the stuff in my sensor event so you can deal with multiple people within your scan range and so that you don't end up giving extra copies to people who already have them. Use llGiveInventoryList in place of the llGiveInventory calls, with some minor tweaking to set it up properly. That way, all the things you give will end up in a single folder in the receiver's inventory.

EDIT: Our notes crossed...:) . Yes, your script is a start. It doesn't deal with the multiple copies issue, so you'll annoy people who keep being detected over and over again -- either because they stay in scan range long enough to be detected many times or because they come back hours later and are detected again. That's why I went through all the business of identifying unique visitors.

If you want to avoid giving yourself items, just include a simple filter of the type

CODE

if (llDetectedKey(i) != llGetOwner())
{// blah blah}
Ollj Oh
Registered User
Join date: 28 Aug 2007
Posts: 522
12-18-2008 18:19
more alt-accounts begging to get muted...
Escort DeFarge
Together
Join date: 18 Nov 2004
Posts: 681
12-18-2008 23:18
As well as introducing spurious lag from a sensor, giving unrequested crap (i mean marketing collateral -- wait no -- i *did* mean "crap";) this script will have a negative effect on your customers/visitors -- often driving them away. Do some checks and you'll see it's true.
_____________________
http://slurl.com/secondlife/Together
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
12-19-2008 07:46
That's a strange reaction. :rolleyes:

I wrote the script for use in a library/museum environment, where visitors are coming LOOKING for information and where it's important to gather statistics on the number of unique visitors. The notecard is generally a guide to the collections. As written, the script greets a visitor and offers a notecard. The script recognizes a visitor who stays around within scan range for a while and doesn't bother him/her with a second offer. A return visitor gets a one-line greeting in chat but doesn't get a notecard unless he/she requests it by touching the device. Minimal annoyance. Sensor lag, at one scan every 20 seconds, is also minimal.
Dayna Bedrosian
Registered User
Join date: 27 May 2008
Posts: 4
12-19-2008 21:01
For me I am working a HUD that is used in a classroom environment. I want to be able to hand out test and text to my students in a folder when I touch the button and also to where it will not give repeats. I can see how the script can be used to an annoyance though. That is not what I am looking for.
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
12-19-2008 21:31
Yup. I guess any script can be used for evil. The notecard giver part of mine is really only three or four lines that can be commented out. For me, the challenge was creating a counter that would keep track of unique visitors, and one that would recognize that when it sees the same person within scan range over a long time, that's still only one visit. I use it mostly for that statistical purpose. Because I work with a library and museum community, though, they also occasionally need a way to be sure that visitors get an overview when they walk in. Hence the notecard capability, which was almost an afterthought. It turns out, though, that by combining the two functions, I have made a greeter with a pretty low annoyance factor. It sounds like you have a parallel need, Dayna.

Good luck.
Dayna Bedrosian
Registered User
Join date: 27 May 2008
Posts: 4
12-19-2008 21:50
It is possible :). Just need to work it a bit. The greeter is a good idea, but having the counter to keep track of visitors is great.