@create #73333 named Mokova dispenser:Mokova dispenser @prop #64246."chains" {} "" @prop #64246."queue" {} "" @prop #64246."lag_threshold" 1.0 rc @prop #64246."lag_meter" #35368 rc @prop #64246."cst_delay" 30 rc @prop #64246."peak" 400 rc @prop #64246."mokova_prompt_msg" "You may now take Mokova. Do you want to?" rc @prop #64246."mokova_start_msg" "You feel a warm momentary glow as the drug surges through your body." rc @prop #64246."mokova_stop_msg" "You shiver for a second as the last of the drug leaves your body." rc @prop #64246."sober_msg" "A faint beep alerts you that an antidote is being released into your bloodstream." rc "#64246.("usage") => E_PERM (Permission denied) ;;#64246.("users") = {} ;;#64246.("help_msg") = {"Mokova is a hallucinogenic tell-filter; users will see text markoved into nonsensical, occasionally beautiful sentence fragments. Before using Mokova, please take two disclaimers into consideration:", " -- Mokova is extremely tick-intensive, and will make your MOOing noticeably more laggy, and", " -- Since input quickly becomes extremely incoherent, do not expect to be able to interact meaningfully with anybody else.", "", "To use Mokova:", "1) @addfeature #64246.", "2) Set #64246 as your tell filter. (If you do not know how to do this, you should read the help texts on your Player Class to find out.)", "3) (Optional) Make a child of the Generic Mokova Bead (#37444) and carry it with you. When you are on Mokova, the bead will insert a line into your description indicating that you are in an altered state -- if your Player Class is one of the many that implements integrating object descriptions. (Type \"help #37444\" for more info.)", "4) If you are on any channels, please turn them off -- otherwise, you'll end up lagging anybody who uses that channel.", "5) Type \"@mokova\" to start. To prevent Mokova from lagging all of Lambda, you will only be able to receive Mokova if system lag is below a certain level. If lag is too high, you'll be given Mokova automatically when lag drops.", "6) Explore and enjoy. The Mokova will wear off on its own, but if you need to instantly sober up, simply type \"@sober\" at any time."} ;;#64246.("feature_verbs") = {"@mokova", "@sober"} ;;#64246.("key") = 0 ;;#64246.("aliases") = {"Mokova dispenser"} ;;#64246.("description") = "A quiet, box-shaped gadget with a brushed aluminum casing and black rubber feet on its bottom corners. As six LEDs blink slowly in an apparently random pattern, a milky blue fluid is gently sloshed back and forth in a tilting, sealed glass vial that juts out of one end of the machine." ;;#64246.("object_size") = {10836, 1043395543} @verb #64246:"@mokova" none none none rxd @program #64246:@mokova "Asks for a dose of Mokova. If system lag is too high at the moment, you won't receive any right away, but will receive it at some point in the future when lag is low enough."; if (this:on_mokova(player)) player:tell("You are currently using Mokova."); elseif (this.queue) if (player in this.queue) player:tell("You are already waiting to use Mokova."); else this.queue = {@this.queue, player}; player:tell("Your name has been added to the queue."); endif else lag = tofloat(this.lag_meter:decimal1(this.lag_meter.total, this.lag_meter.sample_count)); if (lag >= this.lag_threshold) this.queue = {@this.queue, player}; player:tell("It's too laggy right at the moment to give you Mokova. Your name has been added to the queue."); fork cst (this.cst_delay) this:check_start(); endfork else this:_mokova(player); endif endif . @verb #64246:"@sober" none none none rxd @program #64246:@sober "Gives you an instant antidote to Mokova."; recipients = $list_utils:slice(this.chains); if (player in recipients) this:_sober(player); else player:tell("You aren't currently on Mokova."); endif . @verb #64246:"tell_filter" this none this @program #64246:tell_filter calling_objs = $list_utils:slice(callers()); listener = 0; co_ind = 1; while (listener == 0) if (is_player(calling_objs[co_ind])) listener = calling_objs[co_ind]; else co_ind = co_ind + 1; endif endwhile if (this:on_mokova(listener)) word_list = $string_utils:explode(args[1], " "); if (!word_list) return ""; endif listener_ind = $list_utils:iassoc(listener, this.chains); listener_rec = this.chains[listener_ind]; trimmed_list = 0; if (listener_rec[2]) {listener_rec, trimmed_list} = this:get_listener_rec_peaked(listener_rec, listener_ind, listener, word_list, trimmed_list); if (listener_rec == 0) return args[1]; endif else listener_rec = this:get_listener_rec_unpeaked(listener_rec, listener_ind, listener, word_list); if (listener_rec == 0) return args[1]; endif endif this.chains[listener_ind] = listener_rec; output = word_list[1]; next_word = this:get_next_word(output, listener_rec); while (next_word != 0) output = (output + " ") + next_word; next_word = this:get_next_word(next_word, listener_rec); if (this:check_suspend(listener_ind, listener)) return args[1]; endif endwhile if (trimmed_list) fork (0) this:_sober(listener); endfork endif return output; else return args[1]; endif . @verb #64246:"check_start" this none this @program #64246:check_start lag = tofloat(this.lag_meter:decimal1(this.lag_meter.total, this.lag_meter.sample_count)); if (lag <= this.lag_threshold) recipient = 0; while ((recipient == 0) && this.queue) if ($object_utils:connected(this.queue[1])) recipient = this.queue[1]; endif this.queue = {@this.queue[2..$]}; endwhile if (recipient != 0) this:_mokova(recipient); endif else fork (this.cst_delay) this:check_start(); endfork endif . @verb #64246:"_sober" this none this @program #64246:_sober recipient = args[1]; ind = $list_utils:iassoc(recipient, this.chains); if (ind) this.chains = {@this.chains[1..ind - 1], @this.chains[ind + 1..$]}; if ("@sober" in $list_utils:slice(callers(), 2)) player:tell(this.sober_msg); endif recipient:tell(this.mokova_stop_msg); endif . @verb #64246:"_mokova" this none this @program #64246:_mokova recipient = args[1]; recipient:tell(this.mokova_start_msg); this.chains = {@this.chains, {recipient, 0, {}}}; . @verb #64246:"on_mokova" this none this @program #64246:on_mokova return args[1] in $list_utils:slice(this.chains); . @verb #64246:"get_next_word" this none this @program #64246:get_next_word {word, player_rec} = args; word_ind = #94049:iassoc_sorted_cs(word, player_rec[3]); #116857:tell(word_ind); possible_next_words = player_rec[3][word_ind][2]; return possible_next_words[random(length(possible_next_words))]; . @verb #64246:"check_suspend" this none this @program #64246:check_suspend {listener_ind, listener} = args; if ($command_utils:suspend_if_needed(0)) if (!`this.chains[listener_ind][1] == listener ! ANY') return 1; else return 0; endif else return 0; endif . @verb #64246:"trim_word" this none this @program #64246:trim_word {word, word_rec, word_ind, listener_rec, trimmed_list} = args; if (length(word_rec[2]) > 1) word_rec[2] = listdelete(word_rec[2], length(word_rec[2])); elseif (!trimmed_list) if (word_ind < length(listener_rec[3])) trim_ind = word_ind + 1; orig_trim_ind = word_ind; else trim_ind = 1; orig_trim_ind = length(listener_rec[3]); endif while ((trim_ind != orig_trim_ind) && (length(listener_rec[3][trim_ind][2]) == 1)) if (trim_ind < length(listener_rec[3])) trim_ind = trim_ind + 1; else trim_ind = 1; endif endwhile if (trim_ind != orig_trim_ind) listener_rec[3][trim_ind][2] = listdelete(listener_rec[3][trim_ind][2], 1); else trimmed_list = 1; endif endif return {word_rec, listener_rec, trimmed_list}; . @verb #64246:"get_word_rec" this none this @program #64246:get_word_rec {word_ind, word, word_list, inline_count, listener_rec} = args; if ((word_ind != 0) && (!strcmp(listener_rec[3][word_ind][1], word))) word_rec = listener_rec[3][word_ind]; listener_rec[3] = listdelete(listener_rec[3], word_ind); word_ind = word_ind - 1; else word_rec = {word, {}}; endif if (inline_count != length(word_list)) word_rec[2] = {@word_rec[2], word_list[inline_count + 1]}; else word_rec[2] = {@word_rec[2], 0}; endif return {word_ind, word_rec, listener_rec}; . @verb #64246:"get_listener_rec_peaked" this none this @program #64246:get_listener_rec_peaked {listener_rec, listener_ind, listener, word_list, trimmed_list} = args; for inline_count in [1..length(word_list)] word = word_list[inline_count]; word_ind = #94049:iassoc_sorted_cs(word, listener_rec[3]); {word_ind, word_rec, listener_rec} = this:get_word_rec(word_ind, word, word_list, inline_count, listener_rec); if (this:check_suspend(listener_ind, listener)) return {0, 0}; endif {word_rec, listener_rec, trimmed_list} = this:trim_word(word, word_rec, word_ind, listener_rec, trimmed_list); listener_rec[3] = listappend(listener_rec[3], word_rec, word_ind); if (this:check_suspend(listener_ind, listener)) return {0, 0}; endif endfor return {listener_rec, trimmed_list}; . @verb #64246:"get_listener_rec_unpeaked" this none this @program #64246:get_listener_rec_unpeaked {listener_rec, listener_ind, listener, word_list} = args; for inline_count in [1..length(word_list)] word = word_list[inline_count]; word_ind = #94049:iassoc_sorted_cs(word, listener_rec[3]); {word_ind, word_rec, listener_rec} = this:get_word_rec(word_ind, word, word_list, inline_count, listener_rec); listener_rec[3] = listappend(listener_rec[3], word_rec, word_ind); if (this:check_suspend(listener_ind, listener)) return 0; endif endfor if (length(listener_rec[3]) >= #64246.peak) listener_rec[2] = 1; endif return listener_rec; .