Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Trim button names for landmarks

Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
06-08-2009 20:26
Whoohoo! Thanks so much, I see what you mean - it needed a way to correlate the selection to the data - but I did not know how to accomplish a "tie-in". Wow and i tried it , Eureka! Now to try splitting and adding effects, and... and... :)

Going to have to study how you used "lmIdx = llListFindList(MENU2, (list) message)" , was not familiar with "llListFindList" function, at least I learn with the help you guys provide...
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-09-2009 16:57
From: Celty Westwick
Whoohoo! Thanks so much, I see what you mean - it needed a way to correlate the selection to the data - but I did not know how to accomplish a "tie-in". Wow and i tried it , Eureka! Now to try splitting and adding effects, and... and... :)

Going to have to study how you used "lmIdx = llListFindList(MENU2, (list) message)" , was not familiar with "llListFindList" function, at least I learn with the help you guys provide...

hehe now you're cooking with fire... find list is the heavy weight selection function of lsl (find substring is a close second) letting you compare random input to multiple criteria... and it's the (sometimes better, sometimes worse) replacement for "select case" (which doesn't exist in lsl)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-09-2009 17:08
I'm gonna play with it some more tonight also. It will be much more sim friendly if you do not rebuild the menus every time someone collides with the object. Create another user defined function with the menu creation in it instead and only call it from state entry and CHANGED_INVENTORY.

From: Void Singer
hehe now you're cooking with fire... find list is the heavy weight selection function of lsl (find substring is a close second) letting you compare random input to multiple criteria... and it's the (sometimes better, sometimes worse) replacement for "select case" (which doesn't exist in lsl)


I can not wait until he figures out strides :p Will be expecting many more questions fr*m you Celty and some day some answers too ;)
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
06-10-2009 17:48
LOL, well I already have a question. I started trying to figure out why in:

dataserver(key requestID, string data) {
if (requestID == LMid) {
LMid = NULL_KEY;
sim = llGetRegionName();

that the correct sim value works when it is used in "llMapDestination(sim, loc, loc);", however, if I do this:

dataserver(key requestID, string data) {
if (requestID == LMid) {
LMid = NULL_KEY;
sim = llGetRegionName();
llSay(0, sim);

The llSay returns the current sim name where the object is located. I had started on trying to pass the destination information to the second prim, something like:

llMessageLinked(LINK_ALL_OTHERS, fire_num, sim + data, NULL_KEY);

when i discovered it.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-10-2009 18:20
From: Celty Westwick
LOL, well I already have a question. I started trying to figure out why in:

dataserver(key requestID, string data) {
if (requestID == LMid) {
LMid = NULL_KEY;
sim = llGetRegionName();

that the correct sim value works when it is used in "llMapDestination(sim, loc, loc);", however, if I do this:

dataserver(key requestID, string data) {
if (requestID == LMid) {
LMid = NULL_KEY;
sim = llGetRegionName();
llSay(0, sim);

The llSay returns the current sim name where the object is located. I had started on trying to pass the destination information to the second prim, something like:

llMessageLinked(LINK_ALL_OTHERS, fire_num, sim + data, NULL_KEY);

when i discovered it.

That is the correct behavior. Try having it say the data returned. It will just be a large vector and if not in the same sim, some of the axes are going to be larger then 255. The value returned is the global location of the landmark and when you add this to the local sim it gives you the final TP destination.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-10-2009 18:27
And as I promised, I did play with it some more last night. Some here in the scripting forum believe that the best way to teach is by describing the action. While I learned here by people taking my script and either throwing it away completely and/or rewriting it the way they would do it. While both forms of instruction are correct, I much prefer the latter. Here is what I did to make the script friendlier for the sim it is in:

CODE

list MENU1;
list MENU2;
integer menuId;
integer lmIdx;
string sim;
vector loc;
integer i;
integer MyChannel;
integer listener;
key LMid;
key toucher;

integer randBetween(integer min, integer max){
return (integer) (llFrand((float) (max - min)) + min);
}

Dialog(key id, list menu){
llSetTimerEvent(30.0);
llDialog(id, "\nFloo Network \n\nChoose a destination", menu, MyChannel);
}

create_menus(){
integer numberOfLandmarks = llGetInventoryNumber(INVENTORY_LANDMARK);
i = 0;
MENU1 =[];
MENU2 =[];
if (numberOfLandmarks <= 12) {
for (; i < numberOfLandmarks; ++i){
MENU1 += llGetSubString(llGetInventoryName(INVENTORY_LANDMARK, i), 0, 12);
}
}
else {
for (; i < 11; ++i){
MENU1 += llGetSubString(llGetInventoryName(INVENTORY_LANDMARK, i), 0, 12);
}
if (numberOfLandmarks > 21)
numberOfLandmarks = 21;
for (; i < numberOfLandmarks; ++i){
MENU2 += llGetSubString(llGetInventoryName(INVENTORY_LANDMARK, i), 0, 12);
}
MENU1 += ">>";
MENU2 += "<";
}
}

init(){
LMid = llRequestInventoryData(llGetInventoryName(INVENTORY_LANDMARK, lmIdx));
}

default {
state_entry() {
llVolumeDetect(TRUE);
MyChannel = -randBetween(1, 100000);
create_menus();
}

on_rez(integer start_param) {
llResetScript();
}

collision_start(integer total_number) {
toucher = llDetectedKey(0);
listener = llListen(MyChannel, "", toucher, "");
Dialog(llDetectedKey(0), MENU1);
menuId = 1;
}

touch_start(integer total_number) {
llMapDestination(sim, loc, loc);
}

listen(integer channel, string name, key id, string message) {
if (channel == MyChannel) {
if (message == ">>") {
Dialog(id, MENU2);
menuId = 2;
}
else if (message == "<") {
Dialog(id, MENU1);
menuId = 1;
}
else {
if (menuId == 1) {
lmIdx = llListFindList(MENU1, (list) message);
}
else {
lmIdx = llListFindList(MENU2, (list) message) + 11;
}
init();
}
}
}

changed(integer change) {
if (change & CHANGED_INVENTORY || change & CHANGED_OWNER) {
llResetScript();
}
}

dataserver(key requestID, string data) {
if (requestID == LMid) {
sim = llGetRegionName();
loc = (vector) data;
}
}
timer() {
llListenRemove(listener);
}
}
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
06-10-2009 19:57
Jesse, it makes no sense to me, even though it is true, I had already noted the large numbers, but had thought perhaps it was a matter of precision. I need to check out the "global location", and why adding the local sim's name to it works, seems counter intuitive. If I am trying to relay that data in a linked message as in my previous post, then you are saying that combination should work, provided I figure out a way to parse it into the loc and sim variables in the receiving script?

I see what you meant, I think, in that you are saying the function is more efficient as it "pre-runs" in the beginning and re-runs if need due to a change, and is then available for use whenever needed by Dialog from the collision event.

It may be my imagination, but it seems to execute faster with the revised version in llMapDestination. As for strides, Oye! :)
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-10-2009 20:19
Just send the data as it is. As long as the receiving script has the name of the sim it is in and that vector data, llMapDestination will still work exactly the same. The only thing you will need to do in the receiving script is "cast" the message, which is a string, to a vector.

This might help a little bit. "Global coordinates are used to describe a position relative to one point on the entire Second Life world, hence the word "global". This means that every place on the grid has a different vector value when represented in global coordinates." Here is the wiki entry on the subject:

http://lslwiki.net/lslwiki/wakka.php?wakka=GlobalCoordinate

Create an LM for where you are at and drop into a prim and then put this script in there:
CODE

key LMid;
string sim;
vector vec;

default {
state_entry() {
LMid = llRequestInventoryData(llGetInventoryName(INVENTORY_LANDMARK, 0));
}
dataserver(key requestID, string data) {
vec = (vector) data;
llOwnerSay(data);
}
}


The vector given will be the coordinates for that sim and will match where you made the LM at. Now take that prim into inventory and TP to a different sim. Rez that same prim and reset the script inside and see what it says. It is going to be a totally different, much larger number now.

If it gets confusing just post what you have here and we will be glad to help you figure it out.

And it is executing faster because you are saving the execution time of building the menu lists every time.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
06-10-2009 22:58
From the Main Script:

dataserver(key requestID, string data)
{
if (requestID == LMid)
{
sim = llGetRegionName();
loc = (vector) data;
integer fire_num;
fire_num = 3;
llMessageLinked(LINK_ALL_OTHERS, fire_num, data, NULL_KEY);
}
}

From the touch event script:

CODE

integer fire_num = 3;
string sim;
vector loc;

default
{
state_entry()
{
}

on_rez(integer start_param)
{
llResetScript();
}

link_message(integer sender_num, integer num, string str, key id)
{
if ( num == fire_num )
{
llSay(0, str);
loc = (vector) str;
sim = llGetRegionName();
}
}

touch_start(integer total_number)
{
llMapDestination(sim, loc, loc);
}

changed(integer change)
{
if (change & CHANGED_OWNER)
{
llResetScript();
}
}
}


Yippee Yio Kiyaa! Oh and i did help someone inworld with a script tonight, a simple one, but hey ;)
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-11-2009 01:18
the sim name you feed to map destination, is the one it centers it's view on... not the one targeted, which is why it works either way. think of the large numbers as region coordinates, for regions as if they were local. (it's actually meters from the corner of the sim named "Da Boom" IIRC)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
06-11-2009 10:33
I was wondering where the 0 point was located for global coordinate, thanks Void.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-13-2009 03:34
because Iwas updating my own HUD landmark holder, everyone benefits... it's not quite what Celty was after (no dialogs), but it does do something fun... it works both as a hud (owner only/attached) and as a stand alone that anyone can use... and yes, it's a single script.

two versions, because I wanted to see how fast I could make it and how small by approaching the problem from different angles... I recommend the fast version, because the small version is not only slower, but uses more sim resources, and is more prone to outtages (slow responses from dataserver events)

I commented them quite liberally, but if any part is confusing, feel free to ask, I'll do my best to explain (they're both commented for learning, and little details of experience with lsl's weirdness.)

fast version
CODE

/*//-- v7-D Enhanced Landmark Mapper v1.1f --//*/

/*//-- Requirements:
3 linked Prims (minimum)
1 Named "prev" (this will be your previous landmark button)
1 Named "next" (this will be your next landmark button)
any other prim in the object will trigger the map destination for the
currently displayed Landmark name. Recommended to rename landmarks.
//*/

integer gIdxTgt; /*//-- Index of Target --//*/
list gLstLMs; /*//-- List of Landmarks --//*/
list gLstLoc; /*//-- Listt of Locations--//*/

key gKeySec; /*//-- Key for Security checking dataserver calls --//*/
float gFltTmt = 5.0; /*//-- Float for Timeout (dataserver calls & inventory changes) --//*/

default{
state_entry(){
llOwnerSay( "Rebuilding Database" );
gIdxTgt = llGetInventoryNumber( INVENTORY_LANDMARK );
/*//-- Grab Landmark Names For Display --//*/
if (gIdxTgt){
while(gIdxTgt){
gLstLMs = (list)llGetInventoryName( INVENTORY_LANDMARK, --gIdxTgt ) + gLstLMs;
}
/*//-- Get First LM Location --//*/
gKeySec = llRequestInventoryData( llList2String( gLstLMs, gIdxTgt = (gLstLMs != []) - 1 ) );
/*//-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
/*//-- negative indices would've been nice if they were supported by the Req.Inv.Data call --//*/
llSetTimerEvent( gFltTmt );
}
else{
gLstLMs = (list)"Out Of Order, No Landmarks Present";
gLstLoc = (list)<128.0, 128.0, 0.0>;
state sReady;
}
}

dataserver( key vKeySec, string vStrLoc ){
/*//-- verify we're getting our data, not another scripts --//*/
if (gKeySec == vKeySec){
/*//-- Store Location Vector --//*/
gLstLoc = (list)(llGetRegionCorner() + (vector)vStrLoc) + gLstLoc;
/*//-- Add Region Corner (Because Returned Vector Is An Offset From Current Sim) to make it Global --//*/
if (gIdxTgt){
/*//-- Get Next LM Location --//*/
gKeySec = llRequestInventoryData( llList2String( gLstLMs, --gIdxTgt ) );
llSetTimerEvent( gFltTmt );
}
else{
/*//-- Clear Timeout Because Timers Cross States --//*/
llSetTimerEvent( 0.0 );
state sReady;
}
}
}

timer(){
llOwnerSay( "Dataserver Response Timed Out, auto retry in " + (string)((integer)gFltTmt) + " seconds" );
llSleep( gFltTmt );
llResetScript();
}

state_exit(){
/*//-- Set The Initial Display --//*/
llSetText( llList2String( gLstLMs, gIdxTgt ), <1.0, 0.0, 0.0>, 1.0 );
llOwnerSay( "Ready" );
}
}

state sReady{
touch_start( integer vInt ){
/*//-- Check if a prim named "prev" or "next" was touched --//*/
integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
if (~vIntTst){
/*//-- Up.date Index Target --//*/
gIdxTgt += ((vIntTst > 0) - (vIntTst == 0));
/*//-- ((vIntTst > 0) - (vIntTst == 0)) same as: -1 for "prev", +1 for "next" --//*/

/*//-- Up.date Display --//*/
llSetText( llList2String( gLstLMs, (gIdxTgt %= (gLstLMs != [])) ), <0.0, 1.0, 0.0>, 1.0 );
/*//-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
/*//-- "gInCnt %= " allows us to wrap our references so they don't go out of range --//*/
}
else{
/*//-- Trigger map for any other touched prim in this object --//*/
llMapDestination( llGetRegionName(), llList2Vector( gLstLoc, gIdxTgt ) - llGetRegionCorner(), ZERO_VECTOR );
/*//-- sub.tract Region Corner to get the offset from current reigon that map dest. wants --//*/
}
}

changed( integer vBitChg ){
if (vBitChg & CHANGED_INVENTORY){
/*//-- give the user more time to add new LMs before we recompile our database lists. --//*/
/*//-- We could check the count too, but don't in _case the _change was a _change of name --//*/
llSetTimerEvent( gFltTmt );
}
}

timer(){
llResetScript();
}
}

/*//-- License Text:
Free to copy, use, modify, distribute, or sell, with attribution.
(C)2009 (CC-BY) [http://creativecommons.org/licenses/by/3.0]
Void Singer [https://wiki.secondlife.com/wiki/User:Void_Singer]
All usages must contain a plain text copy of the previous 2 lines.
//*/


small version
CODE

/*//-- v7-D Enhanced Landmark Mapper v1.1s --//*/

/*//-- Requirements:
3 linked Prims (minimum)
1 Named "prev" (this will be your previous landmark button)
1 Named "next" (this will be your next landmark button)
any other prim in the object will trigger the map destination for the
currently displayed Landmark name. Recommended to rename landmarks.
//*/

integer gIdxTgt; /*//-- Index of Target LM --//*/
string gStrLMN; /*//-- String of Landmark Name --//*/
vector gPosLoc; /*//-- Position of Location --//*/
key gKeySec; /*//-- Key for Security checking dataserver calls --//*/

uUpdateLM( integer vIntCng ){
integer vIntCnt = llGetInventoryNumber( INVENTORY_LANDMARK );
if (vIntCnt){
gIdxTgt = gIdxTgt = (vIntCnt + (gIdxTgt + vIntCng)) % vIntCnt;
/*//-- " + vIntCnt" correct for positive index needed by Req.Inv.Dat. --//*/
/*//-- " % vIntCnt" range limit for current LM count --//*/
gStrLMN = llGetInventoryName( INVENTORY_LANDMARK, gIdxTgt *= (gIdxTgt >= 0) );
/*//-- (gIdxTgt >= 0) to protect against mass deletions of LMs enabling negative indices --//*/
gKeySec = llRequestInventoryData( gStrLMN );
llSetTimerEvent( 5.0 );
}
else{
/*//-- Uh Oh, set a default of current sim, center, ground level --//*/
llSetText( "Out Of Order, No Landmarks Present", <1.0, 0.0, 0.0>, 1.0 );
gPosLoc = <128.0, 128.0, 0.0>;
}
}

default{
state_entry(){
uUpdateLM( 0 );
}

dataserver( key vKeySec, string vStrLoc ){
/*//-- verify we're getting our data, not another scripts --//*/
if (gKeySec == vKeySec){
/*//-- Clear the timeout --//*/
llSetTimerEvent( 0.0 );
/*//-- Store/Display New Target --//*/
gPosLoc = (vector)vStrLoc;
llSetText( gStrLMN, <1.0, 0.0, 0.0>, 1.0 );
}
}

touch_start( integer vInt ){
/*//-- Check if a prim named "prev" or "next" was touched --//*/
integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
if (~vIntTst){
uUpdateLM( (vIntTst > 0) - (vIntTst == 0) );
}
else{
/*//-- Trigger map for any other touched prim in this object --//*/
llMapDestination( llGetRegionName(), gPosLoc, ZERO_VECTOR );
}
}

timer(){
llOwnerSay( "Dataserver Response Timed Out. Unable To Change Destination; Try Again In A Moment" );
/*//-- Clear the key so we don't _update when it might interfere with a user --//*/
gKeySec = "";
}
}

/*//-- License Text:
Free to copy, use, modify, distribute, or sell, with attribution.
(C)2009 (CC-BY) [http://creativecommons.org/licenses/by/3.0]
Void Singer [https://wiki.secondlife.com/wiki/User:Void_Singer]
All usages must contain a plain text copy of the previous 2 lines.
//*/
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
06-15-2009 12:52
Very interesting code :) , will take me awhile to understand I think, for me "next" prim works but "prev" prim does not.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-16-2009 05:29
From: Celty Westwick
Very interesting code :) , will take me awhile to understand I think, for me "next" prim works but "prev" prim does not.

made some boo-boos (just be glad you didn't attempt it as a hud, I forgot a major detail of LSL stupidity that makes the first version fail to behave correctly on any but the sim it reads the landmarks on originally)

EDIT:
above is now fixed... the prev button was just a matter of using the wrong test (changed my mind halfway through writing it, was supposed to be 1 originally, went with 0 in the end.)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
1 2