////////////////////////////////////////////////////////// // (C) Wizardry and Steamworks 2013, license: GPLv3 // ////////////////////////////////////////////////////////// /////////////// INITIAL CONFIGURATION //////////////////// float DEFAULT_PACEMAKER_PERIOD=15; float DEFAULT_RAPID_REPOLARIZATION_TIME=3; float DEFAULT_PLATEAU_TIME=20; //the pacemaker emits for 2 seconds //total cycle time=15+3+20+2=40 seconds float PACEMAKER_PERIOD = DEFAULT_PACEMAKER_PERIOD; float RAPID_REPOLARIZATION_TIME = DEFAULT_RAPID_REPOLARIZATION_TIME; float PLATEAU_TIME = DEFAULT_PLATEAU_TIME; ////////////////////////////////////////////////////////// ////////////////////// INTERNALS ///////////////////////// string pacemaker = "[♥] Start"; string fibrilate = "[✔] Fib"; integer my_i = 0; integer my_j = 0; integer comChannel = 0; key configAv = NULL_KEY; float p = 0; integer laz=0; touch_menu() { llSetTimerEvent(0); llInstantMessage(configAv, "Entering configuration stage... Please wait..."); comChannel = (( (integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) + (integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)))) & 0x3FFFFFFF ^ 0xBFFFFFFF; llListen(comChannel+1, "", configAv, ""); llListen(comChannel+2, "", configAv, ""); llListen(comChannel+3, "", configAv, ""); llListen(comChannel+4, "", configAv, ""); llDialog(configAv, "\nThe current settings for the selected cell are:\n- Phase 2: " + llGetSubString((string)(PLATEAU_TIME*10),0,4) + " x100 ms.\n- Phase 3: " + llGetSubString((string)(RAPID_REPOLARIZATION_TIME*10),0,4) + " x100 ms.\n- Generator timing: " + llGetSubString((string)((RAPID_REPOLARIZATION_TIME+PLATEAU_TIME+PACEMAKER_PERIOD+2)*10),0,4) + " x100 ms.\n- Generator state: " + llGetSubString(pacemaker, 1, 1) + "\nPlease select from the options below.", [ fibrilate, pacemaker, "Kill Cell", "Show RP", "Hide RP", "Reset", "Set phase 2", "Set phase 3", "Set Gen", "Help", "[ Exit ]" ], comChannel+1); llSetTimerEvent(60); } default { state_entry() { if(llGetObjectDesc() == "") return; list my = llParseString2List(llGetObjectDesc(), ["0"], []); my_i = llList2Integer(my, 0); my_j = llList2Integer(my, 1); llSetObjectDesc((string)my_i + "," + (string)my_j); state resting; } on_rez(integer num) { if(!num) { llSetObjectDesc(""); return; } my_i = num >> 16; my_j = num & 0xFFFF; llSetObjectDesc((string)my_i + "," + (string)my_j); state resting; } } state configuration { state_entry() { touch_menu(); } touch_start(integer num) { touch_menu(); } listen(integer channel, string name, key id, string message) { if(message == "[♥] Start") { laz=1; pacemaker = "[♡] Stop"; llSetColor(<0.4, 0.4, 0.0>, ALL_SIDES); llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, 0.10]); jump exit; } else if(message == "[♡] Stop") { laz=0; pacemaker = "[♥] Start"; llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, 0]); jump exit; } else if(message == "[✔] Fib") { llMessageLinked(LINK_SET, 0, "fibrilate", NULL_KEY); fibrilate = "[✖] Fib"; jump exit; } else if(message == "[✖] Fib") { llMessageLinked(LINK_SET, 0, "stopfibrilate", NULL_KEY); fibrilate = "[✔] Fib"; jump exit; } else if(message == "Show RP") { llMessageLinked(LINK_SET, 0, "showrp", NULL_KEY); llSetText(llGetSubString((string)((RAPID_REPOLARIZATION_TIME + PLATEAU_TIME)*10), 0, 4), <1,1,1>, 1.0); jump exit; } else if(message == "Hide RP") { llMessageLinked(LINK_SET, 0, "hiderp", NULL_KEY); llSetText("", <1,1,1>, 0.0); jump exit; } else if(message == "Set Gen") { llTextBox(id, "\nIf you want this cell to become a Generator, please define how often (in ms) you want it to produce a stimulus. Press Submit and then press the [♥] Start button.\nYour input will be automatically multiplied by 100ms.\n\nCurrent setting is: " + llGetSubString((string)((RAPID_REPOLARIZATION_TIME+PLATEAU_TIME+PACEMAKER_PERIOD+2)*10),0,4) + " x100ms.\n\n", comChannel+2); return; } else if(message == "Set phase 2") { llTextBox(id, "\nPlease define the duration(in ms) of AP's phase 2 (plateau) of the selected cell and press Submit. Your input will be automatically multiplied by 100ms.\n\nCurrent settings is: " + llGetSubString((string)(PLATEAU_TIME*10),0,4) + "x100ms. \n\n", comChannel+3); return; } else if(message == "Set phase 3") { llTextBox(id, "\nPlease define the duration(in ms) of AP's phase 3 (rapid depolarization) of the selected cell and press Submit. Your input will be automatically multiplied by 100ms.\n\nCurrent settings is: " + llGetSubString((string)(RAPID_REPOLARIZATION_TIME*10),0,4) + "x100 ms. \n\n", comChannel+4); return; } else if(message == "Help") { llGiveInventory(configAv, "CEAS_Help_Card");} else if(message == "Kill Cell") { state dead; } else if(message == "Reset") { PACEMAKER_PERIOD = DEFAULT_PACEMAKER_PERIOD; RAPID_REPOLARIZATION_TIME = DEFAULT_RAPID_REPOLARIZATION_TIME; PLATEAU_TIME = DEFAULT_PLATEAU_TIME; pacemaker = "[♥] Start"; llSetPrimitiveParams([PRIM_GLOW, ALL_SIDES, 0]); laz=0; jump exit; } else if(message == "[ Exit ]") { jump exit; } else if(channel == comChannel+2 && (float)message > 0) { PACEMAKER_PERIOD = ((float)(message))/10; } else if(channel == comChannel+3 && (float)message > 0) { PLATEAU_TIME =((float)(message))/10; } else if(channel == comChannel+4 && (float)message > 0) { RAPID_REPOLARIZATION_TIME = ((float)(message))/10; } else return; touch_menu(); return; @exit; llSetTimerEvent(0.2); } timer() { llSetTimerEvent(0); llInstantMessage(configAv, "Leaving configuration stage... Changes will become visible after another cycle."); state resting; } } state resting { state_entry() { if(fibrilate == "[✖] Fib") { llSetTimerEvent(llFrand(DEFAULT_PACEMAKER_PERIOD/5)); return; } else if(pacemaker == "[♥] Start") llSetTimerEvent(0); else if(pacemaker == "[♡] Stop" && laz== 1 && fibrilate=="[✔] Fib" ) { laz=0; llSetTimerEvent(0.5); } else if(pacemaker == "[♡] Stop" && laz== 0 && fibrilate=="[✔] Fib") llSetTimerEvent(PACEMAKER_PERIOD); if(pacemaker == "[♡] Stop") llSetColor(<0.4, 0.4, 0.0>, ALL_SIDES); //if generator cell, set other colour else llSetColor(<0,1,0>, ALL_SIDES); } touch_start(integer num) { if(llGetLinkNumber() == 0) return; llSetTimerEvent(0); configAv = llDetectedKey(0); state configuration; } link_message(integer sender_num, integer num, string str, key id) { if(str == "showrp") { llSetText(llGetSubString((string)((RAPID_REPOLARIZATION_TIME + PLATEAU_TIME)*10), 0, 4), <1,1,1>, 1.0); return; } if(str == "hiderp") { llSetText("", <1,1,1>, 0.0); return; } if(str == "fibrilate") { fibrilate = "[✖] Fib"; return; } if(str == "stopfibrilate") { fibrilate = "[✔] Fib"; return; } if(sender_num == llGetLinkNumber()) return; list ij = llParseString2List(str, [","], [""]); integer di = llAbs(my_i - llList2Integer(ij, 0)); integer dj = llAbs(my_j - llList2Integer(ij, 1)); if(di > 2) return; if(dj > 2) return; float d = llPow(di, 2) + llPow(dj, 2); p += 1/d; if(llFrand(1) < p) state refractory_1; } timer() { state refractory_1; } } state refractory_1 { state_entry() { p=0; llSetColor(<1,1,0>, ALL_SIDES); llSensorRepeat("", NULL_KEY, AGENT, 0.1, 0.1, 1); llSetTimerEvent(2); } link_message(integer sender_num, integer num, string str, key id) { if(str == "showrp") { llSetText(llGetSubString((string)((RAPID_REPOLARIZATION_TIME + PLATEAU_TIME)*10), 0, 4), <1,1,1>, 1.0); return; } if(str == "hiderp") { llSetText("", <1,1,1>, 0.0); return; } if(str == "fibrilate") { fibrilate = "[✖] Fib"; return; } if(str == "stopfibrilate") { fibrilate = "[✔] Fib"; return; } } touch_start(integer num) { if(llGetLinkNumber() == 0) return; llSetTimerEvent(0); configAv = llDetectedKey(0); state configuration; } no_sensor() { llMessageLinked(LINK_SET, 0, llGetObjectDesc(), ""); llSensorRemove(); } timer() { llSetTimerEvent(0); state refractory_2a; } } state refractory_2a { state_entry() { if(pacemaker == "[♡] Stop") llSetColor(<0.4, 0.4, 0.0>, ALL_SIDES); //if generator cell, set other colour else llSetColor(<1,0,0>, ALL_SIDES); if(fibrilate == "[✖] Fib") { llSetTimerEvent(llFrand(DEFAULT_PLATEAU_TIME/5)); return; } llSetTimerEvent(PLATEAU_TIME); } link_message(integer sender_num, integer num, string str, key id) { if(str == "showrp") { llSetText(llGetSubString((string)((RAPID_REPOLARIZATION_TIME + PLATEAU_TIME)*10), 0, 4), <1,1,1>, 1.0); return; } if(str == "hiderp") { llSetText("", <1,1,1>, 0.0); return; } if(str == "fibrilate") { fibrilate = "[✖] Fib"; return; } if(str == "stopfibrilate") { fibrilate = "[✔] Fib"; return; } } touch_start(integer num) { if(llGetLinkNumber() == 0) return; llSetTimerEvent(0); configAv = llDetectedKey(0); state configuration; } timer() { llSetTimerEvent(0); state refractory_2b; } } state refractory_2b { state_entry() { if(pacemaker == "[♡] Stop") llSetColor(<0.4, 0.4, 0.0>, ALL_SIDES); //if generator cell, set other color else llSetColor(<0,1,1>, ALL_SIDES); llSetTimerEvent(RAPID_REPOLARIZATION_TIME); } link_message(integer sender_num, integer num, string str, key id) { if(str == "showrp") { llSetText(llGetSubString((string)((RAPID_REPOLARIZATION_TIME + PLATEAU_TIME)*10), 0, 4), <1,1,1>, 1.0); return; } if(str == "hiderp") { llSetText("", <1,1,1>, 0.0); return; } if(str == "fibrilate") { fibrilate = "[✖] Fib"; return; } if(str == "stopfibrilate") { fibrilate = "[✔] Fib"; return; } } touch_start(integer num) { if(llGetLinkNumber() == 0) return; llSetTimerEvent(0); configAv = llDetectedKey(0); state configuration; } timer() { llSetTimerEvent(RAPID_REPOLARIZATION_TIME); if(pacemaker == "[♡] Stop") llSetTimerEvent(PACEMAKER_PERIOD); // Pass timer over states. state resting; } } state dead { state_entry() { llSetColor(<0,0,0>, ALL_SIDES); } link_message(integer sender_num, integer num, string str, key id) { if(str == "showrp") { llSetText(llGetSubString((string)((RAPID_REPOLARIZATION_TIME + PLATEAU_TIME)*10), 0, 4), <1,1,1>, 1.0); return; } if(str == "hiderp") { llSetText("", <1,1,1>, 0.0); return; } if(str == "fibrilate") { fibrilate = "[✖] Fib"; return; } if(str == "stopfibrilate") { fibrilate = "[✔] Fib"; return; } } touch_start(integer num) { if(llGetLinkNumber() == 0) return; llSetTimerEvent(0); configAv = llDetectedKey(0); state configuration; } }