////////////////////////////////////////////////////////// // Wizardry and Steamworks (c) 2012, GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html // // for legal details, rights of fair usage and // // the disclaimer and warranty conditions. // ////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // ABOUT // ////////////////////////////////////////////////////////// // This is an implementation of LOGO in 3D. // // The original developement page can be found at: // // http://grimore.org/secondlife:logo_turtle // ////////////////////////////////////////////////////////// // EXAMPLES: // ////////////////////////////////////////////////////////// // LOGOParse("REPEAT 4 [ FO 1 YL 90 ]"); // // - draws a square. // // LOGOParse("REPEAT 3 [ FO 1 YL 120 ]"); // // - draws an isosceles triangle // ////////////////////////////////////////////////////////// front(integer step) { if(step == 0) return; llSetPos(llGetPos() + <1,0,0>*llGetRootRotation()); front(--step); } back(integer step) { if(step == 0) return; llSetPos(llGetPos() + <-1,0,0>*llGetRootRotation()); back(--step); } left(integer step) { if(step == 0) return; llSetPos(llGetPos() + <0,1,0>*llGetRootRotation()); front(--step); } right(integer step) { if(step == 0) return; llSetPos(llGetPos() + <0,-1,0>*llGetRootRotation()); back(--step); } up(integer step) { if(step == 0) return; llSetPos(llGetPos() + <0,0,1>*llGetRootRotation()); up(--step); } down(integer step) { if(step == 0) return; llSetPos(llGetPos() + <0,0,-1>*llGetRootRotation()); down(--step); } rollLeft(integer degrees) { if(degrees == 0) return; llSetRot(llEuler2Rot(<-1,0,0> * DEG_TO_RAD) * llGetRot()); rollLeft(--degrees); } rollRight(integer degrees) { if(degrees == 0) return; llSetRot(llEuler2Rot(<1,0,0> * DEG_TO_RAD) * llGetRot()); rollRight(--degrees); } pitchUp(integer degrees) { if(degrees == 0) return; llSetRot(llEuler2Rot(<0,-1,0> * DEG_TO_RAD) * llGetRot()); pitchUp(--degrees); } pitchDown(integer degrees) { if(degrees == 0) return; llSetRot(llEuler2Rot(<0,1,0> * DEG_TO_RAD) * llGetRot()); pitchDown(--degrees); } yawLeft(integer degrees) { if(degrees == 0) return; llSetRot(llEuler2Rot(<0,0,1> * DEG_TO_RAD) * llGetRot()); yawLeft(--degrees); } yawRight(integer degrees) { if(degrees == 0) return; llSetRot(llEuler2Rot(<0,0,-1> * DEG_TO_RAD) * llGetRot()); yawRight(--degrees); } list bs = []; string inner(string in) { if(llStringLength(in) == 0) return ""; string c = llGetSubString(in, 0, 0); in = llDeleteSubString(in, 0, 0); if(c == "[") { bs += "["; jump next; } if(c == "]") { if(llGetListLength(bs) == 0) { return ""; } string peek = llList2String(bs, llGetListLength(bs)-1); if(peek == "[") { bs = llDeleteSubList(bs, llGetListLength(bs)-1, llGetListLength(bs)-1); jump next; } } @next; return c + inner(in); } LOGOParse(string input) { list split = llParseString2List(input, [" "], [""]); do { string in = llList2String(split, 0); if(in == "REPEAT") { // Get the number of times to repeat. integer times = llList2Integer(split, 1); // Delete the "REPEAT" command and number of times. split = llDeleteSubList(split, 0, 0); split = llDeleteSubList(split, 0, 0); // Clean the sub-expression of brackets. string sub = llDumpList2String(split, " "); sub = llDeleteSubString(sub, 0, 0); sub = llDeleteSubString(sub, llStringLength(sub)-1, llStringLength(sub)-1); sub = inner(sub); // And now delete the sub-expression from the input // leaving the rest of the input in split for to // be processed by the current recursive branch. split = llDeleteSubList(split, 0, 0); list delete = llParseString2List(sub, [" "], [""]); do { split = llDeleteSubList(split, 0, 0); delete = llDeleteSubList(delete, 0, 0); } while(llGetListLength(delete) != 0); split = llDeleteSubList(split, 0, 0); // Here we go. For the number of times we have to repeat // the sub-expression, go ahead and parse it that number // of times. do { LOGOParse(sub); } while(--times); // Don't pop off the next REPEAT, we're done here, loop again! jump continue; } if(in == "FO") { front(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("FO"); } if(in == "BA") { back(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("BA"); } if(in == "LE") { left(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("LE"); } if(in == "RI") { right(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("RI"); } if(in == "UP") { up(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("UP"); } if(in == "DO") { down(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("DO"); } if(in == "RR") { rollRight(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("RR"); } if(in == "RL") { rollLeft(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("RL"); } if(in == "PU") { pitchUp(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("PU"); } if(in == "PD") { pitchDown(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("PD"); } if(in == "YR") { yawRight(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("YR"); } if(in == "YL") { yawLeft(llList2Integer(split, 1)); /* DEBUG */// llOwnerSay("YL"); } split = llDeleteSubList(split, 0, 0); @continue; } while(split); } default { state_entry() { llListen(0, "", llGetOwner(), ""); } listen(integer channel, string name, key id, string message) { // Enqueue commands by injecting them into the recursive parser. LOGOParse(message); // Enqueue the commands on the call stack. } on_rez(integer num) { llResetScript(); } }