// // The line above should be left blank to avoid script errors in OpenSim. // LSL script generated: mod.set-1.0.rezzer_reset_btn.lslp Tue Nov 15 15:49:28 Tokyo Standard Time 2011 /* * Part of the Sloodle project (www.sloodle.org) * * Copyright (c) 2011-06 contributors (see below) * Released under the GNU GPL v3 * ------------------------------------------- * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * All scripts must maintain this copyrite information, including the contributer information listed * * Contributors: * Paul Preibisch * * DESCRIPTION * Rezzer.lslp * This script is responsible for: * *** initiating the loading of a quiz * *** getting the first question and loading the options as texture maps on the child prims (pie_slices) * *** initiating a countdown in the timer.lslp script * *** starting a sensor, and using hovertext to display which pie_slice a user is standing over * *** determining the value of each option and telling each pie_slice to open or close when the count down timer reaches zero * *** determining which pie_slice a user is standing over at the end of the countdown, and submitting their answers to the notify_server.lslp script * *** rezzing orbs on each of its edges which are clickable by avatars who answered correctly * *** receive linked messages from the orbs which indicate touch events from avatars who have answered the question correctly, and rez * rezzing child hexagons along the touched edges * *** Receive GET QUESTION command from a child hex when its center orb has been touched by an avatar * *** requesting questions from question_handler.lslp and passing retrieved question along to the requesting child hexagon * * */ float edge_length; list QUESTIONS_ASKED; float edge_length_half; string CONFIG; float tip_to_edge; list rezzed_hexes; list opids; integer PIN=7961; integer doRepeat; integer doRandomize; integer doPlaySound; integer quiz_id; string quiz_name; integer question_id; list question_ids; integer num_questions; integer current_question; string sloodleserverroot = ""; integer sloodlecontrollerid = 0; string sloodlepwd = ""; integer sloodlemoduleid = 0; integer sloodleobjectaccessleveluse = 0; // Who can use this object? integer sloodleobjectaccesslevelctrl = 0; // Who can control this object? integer sloodleserveraccesslevel = 0; // Who can use the server resource? (Value passed straight back to Moodle) integer isconfigured = FALSE; // Do we have all the configuration data we need? integer eof = FALSE; // Have we reached the end of the configuration data? string SLOODLE_EOF = "sloodleeof"; string sloodle_quiz_url = "/mod/sloodle/mod/quiz-1.0/linker.php"; list sides_rezzed; string QUIZ_DATA; integer TIME_LIMIT; list GRAND_CHILDREN; integer SLOODLE_REMOTE_LOAD_SCRIPT=1639277018; string HEX_CONFIG_SEPARATOR="*^*^*^"; integer SLOODLE_CHANNEL_ANIM= -1639277007; integer SLOODLE_CHANNEL_OBJECT_DIALOG = -3857343; // an arbitrary channel the sloodle scripts will use to talk to each other. Doesn't atter what it is, as long as the same thing is set in the sloodle_slave script. integer SLOODLE_CHANNEL_ANSWER_SCORE_FOR_AVATAR = -1639271113; // Tells anyone who might be interested that we scored the answer. Score in string, avatar in key. integer SLOODLE_SET_TEXTURE= -1639277010; integer SLOODLE_CHANNEL_QUIZ_MASTER_RESPONSE= -1639277008; integer SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST= -1639277006; integer SLOODLE_CHANNEL_USER_TOUCH = -1639277002;//user touched object integer SLOODLE_CHANNEL_QUIZ_LOADING_QUIZ = -1639271109; string SLOODLE_TRANSLATE_HOVER_TEXT = "hovertext"; // 2 output parameters: colour , and alpha value string SLOODLE_TRANSLATE_WHISPER = "whisper"; // 1 output parameter: chat channel number string SLOODLE_TRANSLATE_SAY = "say"; // 1 output parameter: chat channel number string SLOODLE_TRANSLATE_OWNER_SAY = "ownersay"; // No output parameters string SLOODLE_TRANSLATE_DIALOG = "dialog"; // Recipient avatar should be identified in link message keyval. At least 2 output parameters: first the channel number for the dialog, and then 1 to 12 button label strings. string SLOODLE_TRANSLATE_LOAD_URL = "loadurl"; // Recipient avatar should be identified in link message keyval. 1 output parameter giving URL to load. string SLOODLE_TRANSLATE_IM = "instantmessage"; // Recipient avatar should be identified in link message keyval. No output parameters. integer SLOODLE_CHANNEL_TRANSLATION_REQUEST = -1928374651; integer SLOODLE_CHANNEL_QUIZ_ASK_QUESTION = -1639271112; //used when this script wants to ask a question and have the results sent to the child hex integer SLOODLE_CHANNEL_QUESTION_ASKED_AVATAR = -1639271105; //Sent by main quiz script to tell UI scripts that question has been asked to avatar with key. String contains question ID + "|" + question text integer SLOODLE_CHANNEL_QUIZ_LOADED_QUIZ = -1639271110; integer SLOODLE_CHANNEL_QUIZ_NOTIFY_SERVER_OF_RESPONSE= -1639277004; integer SLOODLE_CHANNEL_QUIZ_STATE_ENTRY_LOAD_QUIZ_FOR_USER = -1639271116; //mod quiz script is in state CHECK_QUIZ integer SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM= -1639277009; // 3 output parameters: colour , alpha value, link number string HEXAGON_PLATFORM="Hexagon Platform"; integer TIMES_UP=FALSE; integer num_options=0; list CORRECT_AVATARS; list options;//store pie slice correlation. Therefore option[0]=pie_slice# integer quiz_loaded=FALSE; vector RED =<1.00000, 0.00000, 0.00000>; vector ORANGE=<1.00000, 0.43763, 0.02414>; vector YELLOW=<1.00000, 1.00000, 0.00000>; vector GREEN=<0.00000, 1.00000, 0.00000>; vector BLUE=<0.00000, 0.00000, 1.00000>; vector BABYBLUE=<0.00000, 1.00000, 1.00000>; vector PINK=<1.00000, 0.00000, 1.00000>; vector PURPLE=<0.57338, 0.25486, 1.00000>; vector BLACK= <0.00000, 0.00000, 0.00000>; vector WHITE= <1.00000, 1.00000, 1.00000>; vector AVCLASSBLUE= <0.06274,0.247058,0.35294>; vector AVCLASSLIGHTBLUG=<0.8549,0.9372,0.9686>;//#daeff7 integer SLOODLE_TIMER_START= -1639277011; //shoudl be used to starts the timer from its current position integer SLOODLE_TIMER_RESTART= -1639277012;//should be used to set the counter to 0 and begin counting down again integer SLOODLE_TIMER_STOP= -1639277013;//should stop the timer at its current position integer SLOODLE_TIMER_STOP_AND_RESET= -1639277014;//should stop the timer at its current position and reset count to 0 integer SLOODLE_TIMER_RESET= -1639277015;//shoudl reset the count back to zero but not restart the timer integer SLOODLE_TIMER_TIMES_UP= -1639277016;//used to transmit the timer reached its time limit list MY_SLICES; integer already_received_question=FALSE; integer my_start_param; list pie_slice_hover_text; string qdialogtext; list qdialogoptions; list option_points; debug (string message ){ list params = llGetPrimitiveParams ([PRIM_MATERIAL ]); if (llList2Integer (params ,0)==PRIM_MATERIAL_FLESH){ llOwnerSay("memory: "+(string)llGetFreeMemory()+" Script name: "+llGetScriptName ()+": " +message ); } } //rezzes a hexagon at the indicated orb# rez_hexagon(integer orb){ if (llGetListLength(QUESTIONS_ASKED)>=num_questions){ //quiz finished sloodle_translation_request(SLOODLE_TRANSLATE_SAY, [0], "no_more_questions", [], NULL_KEY, "hex_quizzer"); return; } integer my_oposite_section; vector my_coord= llGetPos(); if (orb==0){ return; } float adjustment_x = 0.0402; float adjustment_y = -0.0365; vector child_coord=my_coord; integer DIVISER=1; if (orb==1){//yellow child_coord.x=my_coord.x + edge_length + edge_length/2; child_coord.y=my_coord.y -tip_to_edge; my_oposite_section=4; }else if (orb==2){//pink child_coord.x=my_coord.x; child_coord.y=my_coord.y-tip_to_edge * 2; my_oposite_section=5; }else if (orb==3){ child_coord.x=my_coord.x - edge_length- edge_length/2; child_coord.y=my_coord.y - tip_to_edge; my_oposite_section=6; }else if (orb==4){ child_coord.y=my_coord.y+tip_to_edge; child_coord.x=my_coord.x-edge_length-edge_length/2; my_oposite_section=1; }else if (orb==5){ child_coord.x=my_coord.x; child_coord.y=my_coord.y+ tip_to_edge * 2; my_oposite_section=2; }else if (orb==6){ child_coord.x=my_coord.x+ edge_length+edge_length/2; child_coord.y=my_coord.y+tip_to_edge; my_oposite_section=3; } // child_coord.x=child_coord.x+ adjustment_x; // child_coord.y=child_coord.y+ adjustment_y; //rez a new hexagon, and pass my_oppsosite_section as the start_parameter so that the new hexagon wont rez on that the my_oposite_section edge llRezAtRoot(HEXAGON_PLATFORM, child_coord, ZERO_VECTOR, llGetRot(), my_oposite_section); } set_all_pie_slice_hover_text(string msg){ pie_slice_hover_text=[]; pie_slice_hover_text+=" "; integer pie_slice_num; for (pie_slice_num=1;pie_slice_num<=6;pie_slice_num++){ sloodle_translation_request("SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM", [ORANGE, 1.0,get_prim("option"+(string)pie_slice_num)], "option", [msg], "", "hex_quizzer"); pie_slice_hover_text+=msg; } } //returns the pie_slice the avatar is standing near string get_detected_pie_slice(vector avatar){ //returns name of pie_slice integer i; float closest_orb_distance=100.0; string name_of_closest_orb=""; integer closest_orb_link_number; integer root_orb= get_prim("Hexagon Quizzer"); for (i=1;i<=6;i++){ integer orb_link_number = get_prim("orb"+(string)i); list orb_data=llGetLinkPrimitiveParams(orb_link_number, [PRIM_POSITION]); vector orb_pos = llList2Vector(orb_data, 0); float detected_distance_from_avatar_to_orb = llVecDist(orb_pos, avatar); if (detected_distance_from_avatar_to_orb 1) value1 = llList2String(bits,1); if (numbits > 2) value2 = llList2String(bits,2); if (name == "set:sloodleserverroot") sloodleserverroot = value1; else if (name == "set:sloodlepwd") { // The password may be a single prim password, or a UUID and a password if (value2 != "") { sloodlepwd = value1 + "|" + value2; } else { sloodlepwd = value1; } } else if (name == "set:questiontimelimit"){ TIME_LIMIT= (integer)value1; debug("\n\n\n\n\n we got time limit is: "+(string)TIME_LIMIT); } else if (name == "set:sloodlecontrollerid") sloodlecontrollerid = (integer)value1; else if (name == "set:sloodlemoduleid") sloodlemoduleid = (integer)value1; else if (name == "set:sloodleobjectaccessleveluse") sloodleobjectaccessleveluse = (integer)value1; else if (name == "set:sloodleserveraccesslevel") sloodleserveraccesslevel = (integer)value1; else if (name == "set:sloodlerepeat") doRepeat = (integer)value1; else if (name == "set:sloodlerandomize") doRandomize = (integer)value1; else if (name == "set:sloodleplaysound") doPlaySound = (integer)value1; else if (name == SLOODLE_EOF) eof = TRUE; return (sloodleserverroot != "" && sloodlepwd != "" && sloodlecontrollerid > 0 && sloodlemoduleid > 0); } default { on_rez(integer start_param){ llResetScript(); } state_entry() { integer n=llGetNumberOfPrims(); integer j=0; for (j=0;j0){ //avatar is correct if (llListFindList(CORRECT_AVATARS, [avatar_name])==-1){ //dont add same name twice sloodle_translation_request(SLOODLE_TRANSLATE_IM, [0], "correct_select_orb", [avatar_name], avatar_key, "hex_quizzer"); CORRECT_AVATARS+=avatar_key;//record which avatars are correct because only those who are correct can click an orb llMessageLinked(LINK_SET, SLOODLE_CHANNEL_QUIZ_NOTIFY_SERVER_OF_RESPONSE,"multichoice|"+(string)question_id+"|"+(string)opid+"|"+(string)score_change, avatar_key); llMessageLinked(LINK_SET, SLOODLE_CHANNEL_ANSWER_SCORE_FOR_AVATAR, (string)score_change+"|"+(string)llGetKey(), avatar_key); } }else{ llMessageLinked(LINK_SET, SLOODLE_CHANNEL_QUIZ_NOTIFY_SERVER_OF_RESPONSE,"multichoice|"+(string)question_id+"|"+(string)opid+"|"+(string)score_change, avatar_key); sloodle_translation_request(SLOODLE_TRANSLATE_IM, [0], "incorrect_can_not_select_orb", [avatar_name], avatar_key, "hex_quizzer"); llPushObject(avatar_key,<0,0,100>, <0,0,-100>, TRUE); } string pie_slice_text =llList2String(pie_slice_hover_text,pie_slice_num); pie_slice_hover_text= llListReplaceList(pie_slice_hover_text, [pie_slice_text+"\n"+avatar_name], pie_slice_num, pie_slice_num); llMessageLinked(LINK_SET, SLOODLE_CHANNEL_ANIM, "orb show|0,1,2,3,4,5,6|10", NULL_KEY); integer j; string correct_avatars_str= "Avatars allowed to click:"+strReplace(llList2CSV(CORRECT_AVATARS),",","\n"); for(j=1;j<=6;j++){ sloodle_translation_request("SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM", [GREEN, 1.0,get_prim("orb")+(string)j], "option", [correct_avatars_str], "", "hex_quizzer"); } //check if this was the last question } //print names on pie slice hover text in GREEN if correct, in RED if incorrect string avatar_names; list grades=[];//retrieve the grade for each pie_slice vector color; for (pie_slice_num=1;pie_slice_num<=6;pie_slice_num++){ if (pie_slice_value(pie_slice_num)>0) { color=GREEN; }else{ color=RED; } avatar_names=llList2String(pie_slice_hover_text,pie_slice_num); sloodle_translation_request("SLOODLE_TRANSLATE_HOVER_TEXT_LINKED_PRIM", [color, 1.0,get_prim("option"+(string)pie_slice_num)], "option", [avatar_names], "", "hex_quizzer"); integer grade = pie_slice_value(pie_slice_num); grades+=grade; } //send the list of grades to the pie_slices so that they open or close. If grade is 0 for that option, pie_slice will open llMessageLinked(LINK_SET, SLOODLE_CHANNEL_ANIM, "pie_slice|"+llList2CSV(grades), NULL_KEY); debug("sending grades to pie_slices: "+llList2CSV(grades)); }; } object_rez(key platform) { //a new hex was rezzed, listen to the new hex platform llListen(SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST, "", platform, ""); rezzed_hexes+=platform; llGiveInventory(platform, HEXAGON_PLATFORM); debug("giving platform script"); //since llRemoteLoadScriptPin makes a script sleep for 3 seconds, we need to offload the remote loading of the scripts to a seperate loader script /* llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "0|"+(string)PIN+"|sloodle_translation_en.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "1|"+(string)PIN+"|sloodle_translation_hex_quizzer_en.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "2|"+(string)PIN+"|timer.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "3|"+(string)PIN+"|delayed_set_text.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "4|"+(string)PIN+"|feedback_request.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "5|"+(string)PIN+"|finish_quiz.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "6|"+(string)PIN+"|load_quiz.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "7|"+(string)PIN+"|notify_server_of_response.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "8|"+(string)PIN+"|sloodle_quiz_question_handler.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "9|"+(string)PIN+"|hex_multi_user_quiz.lslp|"+(string)TRUE+"|0", platform); llMessageLinked(LINK_SET, SLOODLE_REMOTE_LOAD_SCRIPT, "10|"+(string)PIN+"|rezzer_platform.lslp|"+(string)TRUE+"|0", platform); */ llRemoteLoadScriptPin(platform, "rezzer_platform.lslp",PIN, TRUE, 0); } listen(integer channel, string name, key id, string message) { list data = llParseString2List(message, ["|"], []); string command = llList2String(data, 0); debug("************************** command is: "+command); if (command=="rezzed grandchild"){ debug("a grandchild.. i hope its mine!"); string my_hash = llSHA1String(sloodleserverroot+sloodlecontrollerid+sloodlemoduleid); string received_hash=llList2String(data,2); if (received_hash==my_hash){ debug("(((((((((server(((((((((((((((( "+sloodleserverroot+" "+sloodlecontrollerid+" "+sloodlemoduleid+" my hash " +my_hash+ " received hash: "+received_hash); //this is my grandchild because they have the same serverroot, controllerid, and moduleid as me! key grandchild=llList2Key(data,1); llListen(SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST, "",grandchild, ""); if (llListFindList(GRAND_CHILDREN,[grandchild])==-1){ GRAND_CHILDREN+=grandchild; } debug("\n\n\n\nYay! a grandchild! listening to "+llList2CSV(GRAND_CHILDREN)); } } if (llListFindList(rezzed_hexes, [id])==-1&&llListFindList(GRAND_CHILDREN,[id])==-1){ debug("---------------not my relative!!"); llOwnerSay("---------------not my relative!!"); //return; } debug("continuing"); if (channel==SLOODLE_CHANNEL_QUIZ_MASTER_REQUEST){ if (command=="GET CONFIG"){ debug("sending config data"); llRegionSayTo(id,SLOODLE_CHANNEL_QUIZ_MASTER_RESPONSE, "receive config"+HEX_CONFIG_SEPARATOR+CONFIG); }else if (command=="LOAD QUIZ"){ key user_key = llList2Key(data,1); debug("received load quiz - current question is: "+(string)current_question+ " num questions is : "+(string)num_questions); if (current_question>num_questions){ if (doRepeat==TRUE){ current_question=0; }else{ //TODO finish quiz for all avatars sloodle_translation_request(SLOODLE_TRANSLATE_SAY, [0], "no_more_questions", [], NULL_KEY, "hex_quizzer"); return; } } integer question_id = llList2Integer(question_ids,current_question); current_question++; debug("sending quiz data"); debug("sending: "+"receive quiz data"+HEX_CONFIG_SEPARATOR+QUIZ_DATA+"|"+(string)question_id+"|"+(string)current_question); llRegionSayTo(id,SLOODLE_CHANNEL_QUIZ_MASTER_RESPONSE, "receive quiz data"+HEX_CONFIG_SEPARATOR+QUIZ_DATA+"|"+(string)question_id+"|"+(string)current_question); } } } }