• GeSHi library error: sites/all/modules/geshifilter/geshi is not a directory.
  • strict warning: Non-static method view::load() should not be called statically in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/views.module on line 906.
  • strict warning: Declaration of views_handler_field_comment::init() should be compatible with views_handler_field::init(&$view, $options) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/modules/comment/views_handler_field_comment.inc on line 49.
  • strict warning: Declaration of views_handler_filter::options_validate() should be compatible with views_handler::options_validate($form, &$form_state) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/handlers/views_handler_filter.inc on line 607.
  • strict warning: Declaration of views_handler_filter::options_submit() should be compatible with views_handler::options_submit($form, &$form_state) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/handlers/views_handler_filter.inc on line 607.
  • strict warning: Declaration of views_handler_filter_node_status::operator_form() should be compatible with views_handler_filter::operator_form(&$form, &$form_state) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/modules/node/views_handler_filter_node_status.inc on line 13.
  • strict warning: Declaration of views_plugin_row::options_validate() should be compatible with views_plugin::options_validate(&$form, &$form_state) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/plugins/views_plugin_row.inc on line 134.
  • strict warning: Declaration of views_plugin_row::options_submit() should be compatible with views_plugin::options_submit(&$form, &$form_state) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/plugins/views_plugin_row.inc on line 134.
  • strict warning: Non-static method view::load() should not be called statically in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/views.module on line 906.
  • strict warning: Declaration of views_handler_argument::init() should be compatible with views_handler::init(&$view, $options) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/handlers/views_handler_argument.inc on line 744.
  • strict warning: Declaration of views_handler_filter_boolean_operator::value_validate() should be compatible with views_handler_filter::value_validate($form, &$form_state) in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/handlers/views_handler_filter_boolean_operator.inc on line 159.
  • strict warning: Non-static method view::load() should not be called statically in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/views.module on line 906.
  • strict warning: Non-static method view::load() should not be called statically in /home/ordinal/ordinalmalaprop.com/engine/sites/all/modules/views/views.module on line 906.

Semaphore - main script

Code summary: 

This is the main script to put in an attachment somewhere.

// Semaphore Animation Script // Ordinal Malaprop // 2007-09-15 // LICENCE // This script is licenced under a Creative Commons // Attribution-Noncommercial-Share Alike licence - see // http://creativecommons.org/licenses/by-nc-sa/3.0/ // for exact details. To sum up, feel free to distribute or modify // but it must retain my name and this licence and can't be sold, // even for L$1. //-------------------------------------------------------------------- // Globals and constants // Flag positions for characters // Every pair of digits indicates right+left arm positions, from 0 to 6 // The index of the correct pair is the index of the character in // the LETTERS or NUMBERS list, x2 string FLAG_POS = "5512244535251552535436401341424344303132333421221403042363"; // (rest)(numerals)(cancel)ABCDEFGHIJKLMNOPQRSTUVWXYZ // or in numeric mode // (r)(n)(c)123456789(letters)0..(negative) string LETTERS = " n#ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // when in letter mode string NUMBERS = " ##123456789l0"; // when in number mode string LEGAL = " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; // all allowed input characters // Wait this long between signals float gInterval = 1.0; // Channel for command input integer CHANNEL_INPUT = 9; // Channel for public output integer CHANNEL_PUBLIC = -34562421; // Channel for local communication with attachments integer CHANNEL_ATTACH = -89823958; // The current message being processed string gMessage = ""; // Next message to process string gMessageQueue = ""; // The final, cleaned message - say this at the end string gFinalMsg = ""; // Current mode - 0 = letter, 1 = numbers integer gMode = 0; // Are we translating other people's messages? integer gTranslating = TRUE; // Assorted constants string ANIM_POSE = "semaphore pose"; string ANIM_ERROR = "error"; string SOUND_CLICK = "4c8c3c77-de8d-bde2-b9b8-32635e0fd4a6"; key TEXTURE_ACTIVE = "30465632-5ac5-378f-a6bf-46ab56883e7a"; key TEXTURE_DISABLED = "2ecd1b3f-4659-2bf9-fda1-a4c47d30c78f"; // Some link numbers, hardcoded, naughty integer LINK_STATUS_DISPLAY = 2; integer LINK_INT_BUTTON = 3; integer LINK_INT_DISPLAY = 4; integer LINK_ERROR = 5; //-------------------------------------------------------------------- // Functions // update_display // Updates the HUD's display features update_display() { string interval = llGetSubString((string)gInterval, 0, 2); llMessageLinked(LINK_INT_DISPLAY, -3, interval, NULL_KEY); llOwnerSay("Interval between signals is " + interval + " seconds"); } // local_msg // Function to send messages to attachments etc local_msg(string msg) { llWhisper(CHANNEL_ATTACH, msg); } // public_msg // Function to send messages publicly public_msg(string msg) { llShout(CHANNEL_PUBLIC, llKey2Name(llGetOwner()) + "|" + msg); } update_translate(integer translating) { gTranslating = translating; string word = ""; if (!gTranslating) { word = "not "; } llOwnerSay("Currently " + word + "translating other people's semaphore messages"); } // preload // Preloads all the animations in the HUD. It does this each time you // activate it, so that anyone nearby will have them preloaded. preload() { integer n = llGetInventoryNumber(INVENTORY_ANIMATION); integer f = 0; string name = ""; do { name = llGetInventoryName(INVENTORY_ANIMATION, f); if (name != ANIM_POSE) { llStartAnimation(name); llStopAnimation(name); } } while (++f < n); llStartAnimation(ANIM_POSE); } // process_next_char // Main routine function - process the next letter or number in the current message // and returns the message with that trimmed off. string process_next_char(string msg) { // Quit if there's nothing more to do if (msg == "") return msg; // Stop the timer while we process the next letter llSetTimerEvent(0.0); string letter = llGetSubString(msg, 0, 0); // Pick the correct lookup list to use string lookup = LETTERS; if (gMode) lookup = NUMBERS; // Find out the index of the character, and play the appropriate animations integer pos = llSubStringIndex(lookup, letter); llMessageLinked(LINK_THIS, -1, llGetSubString(FLAG_POS, pos * 2, pos * 2 + 1), NULL_KEY); // What is being broadcast string broadcast = letter; if (letter == "n") { gMode = 1; broadcast = "(numbers)"; } else if (letter == "l") { gMode = 0; broadcast = "(letters)"; } else if (letter == " ") { broadcast = "(rest)"; } llOwnerSay(broadcast); public_msg(broadcast); // Restart the timer llSetTimerEvent(gInterval); // Was that the last character? If not, strip off the letter and return the result if (msg != letter) return llGetSubString(msg, 1, -1); // otherwise return a blank string else return ""; } // clean_msg // This function cleans the original message into a nice legal message string. // We do this at the start to avoid unexpected delays during semaphoring. string clean_msg(string msg) { msg = llToUpper(msg); integer f = 0; integer length = llStringLength(msg); string newMsg = ""; string lastChar = ""; string letter = ""; integer mode = 0; // 0 = letters 1 = numbers do { letter = llGetSubString(msg, f, f); // Do not allow: // - Letters not in the legal character list // - Multiple spaces if (llSubStringIndex(LEGAL, letter) != -1 && !(letter == " " && (lastChar == " " || f == 0))) { if (letter == lastChar) { newMsg += " "; // Insert a break between identical letters } if (llSubStringIndex(LETTERS, letter) == -1 && mode == 0) { // We have a number, when we are in letter mode, so change mode newMsg += "n"; mode = 1; } else if (llSubStringIndex(NUMBERS, letter) == -1 && mode == 1) { // Letter, when we are in number mode, change newMsg += "l"; mode = 0; } newMsg += letter; lastChar = letter; } } while (++f < length); // Chop off any spaces at the start and end if (llGetSubString(newMsg, -1, -1) == " ") { newMsg = llGetSubString(newMsg, 0, -2); } if (llGetSubString(newMsg, 0, 0) == " ") { newMsg = llGetSubString(newMsg, 1, -1); } return newMsg; } error() { llSetTimerEvent(0.0); gMessage = ""; gMessageQueue = ""; llStartAnimation(ANIM_ERROR); public_msg("(error)"); llMessageLinked(LINK_THIS, -2, "", NULL_KEY); llSleep(2.0); llStopAnimation(ANIM_ERROR); llOwnerSay("All messages cancelled."); } help() { llGiveInventory(llGetOwner(), llGetInventoryName(INVENTORY_NOTECARD, 0)); } //-------------------------------------------------------------------- // Main program default { on_rez(integer p) { llResetScript(); } state_entry() { llSetLinkAlpha(LINK_INT_BUTTON, 1.0, ALL_SIDES); llSetLinkAlpha(LINK_ERROR, 1.0, ALL_SIDES); update_display(); update_translate(gTranslating); llListen(CHANNEL_PUBLIC, "", NULL_KEY, ""); // We need animation permission llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); } run_time_permissions(integer perms) { if (perms & PERMISSION_TRIGGER_ANIMATION) { local_msg("active"); llSetLinkTexture(LINK_STATUS_DISPLAY, TEXTURE_ACTIVE, ALL_SIDES); llListen(CHANNEL_INPUT, "", llGetOwner(), ""); llOwnerSay("Enter a message on channel " + (string)CHANNEL_INPUT + " to say it in semaphore, e.g. '/9 hello world'. Say '/9 !help' for full instructions."); preload(); } else { llOwnerSay("Unfortunately you need to grant animation permissions for me to work."); state disabled; } } listen(integer c, string name, key id, string msg) { if (c == CHANNEL_INPUT) { if (llGetSubString(msg, 0, 0) == "!") { // This indicates a special voice command if (msg == "!translate") { update_translate(!gTranslating); } else if (msg == "!help") { help(); } else if (llGetSubString(msg, 0, 8) == "!interval") { float interval = (float)llGetSubString(msg, 10, -1); if (interval > 0.0 && interval < 10.0) { gInterval = interval; update_display(); } else { llOwnerSay("That was not a suitable interval parameter - try one above 0 and below 10."); } } else { llOwnerSay("That looked like some sort of special command, but unfortunately it wasn't one that I understood."); } } else if (gMessage != "") { gMessageQueue += " " + msg; llOwnerSay("Your new message will be added to the current one."); } else { llOwnerSay("Thinking..."); gMessage = "wait"; // set this to stop it adding another message gFinalMsg = clean_msg(msg); llOwnerSay("Beginning!"); gMessage = process_next_char(gFinalMsg); } } else if (c == CHANNEL_PUBLIC && gTranslating) { integer pos = llSubStringIndex(msg, "|"); string name = llGetSubString(msg, 0, pos - 1); msg = llGetSubString(msg, pos + 1, -1); if (llStringLength(msg) == 1 || llGetSubString(msg, 0, 0) == "(") { llOwnerSay(name + " sends the signal '" + msg + "'"); } else { llOwnerSay(name + " has sent the message '" + msg + "'"); } } } timer() { if (gMessage == "") { llSetTimerEvent(0.0); // Stop the current animations llMessageLinked(LINK_THIS, -2, "", NULL_KEY); public_msg(gFinalMsg); gFinalMsg = ""; if (gMessageQueue == "") { llOwnerSay("Finished!"); } else { llOwnerSay("Thinking..."); string msg = gMessageQueue; gMessageQueue = ""; gMessage = "wait"; gFinalMsg = clean_msg(msg); llOwnerSay("Beginning!"); gMessage = process_next_char(gFinalMsg); } } else { gMessage = process_next_char(gMessage); } } touch_start(integer n) { if (llDetectedKey(0) != llGetOwner()) return; llPlaySound(SOUND_CLICK, 1.0); integer link = llDetectedLinkNumber(0); if (link == LINK_INT_BUTTON) { gInterval = gInterval * 2; if (gInterval > 2.0) gInterval = 0.5; update_display(); } else if (link == LINK_ERROR) { error(); } else { state disabled; } } state_exit() { llSetTimerEvent(0.0); llStopAnimation(ANIM_POSE); } } state disabled { state_entry() { llMessageLinked(LINK_THIS, -2, "", NULL_KEY); gMessage = ""; gMessageQueue = ""; gMode = 0; local_msg("disabled"); llSetLinkTexture(LINK_STATUS_DISPLAY, TEXTURE_DISABLED, ALL_SIDES); llMessageLinked(LINK_INT_DISPLAY, -3, "", NULL_KEY); llSetLinkAlpha(LINK_INT_BUTTON, 0.5, ALL_SIDES); llSetLinkAlpha(LINK_ERROR, 0.5, ALL_SIDES); llOwnerSay("Switched off - touch me again to start"); } on_rez(integer p) { llOwnerSay("Currently disabled - touch me to start semaphore"); } touch_start(integer n) { if (llDetectedKey(0) != llGetOwner()) return; llPlaySound(SOUND_CLICK, 1.0); state default; } }