|
Shifting Dreamscape
Always questioning ...
Join date: 12 Dec 2007
Posts: 266
|
04-18-2008 23:58
Is there any know issue with SL reordering list variables in scripts? Let me explain... I have the following code that loads a set of variables (this is actually a trimmed down version to avoid the complications of the rest of the script. The basic idea is that i need to group a series of prims (windows) to be later able to set their values when the user decides to. Each group (room) can have a number of windows in it, each with their own set of values: <php> ... //The window will call passing a long data string in message //These are the values associated with the window seperated by a @ //Pare out the data dataList = llParseString2List(message, ["@"],[""]); //Find the next position in the datasets .. this just sees how many //elements there are in the linknum list as there is one for each room newIndex = llGetListLength(gWindowLinkNum); //Get the room name from the list windowName = llList2String(dataList,0); //Check if room name already in List index = llListFindList(gWindowOptions, [windowName]); if ( index != -1) { //Already in the list so we add to the variable there the next available index //number .. this will point to the position in the lists for the window stored values linkList = llList2String(gListPosit, index) + "@" + (string)newIndex; gListPosit = llListReplaceList(gListPosit, [linkList], index, index); } else { //Create new entry in the base lists gWindowOptions = gWindowOptions + [windowName]; gListPosit = gListPosit + [(string)newIndex]; } //Then Store the Data .. the index of each of the following values should be the same ... //it means that we can then recuperate the index values for a particular room gWindowLinkNum = (gWindowLinkNum=[]) + gWindowLinkNum + [(string)linkId]; gInFace = (gInFace=[]) + gInFace + [inFace]; gInColor = (gInColor=[]) + gInColor + [(vector)llList2String(dataList,2)]; gInText = (gInText=[]) + gInText + llList2List(dataList, 3, 3); ... </php> Then the basic code used to retrieve the data is as follows: <php> ... integer quit = 0; integer listLen = llGetListLength(gListPosit); //Now call the windows while (quit == 0 && i < listLen) { //For each element in the list of rooms ... check to see if this is the same as the one selected from the //Dialog ... or we are doing all if (llList2String(gWindowOptions, i) == gWinSelected || gWinSelected == "All"  { //Need to Split out the List Positions Ids .. the indexs of windows associated with //this room indexList = llParseString2List(llList2String(gListPosit, i),["@"],[""]); indexLen = llGetListLength(indexList); //Now for each window associated with the room for (x = 0; x < indexLen; x++) { //get the index in the data lists associated index = llList2Integer(indexList, x); //get the pertinent values .. link of the window first linkNum = llList2Integer(gWindowLinkNum, index); llSetLinkTexture(linkNum, llList2String(gInText, index), faceWork) ... </php> So .. if you have hung on this long I am sure you are asking when I'll get to the problem. Well after finally getting the earlier kinks worked out I had this installed and configured and working, each window across the three rooms was getting its proper texture. I then went away for about an hour or so and came back later with a friend to show them the house, and suddenly the textures being set were off. And it wasn't that just the rooms were being mixed up, it was that the windows were being crossed across rooms, i.e. if when setup, Room A contained windows 1-4 and Room B Windows 5-8, now when selecting to set room C, windows 1,5,6,7 were being set. So it appears that some of the lists have been reordered. Is this a known issue in SL? Is there a work around? Thanks!
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
04-19-2008 05:36
The code you have looks good on the face which makes me think you are corrupting the data elsewhere.
You may want to consider using pipe "|" as your separator since it can't appear in asset names.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
04-19-2008 06:55
Haven't heard of any problems and I use some really heavy multiple lists manipulations in my teleport hud with no problems. Click on the link in my sig and take a look at the teleport hud script. You will see that I used strides which might come in handy for what you are doing. This would allow for a master list like so: list main = ["roomA","window1","roomB","window3","roomA","window2","roomC","window6", "roomB","window8","roomA","window4","roomD","window7","roomB","window5"];
default { touch_start(integer total_number) { main = llListSort(main,2,1); integer start = llListFindList(main,["roomB"]); integer end = llListFindList(main,["roomC"]); list room = llList2List(main,start,end - 1); list windows = llList2ListStrided(main,start,end - 1,2); llOwnerSay(llDumpList2String(room, ",")); llOwnerSay(llDumpList2String(windows, ","));
} }
returns this output: "temp2: roomB,window8,roomB,window3,roomB,window5 temp2: window8,window3,window5" If I completely missed it in this answer then you could post the whole code and we will give it a look and help spot the problem.
_____________________
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
|
|
Shifting Dreamscape
Always questioning ...
Join date: 12 Dec 2007
Posts: 266
|
04-19-2008 07:17
Strife - I thought at first that I could be corrupting but once the lists are set up during the configuration process they do not get modified again. And as I said at one point they were correct.
Jesse - I'll take a look at the script. Thouhgt about using stride .. but my lists ae created dynamically and could get longer than the max allowed.
|
|
Shifting Dreamscape
Always questioning ...
Join date: 12 Dec 2007
Posts: 266
|
04-19-2008 07:17
Here is the whole origianl code ... // // Window Tint Controller Script (put into controller prim) // // ******************************************************************* // This program is free software; you can redistribute it and/or // modify as you wish. Just don't try and sell it to someone ... // that would not be nice or fair. // If you have paid someone for this script .. contact me and we'll // track them down inworld and harass them ;-) // // While I do not offer support for this script if you have questions // feel free to contact me inworld. // // Writen by Shifting Dreamscape // *******************************************************************
//Parameter Notecard string DATA_NOTECARD = "control_data_params"; //Notecard read integer gLine; key gParamData;
//Values from Param Notecard //Dialog Channel to listen on integer DIALOG_CHAN;//dialog_channel //Chat Channel To Listen to integer RESET_CHAN;//windowcontrol_chat_channel //Channel the window scripts listen on integer WINDOW_SET_CHAN;//window_comm_channel //DataLink 'channel' integer DATA_CHAN;//window_data_channel //Link channels 'listened' to integer INDIVID_CHAN;//window_individ integer GROUP_CHAN;//window_group //ID of the controller string CTRL_ID; //End Parameter Variables
//The % to Tint the window list TINT_OPTIONS = ["40%", "20%", "None", "100%", "80%", "60%"]; //Side of the Window to Tint list SIDE_OPTIONS = ["Outside", "Inside", "Both"];
//Identifiers for the different dialog boxes integer NO_DIALOG = 0; integer CHECK_WINDOW = 1; integer CHECK_TINT = 2; integer CHECK_SIDE = 3;
//Variable set when a window is chosen string gWinSelected; //Holds the Tint level Chosen float gMsgTint; //Holds the side of the window to tint string gSideModifier; //Holds which Dialog was last shown integer gCurDialog;
//List of Window names list gWindowOptions;
//Holds the index positions for a winodw or window group list gListPosit;
//Data Lists list gWindowLinkNum; list gInFace; list gInColor; list gInText; list gIn100Color; list gIn100Text; list gOutFace; list gOutColor; list gOutText; list gOut100Color; list gOut100Text;
//Temporary Data lists list gTempWindowOptions; list gTempListPosit; list gTempWindowLinkNum; list gTempInFace; list gTempInColor; list gTempInText; list gTempIn100Color; list gTempIn100Text; list gTempOutFace; list gTempOutColor; list gTempOutText; list gTempOut100Color; list gTempOut100Text;
//Listener Handle integer gListenHandle;
//Functions integer call_windows() { integer i = 0; integer x = 0; integer quit = 0; integer listLen = llGetListLength(gListPosit); list indexList; integer indexLen; integer index; integer linkNum; integer faceWork; string sText; string message; //Now call the windows while (quit == 0 && i < listLen) { if (llList2String(gWindowOptions, i) == gWinSelected || gWinSelected == "All") { //Need to Split out the List Positions Ids indexList = llParseString2List(llList2String(gListPosit, i),["@"],[""]); indexLen = llGetListLength(indexList); for (x = 0; x < indexLen; x++) { index = llList2Integer(indexList, x); linkNum = llList2Integer(gWindowLinkNum, index);
//Check for a negative Link ID .. this means that it is an unlinked window if (linkNum < 0) { //Send ... WinControlID, SideMod, Tint .. The window has stored its texture/color values message = CTRL_ID + "@" + gSideModifier + "@" + (string)gMsgTint; llRegionSay(linkNum, message); } else {
//Check for each side if (gSideModifier != "Inside") { faceWork = llList2Integer(gOutFace, index);
//Now depending on the Tint % we set one color or other if (gMsgTint == 1) { //Only do this if we really have a texture ... a none will be here if not sText = llList2String(gOut100Text, index); if (sText != "non") { llSetLinkColor(linkNum, llList2Vector(gOut100Color, index), faceWork); llSetLinkTexture(linkNum, llList2String(gOut100Text, index), faceWork); } } else { llSetLinkColor(linkNum, llList2Vector(gOutColor, index), faceWork); llSetLinkTexture(linkNum, llList2String(gOutText, index), faceWork); } llSetLinkAlpha(linkNum, gMsgTint, faceWork); } if (gSideModifier != "Outside") { faceWork = llList2Integer(gInFace, index);
//Now depending on the Tint % we set one color or other if (gMsgTint == 1) { //Only do this if we really have a texture ... a none will be here if not sText = llList2String(gOut100Text, index); if (sText != "non") { llSetLinkColor(linkNum, llList2Vector(gOut100Color, index), faceWork); llSetLinkTexture(linkNum, llList2String(gOut100Text, index), faceWork); } } else { llSetLinkColor(linkNum, llList2Vector(gInColor, index), faceWork); llSetLinkTexture(linkNum, llList2String(gInText, index), faceWork); } llSetLinkAlpha(linkNum, gMsgTint, faceWork); } } } if (gWinSelected != "All") { quit = 1; } } i++; } return 0; }//End call_windows
//Body default { state_entry() { //Initialize Window Options to null gWindowOptions = ["Set"]; //Read in from the notecard my data gLine = 0; gParamData = llGetNotecardLine(DATA_NOTECARD, gLine); } // end state_entry()
dataserver(key requested, string data) { list dataPair; string dataKey; string dataValue;
if (requested == gParamData && data != EOF) { if (llGetSubString(data, 0, 1) != "//" && data != "") { dataPair = llParseString2List(data, ["="], [""]); dataKey = llList2String(dataPair, 0); dataValue = llList2String(dataPair, 1);
if (dataKey == "dialog_channel") { DIALOG_CHAN = (integer)dataValue; } else if (dataKey == "windowcontrol_chat_channel") { RESET_CHAN = (integer)dataValue; } else if (dataKey == "window_comm_channel") { WINDOW_SET_CHAN = (integer)dataValue; } else if (dataKey == "window_data_channel") { DATA_CHAN = (integer)dataValue; } else if (dataKey == "window_individ") { INDIVID_CHAN = (integer)dataValue; } else if (dataKey == "window_group") { GROUP_CHAN = (integer)dataValue; } else if (dataKey == "window_control_id") { CTRL_ID = dataValue; } } ++gLine; gParamData = llGetNotecardLine(DATA_NOTECARD, gLine); } }//End dataserver
link_message(integer sender_number, integer channel, string message, key id) { list dataList; integer index; integer newIndex; integer linkId; integer inFace; string linkList; string tint; string windowName;
if (channel == INDIVID_CHAN) { llDialog(id, "Which window would you like to tint?", gWindowOptions, DIALOG_CHAN); //Start Listening gListenHandle = llListen(DIALOG_CHAN, "", NULL_KEY, ""); //Set Timer to Turn off this channel in case the user does nto go all the way through llSetTimerEvent(60.0); //Flag for what dialog is visible gCurDialog = CHECK_WINDOW; } else if (channel == GROUP_CHAN) { gWinSelected = "All"; dataList = llParseString2List(message, ["@"], [""]); //Change the tint value to a number if (llList2String(dataList, 0) == "None") { gMsgTint = 0; } else { tint = llList2String(dataList, 0); gMsgTint = (float)llGetSubString(tint, 0, llStringLength(tint)-2)/100; } gSideModifier = llList2String(dataList, 1); call_windows(); } else if (channel == DATA_CHAN) { //The window will call passing a long data string in message //The structure is name, inside face, color, texture, the the outside values //each value seperated by the @ symbol //All the data will be just appended to the end of the various lists //The new list position will be added to a @ seperated string that holds //the same position in its list as the window name dataList = llParseString2List(message, ["@"],[""]);
//Next Position in the data sets newIndex = llGetListLength(gTempWindowLinkNum); windowName = llList2String(dataList,0); //Check if window name already in List index = llListFindList(gTempWindowOptions, [windowName]); if ( index != -1) { linkList = llList2String(gTempListPosit, index) + "@" + (string)newIndex; gTempListPosit = llListReplaceList(gTempListPosit, [linkList], index, index); } else { //Create new entry gTempWindowOptions = gTempWindowOptions + [windowName]; gTempListPosit = gTempListPosit + [(string)newIndex]; } //Then Store the Data //First check the inface value .. if negative we are working with an unlinked window //and the value in inface needs to be used for linknum inFace = llList2Integer(dataList, 1); if (inFace < 0) { linkId = inFace; } else { linkId = sender_number; } gTempWindowLinkNum = (gTempWindowLinkNum=[]) + gTempWindowLinkNum + [(string)linkId]; gTempInFace = (gTempInFace=[]) + gTempInFace + [inFace]; gTempInColor = (gTempInColor=[]) + gTempInColor + [(vector)llList2String(dataList,2)]; gTempInText = (gTempInText=[]) + gTempInText + llList2List(dataList, 3, 3); gTempIn100Color = (gTempIn100Color=[]) + gTempIn100Color + [(vector)llList2String(dataList,4)]; gTempIn100Text = (gTempIn100Text=[]) + gTempIn100Text + llList2List(dataList, 5, 5); gTempOutFace = (gTempOutFace=[]) + gTempOutFace + llList2List(dataList, 6, 6); gTempOutColor = (gTempOutColor=[]) + gTempOutColor + [(vector)llList2String(dataList,7)]; gTempOutText = (gTempOutText=[]) + gTempOutText + llList2List(dataList, 8, 8); gTempOut100Color = (gTempOut100Color=[]) + gTempOut100Color + [(vector)llList2String(dataList,9)]; gTempOut100Text = (gTempOut100Text=[]) + gTempOut100Text + llList2List(dataList, 10, 10); } }//End link_message
listen(integer channel, string name, key id, string message) { //Which Channel?? if (channel == RESET_CHAN) { if (message == "Done") { llSetTimerEvent(0.0); //we close out the list with all and reset gTempWindowOptions = gTempWindowOptions + ["All", "Reset"]; llListenRemove(gListenHandle); llSay(0, "To remove the scripts from the windows simply say 'Die' on channel " + (string)WINDOW_SET_CHAN); llMessageLinked(LINK_ALL_OTHERS, 0, "Done", NULL_KEY);
//Finally update the storage variables gWindowOptions = gTempWindowOptions; gListPosit = gTempListPosit; gWindowLinkNum = gTempWindowLinkNum; gInFace = gTempInFace; gInColor = gTempInColor; gInText = gTempInText; gIn100Color = gTempIn100Color; gIn100Text = gTempIn100Text; gOutFace = gTempOutFace; gOutColor = gTempOutColor; gOutText = gTempOutText; gOut100Color = gTempOut100Color; gOut100Text = gTempOut100Text; gTempWindowOptions = []; gTempListPosit = []; gTempWindowLinkNum = []; gTempInFace = []; gTempInColor = []; gTempInText = []; gTempIn100Color = []; gTempIn100Text = []; gTempOutFace = []; gTempOutColor = []; gTempOutText = []; gTempOut100Color = []; gTempOut100Text = []; } else if (message == "Cancel") { //Stop the timer and Listener llSetTimerEvent(0.0); llListenRemove(gListenHandle); llSay(0, "To remove the scripts from the windows simply say 'Die' on channel " + (string)WINDOW_SET_CHAN);
//Clear the temp lists gTempWindowOptions = []; gTempListPosit = []; gTempWindowLinkNum = []; gTempInFace = []; gTempInColor = []; gTempInText = []; gTempIn100Color = []; gTempIn100Text = []; gTempOutFace = []; gTempOutColor = []; gTempOutText = []; gTempOut100Color = []; gTempOut100Text = []; } } else if (channel == DIALOG_CHAN) { //First Check if we are setting/resetting the windows ... if (message == "Reset" || message == "Set") { //Each window to be set needs a script ... //The user touches the window ... Texture will change to numbers ... //user says on window channel inside#@outside# then clicks again //window resets scripts and passes data to contoller
llSay(0, "Touch each window to control, when the texture changes, "); llSay(0, "say on channel " + (string)WINDOW_SET_CHAN + " the inside # followed by"); llSay(0, "the @ symbol, followed by the outside #. Then touch the window again."); llSay(0, "Repeat the process for all windows, saying 'Done' on channel " + (string)RESET_CHAN + " when complete."); llSay(0, "At anytime you may say 'Cancel' on channel " + (string)RESET_CHAN + " to stop the process.");
//Advise all the windows with the set script the linkid of this prim llRegionSay(WINDOW_SET_CHAN, "link" + (string)llGetLinkNumber()); //Set up to Listen on reset channel, stoping the nomal Channel llListenRemove(gListenHandle); gListenHandle = llListen(RESET_CHAN,"",NULL_KEY,"");
//Set Timer to Turn off this channel if the user doesnt do anything .. llSetTimerEvent(0); llSetTimerEvent(1200.0); } else if (gCurDialog == CHECK_WINDOW) { //Hold the option selected gWinSelected = message;
//Now Ask for the Tint .. setting the the proper dialog gCurDialog = CHECK_TINT; llDialog(id, "How much tint would you like?", TINT_OPTIONS, DIALOG_CHAN); } else if (gCurDialog == CHECK_TINT) { //Change the message into a number and hold it if (message == "None") { gMsgTint = 0; } else { gMsgTint = (float)llGetSubString(message, 0, llStringLength(message)-2)/100; }
//Set Next Dialog and show gCurDialog = CHECK_SIDE; llDialog(id, "Which sides would you like to tint?", SIDE_OPTIONS, DIALOG_CHAN); } else if (gCurDialog == CHECK_SIDE) { //Now we start tinting!!! gCurDialog = NO_DIALOG; //Stop Listening for the dialog llSetTimerEvent(0.0); llListenRemove(gListenHandle);
//Hold the sid modifier gSideModifier = message; call_windows(); } } } // end listen
timer() { //We have timed out .... llSetTimerEvent(0.0); llListenRemove(gListenHandle); gCurDialog = NO_DIALOG;
}//End timer } // end default //
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
04-19-2008 19:05
I went over the script pretty good and I can't find anything that could possibly "change" the list orders. Am wondering why you did this bit thou: llListenRemove(gListenHandle); gListenHandle = llListen(RESET_CHAN, "", NULL_KEY, ""  ; llSetTimerEvent(0); llSetTimerEvent(1200.0) You changed from DIALOG_CHAN to RESET_CHAN but then removed the RESET_CHAN listen by calling llSetTimerEvent(0); but then recalled the timer event again with; llSetTimerEvent(1200.0)? Other then that you are probably going to have to debug with llOwnerSay everywhere is the problem happens again. And wouldn't hurt to put a script out that will llOwnerSay everything on the channels you have chosen to make sure someone else isn't using one. BTW, nice job on your coding, readable and neat!
_____________________
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
|
|
Shifting Dreamscape
Always questioning ...
Join date: 12 Dec 2007
Posts: 266
|
04-21-2008 01:32
Jesse ... first off it now seems to be working ... reconfigured and no errors for the last day .. am going to watch to see if it happens again .. but must have been a glitch in SL.
As to the timer ... at least from what I've read in the documentation, setting to 0 removes any prior set Timer events, not causing the event to occur. Then I reset it so that there is time to configure the windows. Is that not correct?
|