Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
Survey Survey_1  

Survey_1

Survey 1.lsl

Category: Survey
By : Eloise Pasteur
Created: 2010-01-10 Edited: 2010-01-10
Worlds: Second Life

the Zip file

Download all files for Survey_1
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. Survey_1_1.lsl
1
2 //=============================================================
3 //SL SURVEY, 1.1
4 //Gathers survey responses via dialog, emails results from Second Life
5 //Copyright (C) 2006 Eloise Pasteur and Jeremy Kemp
6 //=============================================================
7 //SETTING UP THE OBJECT ===============
8 //Create an object, its name will be the "From" field in the results email
9 //Include the script and a questions notecard
10 //The notecard name will be listed in the body of the results email
11 //Enter questions on one line, answers on the next, alternating lines
12 //Denote separate options in the answer line with a | pipe character
13 //You may need to fiddle a little with the order of your answers - there is no way to automatically adjust them irrespective of the number of answers you have that will also allow you to ask a reasonable number of questions. The dialog box displays as follows:
14 //10, 11, 12
15 //7, 8, 9
16 //4, 5, 6
17 //1, 2, 3
18 //Example:
19 //What color is the sky?
20 //blue|orange|green|red
21 //This will display the answers as:
22 //red
23 //blue, orange, green
24 //On the buttons.
25
26 //No line can be more than 255 characters
27 //Answers are truncated at 8 characters - they can be up to 24 characters but there is only space for 8 characters to display on the buttons.
28
29 //LAUNCHING THE SURVEY ===============
30 //Upon resing, the script will request an email address for results - or you can enter your email directly into the script in the first non-orange line below in the format string address="example@aol.com";
31 //The script will take longer to setup with more questions
32 //Changes to the card after a survey is started require a manual reset of the script
33
34 string address; //The email address. email is a restricted word in lsl - it's an event name. - if you don't want to set these each time you can enter your email directly here - the script will automatically adjust and not ask you for your email.
35 integer pointer=0; //Where we are in the various cycles - reading notecards, asking questions etc.
36 list questions; //The questions we've read in
37 list answers; //The answers in raw form (still in one string per answer set)
38 integer listenID; //So we can turn listeners on and off - less lag that way.
39 key owner; //So I can listen to only the owner, and potentially add some admin functions off a touch (not implemented but the code is there).
40 integer chan; //Channel for the silent email registration - required in state_entry AND listen, hence a global.
41 string card; //Name of the notecard you're using.
42 key questionnaire; //Key of the person taking the questionnaire
43 string totalq; //Total number of questions
44 string responses; //The actual answers given, plus querent's name and card name.
45 float timePerQuestion=60.0; //Although there is a sensor to detect crashed etc. people it's not 100% reliable according to some. This lets you set a time (in seconds) per question (so it's currently 1 minute per question) so that if they take too long they time out. For tricky questions you might want to have some more time...
46
47
48 setQuestions() //A function - we need to access this from a couple of places, hence putting it in as a function
49 {
50 string question=llList2String(questions, pointer); //Raw question
51 question=llDumpList2String(llParseString2List(question, ["|"], []), "\n"); //Swaps | for /n (new line)
52 if(llStringLength(question)!=0)
53 {
54 llDialog(questionnaire, question, llParseString2List(llList2String(answers, pointer), ["|"], []), -1001); //Asks the questions in a dialog box.
55 }
56 }
57
58 default //Set everything up
59 {
61 {
62 llSetText("Setting up", <1.0, 1.0, 1.0>, 1.0); //Show what we're doing.
63 owner=llGetOwner(); //Grab the owner's key for lower down
64 //chan=(integer)("0x"+llGetSubString((string)owner, 0, 1)); //Set up a channel (not 0) based on the key (1-255) so there's silent entry.
65 if(address=="") //They've not entered their email address in the script.
66 {
67 chan=0;
68 listenID=llListen(0, "", llGetOwner(), ""); //Listen only to the owner as well.
69 llOwnerSay("To what email shall I send responses?"); //Tell them what to say - revised for v0.9.3
70 } else
71 {
72 if(llGetInventoryNumber(INVENTORY_NOTECARD)!=1) //there's not 1 notecard, so I'm not sure which one to use. Complain!
73 {
74 llOwnerSay("You must put exactly one card in me with the questions and answers on it before I can set up!"); //Complain politely...
75 } else //There is only one, so we'll assume (however rashly) it's the right one.
76 {
77 card=llGetInventoryName(INVENTORY_NOTECARD, 0); //Get the card's name
78 pointer=0; //reset the pointer (this is paranoia, but it doesn't hurt)
79 llGetNotecardLine(card, pointer); //Start reading the card (handled in the dataserver event).
80 }
81 }
82 }
83 listen(integer cha, string name, key id, string msg) //Listen event - grab their details and make sure it's all OK.
84 {
85 if(cha==chan)
86 {
87 address=msg;
88 llListenRemove(listenID); //Tidy up the listen, just in case.
89 listenID=llListen(-1001, "", owner, "");
90 llDialog(owner, "The email address for results is "+msg+". Is that correct?", ["Yes", "No"], -1001); //Check the email address is right
91 } else if(cha=-1001)
92 {
93 if(msg=="Yes") //Email is OK, so...
94 {
95 llListenRemove(listenID);
96 if(llGetInventoryNumber(INVENTORY_NOTECARD)!=1) //there's not 1 notecard, so I'm not sure which one to use. Complain!
97 {
98 llOwnerSay("You must put exactly one card in me with the questions and answers on it before I can set up!"); //Complain politely...
99 } else //There is only one, so we'll assume (however rashly) it's the right one.
100 {
101 card=llGetInventoryName(INVENTORY_NOTECARD, 0); //Get the card's name
102 pointer=0; //reset the pointer (this is paranoia, but it doesn't hurt)
103 llGetNotecardLine(card, pointer); //Start reading the card (handled in the dataserver event).
104 }
105 } else //They put their email address in wrong
106 {
107 llResetScript(); //Well we've not really done anything. We could cycle back to ask again if we'd done more.
108 }
109 }
110 }
111 dataserver(key id, string data) //This handles various things - this time it's reading data from a notecard.
112 {
113 if(data!=EOF) //It's real data, not the end of the file.
114 {
115 if(llStringLength(data)==0)
116 {
117 llSay(0, "CAUTION! Line "+(string)pointer+"of the notecard is blank! This may cause errors, questions to display out of sync with their answers etc.");
118 }
119 if(pointer%2) //is it an odd numbered line
120 {
121 answers+=data; //if so, it's an answer line
122 } else
123 {
124 questions+=data; //else it's even (0 first remember) - so it's a question
125 }
126 pointer++; //Advance the pointer
127 llGetNotecardLine(card, pointer); //Get the next line.
128 } else //It IS the end of the file, so we've grabbed it all...
129 {
130 totalq=(string)llGetListLength(questions); //Get the number of questions
131 state ready; //Go into a ready state, so we can take answers.
132 }
133 }
134 changed(integer change)
135 {
136 if((change & CHANGED_OWNER) || (change & CHANGED_INVENTORY)) //They've changed the contents, or the owner, so reset it - probably a new card after all.
137 {
139 }
140 }
141 }
142
143 state ready //Waiting for victims to answer questions.
144 {
146 {
147 llSetText("Touch to start survey\n"+card+" - "+totalq+" ?s.", <0.0, 1.0, 0.0>, 1.0); //Tell punters what to do
148 }
149 changed(integer change)
150 {
151 if((change & CHANGED_OWNER) || (change & CHANGED_INVENTORY)) //They've changed the contents, or the owner, so reset it - probably a new card after all.
152 {
154 }
155 }
156 touch_start(integer num) //Process the touch
157 {
158 key temp=llDetectedKey(0);
159 if(temp==owner) //No admin built in, but it's available as an option
160 {
161 //offer some options
162 questionnaire=temp;
163 state running;
164 } else //It's a punter - start the questionnaire.
165 {
166 questionnaire=temp;
167 state running;
168 }
169 }
170 }
171
172 state running //We're actually asking questions
173 {
175 {
176 llSetTimerEvent(timePerQuestion * (float)totalq); //This is a timer to clean up people that don't finish but the sensor doesn't catch for some reason.
177 llSetText(llKey2Name(questionnaire)+" is taking the questionnaire, please wait!", <0.0, 0.0, 1.0>, 1.0); //Tell the world so!
178 listenID=llListen(-1001, "", questionnaire, ""); //Only listen to the answers, stops spamming
179 llSensorRepeat("", questionnaire, AGENT, 60, PI, 30.0); //Keep checking they're still there - they might have got bored and wondered off, crashed etc.
180 pointer=0; //reset the pointer (recycling variables is good)
181 setQuestions(); //Ask the first question (see function above)
182 }
183 listen(integer chan, string name, key id, string msg) //Listen for the answers.
184 {
185 if(pointer==0) //First answer, so say what's happening.
186 {
187 responses=name+"'s answers to the questionnaire on notecard "+card+".\n";
188 }
189 responses+="Q"+(string)(pointer+1)+": "+msg+"\n"; //Add their answer to this question to the email.
190 pointer++;
191 if(pointer==(integer)totalq) //Got to last question.
192 {
193 llSay(0, "Thank you for taking this questionnaire. Please wait whilst I send the results before starting."); //Tell them they're done.
194 llSetText("Sending results, please wait.\nThis should take about 20s.", <1.0, 0.0, 0.0>, 1.0); //Tell others they're done too, and to wait a bit
195 llEmail(address, "Questionnaire answers", responses); //Send the email.
196 state ready; //Back to the ready state
197 } else
198 {
199 setQuestions(); //Ask the next question
200 }
201 }
202 no_sensor() //The person's left, so send their partial answers
203 {
204 llSensorRemove(); //Tidy up
205 llEmail(address, "Questionnaire answers", responses); //Send email
206 state ready; //Back to ready state
207 }
208 timer()
209 {
210 llSensorRemove(); //Tidy up - slow sensor repeats aren't THAT laggy, but are a bit
211 llSetTimerEvent(0.0); //Tidies up the timer to stop it firing
212 llEmail(address, "Questionnnaire answers", responses); //Send their answers
213 state ready; //Back to ready state
214 }
215 }// END //

Back to the Best Free Tools in Second Life and OpenSim.