Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Shopping HUD

Astra Melody
Registered User
Join date: 5 Jan 2010
Posts: 10
01-13-2010 02:30
What is the Shopping HUD?

When you enter a SIM you click Search on the HUD and it asks the nearby vendors containing the Shopping HUD Info script about their contents. The vendors reply by email to save on the sim lag and they send picture and descriptions of the items they sell.

Then the HUD owner can browse through the items without moving and then can find a vendor by pressing Locate. This will move the avatar to the vendor.

It is very experimental and there might be issues in large sims with many vendors. On the other hand you don't need to use it on every vendor in your sim you can only drop it on a few well chosen places.

About lag, it shouldn't add much lag to the sim since it uses the email system to communicate.

So it comes into 3 parts, the first is the notecard you add to the vendor here is a sample one, it shall be called "Shopping Hud".

The first line is the description of the item.

The second line is the name or the UUID of the image to display on the HUD (FULL PERMS). If you provide the name the image must be in the vendor.

The third line is the price of the item it can be a price range too like 10-500. You can put as many as you want but I would advice against putting too many of these because of the lag issues.

From: someone

Another nice outfit
nice
50
Another useful item
2ef4b857-955b-c0af-cd22-fde694a8f8c7
100-300


You need this script to put into the vendors. It relies on the HUD being named "Shopping HUD" or it won't listen to it.


From: someone

string NotecardName = "Shopping Hud" ;
integer Line ;
key QueryID ;
integer SHChannel = 69 ;
key ObjectID ;
integer Handle ; // Listener Handle
string EMailDest ; // object destination
string Message ; // name and price of item
key ImageKey ; // image to display


// Ezhar Fairlight function
integer IsKey(string str) { // returns TRUE if string is a key
return ( (llStringLength(str) == 36) &&
(llGetSubString(str, 8, 8) == "-";) &&
(llGetSubString(str, 13, 13) == "-";) &&
(llGetSubString(str, 18, 18) == "-";) &&
(llGetSubString(str, 23, 23) == "-";) );
}

default
{
state_entry()
{
Handle = llListen(SHChannel, "Shopping HUD", NULL_KEY, "";) ;
}
listen(integer channel, string name, key id, string message)
{
if (message == "SHQ:";)
{
llListenControl(Handle, FALSE) ;
EMailDest = (string)id + "@lsl.secondlife.com" ;
Line = 0 ;
QueryID = llGetNotecardLine(NotecardName, Line) ;
}
}
dataserver(key query_id, string data) {
integer l ;
key k ;

if (query_id == QueryID) {
if ((data != EOF)) { // not at the end of the notecard
l = Line % 3 ;
if (l == 0)
{
Message = data ;
}
else if (l == 1)
{
if (IsKey(data))
{
ImageKey = (key)data ;
}
else // it was not a key but a texture name
{
ImageKey = llGetInventoryKey(data) ;
}
}
else if (l == 2)
{
Message += ", " + data + "L$" ;
llEmail(EMailDest, ImageKey, Message) ;
}
++Line; // increase line count
QueryID = llGetNotecardLine(NotecardName, Line) ; // request next line
}
else
{
llListenControl(Handle, TRUE) ;
}

}
}
}


to be continued with the shopping hud script....
Astra Melody
Registered User
Join date: 5 Jan 2010
Posts: 10
01-13-2010 02:31
The shopping HUD script:
From: someone
integer SHChannel = 69 ;
integer Handle ;
key MyKey ;
integer MyChannel = 42; // dialog channel
list MENU_MAIN = ["Search", "<--", "-->", "Reset", "Locate"]; // the main menu
integer MAXTIME = 300 ;
integer MENUTIMEOUT = 60 ;


list Pos ;
list Desc ;
list Texture ;
integer ItemsCount ;
integer CurItem = 0 ;

integer MenuTick = 0 ;
integer Listening = FALSE ;

setTitle()
{
string title ;
if (ItemsCount == 0)
{
title = "No vendor items found. Click Search to find them." ;
}
else
{
title = "Actually examining " + llList2String(Desc, CurItem) ;
}
llDialog(llGetOwner(), title, MENU_MAIN, MyChannel); // present dialog on
}

resetHUD()
{
Pos = [] ;
Desc = [] ;
Texture = [] ;
llSetTexture(TEXTURE_BLANK, ALL_SIDES) ;
ItemsCount = 0 ;
CurItem = 0 ;
}

init()
{
resetHUD() ;
MyKey = llGetKey() ;
Handle = llListen(MyChannel, "", llGetOwner(), "";); // listen for dialog answers (from multiple users)
llListenControl(Handle, FALSE) ;
llSetTimerEvent(1) ;
}
setCurrent()
{
key k = llList2Key(Texture, CurItem) ;

llSetTexture(TEXTURE_BLANK, ALL_SIDES) ;
if (k == NULL_KEY)
k = TEXTURE_BLANK ;

llSetTexture(k, ALL_SIDES) ;
string desc = llList2String(Desc, CurItem) ;
llOwnerSay(desc) ;
}

default
{
state_entry()
{
init() ;
}
on_rez(integer i)
{
init() ;
}


to be continued...
Astra Melody
Registered User
Join date: 5 Jan 2010
Posts: 10
01-13-2010 02:35
end of the Hud script:

From: someone

email(string time, string address, string subj, string message, integer num_left)
{
list l ;
integer len ;
integer i ;
string s ;
integer ind1 ;
integer ind2 ;
integer posx ;
integer posy ;
integer posz ;
vector v ;

if ((llGetUnixTime() - (integer)time) > MAXTIME)
return ;

Texture += subj ;
l = llParseString2List(message,["\n"],[]);

Desc += llList2String(l , 3) ; // description
s = llList2String(l , 2) ; // position
ind1 = llSubStringIndex(s, ";(";) ;
ind2 = llSubStringIndex(s, ";)";) ;
if ((ind1 != -1) && (ind2 != -1) && (ind1 < ind2))
{
s = llGetSubString(s, ind1+1, ind2-1) ;
ind1 = llSubStringIndex(s, ",";) ;
if (ind1 != -1)
{
posx = (integer)llGetSubString(s, 0, ind1-1) ;
s = llGetSubString(s, ind1+1, llStringLength(s)) ;
ind1 = llSubStringIndex(s, ",";) ;
if (ind1 != -1)
{
posy = (integer)llGetSubString(s, 0, ind1-1) ;
posz = (integer)llGetSubString(s, ind1+1, llStringLength(s)) ;
Pos += < posx, posy, posz> ;
}
}
}
ItemsCount++ ;
if (ItemsCount == 1)
{
setCurrent() ;
}
}
timer()
{
llGetNextEmail("", "";) ;
if (Listening)
{
MenuTick++ ;
if (MenuTick > MENUTIMEOUT)
{
llListenControl(Handle, FALSE) ;
llOwnerSay("The dialog have been cancelled because of " + (string)MENUTIMEOUT + " seconds of inactivity. Click on the HUD to start a new dialog.";) ;
Listening = FALSE ;
MenuTick = 0 ;
}
}
}
listen(integer channel, string name, key id, string message)
{
string code ;
string entry ;
integer l ;

if (channel == MyChannel)
{
if (llListFindList(MENU_MAIN, [message]) != -1) // verify dialog choice
{
MenuTick = 0 ; // used menu so refresh the timer
if (message == "Search";)
{
llSay(SHChannel, "SHQ:";) ;
}
else if (message == "Reset";)
{
resetHUD() ;
}
else if (message == "Locate";)
{
llMoveToTarget(llList2Vector(Pos, CurItem), 0.05) ;
llSleep(0.25); //Prevents you from flying.
llStopMoveToTarget(); //Stops the movement
}
else if (message == "<--";)
{
CurItem-- ;
if (CurItem < 0) CurItem = ItemsCount - 1 ;
setCurrent() ;
}
else if (message == "-->";)
{
CurItem++ ;
if (CurItem >= ItemsCount) CurItem = 0 ;
setCurrent() ;
}
setTitle() ;
}
}
}

touch_start(integer total_number)
{
setTitle() ;
llListenControl(Handle, TRUE) ;
Listening = TRUE ;
}
}

Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
01-13-2010 08:52
one thing i would change after scanning thru this. instead of putting the name of the image in the notecard, i would use the actual uuid, then it doesn't have to be present in the vendor (unless the vendor itself needs it present) that will help with object content loading and reduce lag as well
_____________________
Dark Heart Emporium

http://www.xstreetsl.com/modules.php?name=Marketplace&MerchantID=133020

want more layers for tattoos, specifically for the head? vote here
http://jira.secondlife.com/browse/VWR-1449?

llDetectedCollision* Functions similar to touch
http://jira.secondlife.com/browse/SVC-3369
Astra Melody
Registered User
Join date: 5 Jan 2010
Posts: 10
01-13-2010 10:33
Hello Ruthven, this is an excellent idea! Though I think that new users would be confused with how to find the picture key, so I made a mix of our ideas.

I also modified the HUD menu to timeout after 60 seconds.
Indeterminate Schism
Registered User
Join date: 24 May 2008
Posts: 236
01-14-2010 09:47
The information in a sim is, relatively, static in that it only changes when a vendor does. It MAY be worth adding another object and script to act as a sim consolidator - this would hold the whole sim's data and would therefore be the only object that needed to communicate with the HUDs.

Possibly the easiest way to handle the consolidator without actually having the potentially very large amount of data in memory would be to copy the notecard from each vendor to the consolidator.
Astra Melody
Registered User
Join date: 5 Jan 2010
Posts: 10
01-14-2010 11:47
Hi Indeterminate, I like that idea because then the consolidator could send a particle ray to point at the vendor, which was my first intent.

Then it would be necessary to use a sensor (to find the vendor position) and take the vendor name from the notecard.

What I fail to see is how a single consolidator would handle an entire sim. Even if it could there would be too many items displayed in the HUD to be useful. Scanning a whole sim with sensors IS possible but it takes a lot of efforts, memory, and adds a lot of lag.

Several consolidators, placed every 30 meters for example could handle the vendors nearby, and point at them with a ray.

Actually I thought you could do that if you have really a lot of vendors in your sim, but I didn't think about the ray.

So what would change is adding the vendor name in the notecard, move the avatar to the consolidator, and have the consolidator send a ray to the vendor, yes?
Indeterminate Schism
Registered User
Join date: 24 May 2008
Posts: 236
01-14-2010 13:26
I was thinking of the vendors telling the consolidator their details, rather than it having to find them. Similarly the consolidator could filter any search results based on the current position of the HUD (identified from the request).
Astra Melody
Registered User
Join date: 5 Jan 2010
Posts: 10
01-14-2010 13:58
How would the HUD find the consolidator?
Indeterminate Schism
Registered User
Join date: 24 May 2008
Posts: 236
01-15-2010 06:24
Oookay, I'm not really commenting on your code, just thinking about options for how things could work in case they sound interesting. That being the case I haven't thought this all through, but I am thinking of something like this.

1. (Re) configure vendor
Vendor sends - llRegionSay(ChannelControl, "Consolidator?";);
Consolidator logs vendor UUID & position then sends - llRegionSay(ChannelControl, "Here";);
Vendor gets consolidator UUID from the listen event then - llGiveInventory(KeyConsolidator, NotecardConfig);

2. HUD search clicked
HUD sends - llRegionSay(ChannelControl, "Consolidator?";);
Consolidator logs HUD UUID & position then sends - llRegionsSay(ChannelControl, "Here";);
Consolidator checks vendor details & positions against searching HUD then emails results.
Astra Melody
Registered User
Join date: 5 Jan 2010
Posts: 10
01-15-2010 07:18
You are right, I forgot about Shout. That would not work exactly like this because of parcels and vendor position but it's interesting.