Dump of #33337 (Politically Correct Featureful Player Class Created Because Nobody Would @Copy Verbs To 8855)

@create #8855 named Politically Correct Featureful Player Class Created Because Nobody Would @Copy Verbs To 8855:Politically Correct Featureful Player Class Created Because Nobody Would @Copy Verbs To 8855,PC Class
@prop #33337."tell_filter_hook" #-1 r
@prop #33337."last_read_pc_news" 706626366 r
"#33337.("last_player_paged") => E_PERM (Permission denied)
@prop #33337."goto_delay" 5 rc
@prop #33337."use_goto" 0 rc
@prop #33337."map" #33965 rc
"#33337.("idle_watched") => E_PERM (Permission denied)
@prop #33337."pc_options" {} r
;;#33337.("pc_options") = {{"crosspost_list_length", 20}, {"ignore_crossposts", 4}, "prompt_for_long_posts"}
"#33337.("crosspost_list") => E_PERM (Permission denied)
;;#33337.("spoof_attribution") = "     --"
"#33337.("idle_messages") => E_PERM (Permission denied)
"#33337.("respond_to") => E_PERM (Permission denied)
;;#33337.("moved_by") = {}
;;#33337.("sessile") = 0
;;#33337.("eval_subs") = {{"ME", "player"}, {"HERE", "player.location"}}
"#33337.("witnessing") => E_PERM (Permission denied)
;;#33337.("rooms") = {{"Living", #17}, {"Dining", #28}, {"Library", #1670}, {"Pool", #1428}}
"#33337.("messages_going") => E_PERM (Permission denied)
;;#33337.("mail_options") = {"sticky", {"@mail", "new"}}
"#33337.("current_message") => E_PERM (Permission denied)
"#33337.("messages") => E_PERM (Permission denied)
;;#33337.("features") = {#55317, #30203, #40842, #26787}
"#33337.("previous_connection") => E_PERM (Permission denied)
"#33337.("email_address") => E_PERM (Permission denied)
;;#33337.("help") = #55502
"#33337.("linebuffer") => E_PERM (Permission denied)
"#33337.("current_folder") => E_PERM (Permission denied)
"#33337.("all_connect_places") => E_PERM (Permission denied)
"#33337.("last_connect_place") => E_PERM (Permission denied)
"#33337.("lines") => E_PERM (Permission denied)
;;#33337.("pq") = "eirs"
;;#33337.("pqc") = "Eirs"
"#33337.("ownership_quota") => E_PERM (Permission denied)
;;#33337.("prc") = "Eirself"
;;#33337.("ppc") = "Eir"
;;#33337.("poc") = "Em"
;;#33337.("psc") = "E"
;;#33337.("pr") = "eirself"
;;#33337.("pp") = "eir"
;;#33337.("po") = "em"
;;#33337.("ps") = "e"
;;#33337.("home") = #-1
"#33337.("password") => E_PERM (Permission denied)
"#33337.("size_quota") => E_PERM (Permission denied)
"#33337.("last_password_time") => E_PERM (Permission denied)
"#33337.("last_connect_attempt") => E_PERM (Permission denied)
"#33337.("key") => E_PERM (Permission denied)
;;#33337.("aliases") = {"Politically Correct Featureful Player Class Created Because Nobody Would @Copy Verbs To 8855", "PC Class"}
;;#33337.("description") = "You see a player who looks very willing to espouse the proper views on most everything."
;;#33337.("object_size") = {33290, 1141286584}

@verb #33337:"mu*rmur" any any any
@program #33337:murmur
if (length(args) < 2)
  player:tell("EZ-Whisper Usage: mu <player> <message>");
  return;
endif
who = this.location:match_object(args[1]);
if (!$command_utils:object_match_failed(who, args[1]))
  dobjstr = argstr[index(argstr, " ") + 1..length(argstr)];
  iobj = who;
  who:whisper(argstr);
endif
return;
"";
"old version";
"";
if (!valid(who))
  player:tell("\"", args[1], "\"", "is either ambiguous, or that person isn't here.");
  return;
endif
"dobjstr = $string_utils:from_list(listdelete(args, 1), \" \");";
dobjstr = argstr[index(argstr, " ") + 1..length(argstr)];
iobj = who;
who:whisper(argstr);
.

@verb #33337:"@watch" any any any
@program #33337:@watch
"Watch a player to see when they type a command.";
"@watch <player>   to begin watching";
"@watch none|off   to stop watching";
"@watch            to see who you're watching";
if (this != player)
  player:tell("I don't understand that.");
  return E_PERM;
endif
if ((argstr == "off") || (argstr == "none"))
  if (valid(this.idle_watched))
    player:tell(("You stop watching " + this.idle_watched.name) + ".");
    this.idle_watched = #-1;
    return;
  else
    player:tell("You're not currently watching anyone.");
    return;
  endif
endif
if (!argstr)
  if (valid(this.idle_watched) && is_player(this.idle_watched))
    player:tell($string_utils:pronoun_sub("You are watching %n (%[#n]).", this.idle_watched));
  else
    player:tell("You are not watching anyone.");
  endif
  return;
endif
target = $string_utils:match_player(argstr);
if (!valid(target))
  player:tell("I don't know who that is.");
  return;
else
  this.idle_watched = target;
  this:tell($string_utils:pronoun_sub("You begin watching %n (%[#n]).", target));
  "Notice that .idle_watched is expected to change during the suspend whereas ic is not.";
  while ((valid(ic = this.idle_watched) && (ic in connected_players())) && (this in connected_players()))
    if (idle_seconds(ic) < 30)
      this:tell("[", ic.name, "]");
    endif
    "$command_utils:suspend(30);";
    suspend(30);
  endwhile
endif
.

@verb #33337:"goto" any none none rxd
@program #33337:goto
player:tell("Please use @go ", argstr, " instead; this verb is too spammy to use any more.");
return;
if (!valid(dobj))
  player:tell("Searching room names...");
  dobj = $string_utils:match(dobjstr, this.map.rooms, "name");
endif
if (valid(dobj))
  player:tell("Getting path to ", dobj.name, ".");
  path = {};
  path = this.map:path_from_A_to_B(this.location, dobj);
  if (typeof(path) != LIST)
    return E_NACC;
  endif
  path = path[2];
  player:tell("Executing path.");
  i = 0;
  "this.brief = 1;";
  this:set_brief(1, "add");
  len = length(path);
  for exit in (path)
    i = i + 1;
    "player:tell(i, \" \", len);";
    if (i >= len)
      this:set_brief(-1, "add");
    endif
    exit:move(this);
    $command_utils:suspend(this.goto_delay);
  endfor
  "this:set_brief(-1, \"add\");";
  return 1;
else
  player:tell("Could not find ", dobjstr, ".");
  return E_NACC;
endif
.

@verb #33337:"teleport" this none this
@program #33337:teleport
if ((!this.use_goto) || (args[1] != this))
  return pass(@args);
else
  old = dobj;
  dobj = args[2];
  if (!this:goto())
    return pass(@args);
  endif
  dobj = old;
endif
.

@verb #33337:"@who(old)" any any any rxd
@program #33337:@who(old)
argstr = dobjstr = "";
prepstr = iobjstr = "";
dobj = iobj = #-1;
pass(@args);
.

@verb #33337:"'*" any any any r
@program #33337:'
" [EZ-Page]             Page: '<player> [<message>]";
"                    Respond: ' <message>";
"";
" EZ-Page responds to the player last contacted with \"'\"";
if ((verb == "'") && (!argstr))
  player:tell_lines($code_utils:verb_documentation(#33337, "'"));
else
  if (verb == "'")
    who = this.last_player_paged;
  else
    who = this.last_player_paged = verb[2..length(verb)];
  endif
  argstr = tostr("\"", who, "\" ", $code_utils:argstr(verb, args, argstr));
  this:page(who, @args);
endif
.

@verb #33337:"receive_shout" this none this rx
@program #33337:receive_shout
if (this.shout_state_shm)
  this:tell(args[2]);
endif
.

@verb #33337:"_who's_infidel_slime" this none this rx
@program #33337:_who's_infidel_slime
"Called by \"who's schmooed\"";
connected_players = connected_players();
where_name = "logged on";
no_one = "No other infidel slime are %l.";
someone = "%w %b %l.";
who_all = {};
for thing in (connected_players)
  if (thing.shout_state_shm && (!$object_utils:isa(thing, #4803)))
    who_all = {@who_all, thing};
  endif
endfor
wo = this:feature("who's");
player:tell(wo:("who's_substitute")(who_all ? someone | no_one, $list_utils:map_arg(wo, "who's_title", who_all), where_name));
su = $string_utils;
.

@verb #33337:"feature" this none this
@program #33337:feature
"feature(name)";
"Match name against this.features' aliases, return object, $nothing, $ambigous_match, or $failed_match as per $string_utils:match or the parser.";
return $string_utils:match(args[1], this.features, "aliases");
.

@verb #33337:"confunc" this none this
@program #33337:confunc
this:clear_tell_filter_instructions();
this:clear_crosspost_list();
pass(@args);
if (this.last_read_pc_news < #19664.last_written)
  player:tell("There is new news on #33337, the PC Player Class.  Type @pc-news to read it.");
endif
.

@verb #33337:"@pc-news" none none none
@program #33337:@pc-news
player:tell("PC News written by Jonny at ", player:time_stamp_msg(#19664.last_written), ":");
player:tell("");
player:tell_lines(#19664:text());
player:tell("");
player:tell("(You finish reading.)");
player.last_read_pc_news = time();
.

@verb #33337:"@tell-filter*-hook" none none none r
@program #33337:@tell-filter-hook
filter_object = this.tell_filter_hook;
if (valid(filter_object))
  message = $string_utils:pronoun_sub("Your tell-filter is %t (%[#t]).", this, filter_object);
else
  message = "Your tell-filter is unset.";
endif
this:unfiltered_tell(message);
this:clear_tell_filter_instructions();
.

@verb #33337:"unfiltered_tell" this none this rx
@program #33337:unfiltered_tell
if (caller == this)
  filter = this.tell_filter_hook;
  this.tell_filter_hook = $nothing;
  result = this:tell(@args);
  this.tell_filter_hook = filter;
  return result;
else
  return E_PERM;
endif
.

@verb #33337:"@set-tell-filter*-hook" any none none r
@program #33337:@set-tell-filter-hook
if (player != this)
  player:tell("Permission denied.");
  return;
endif
if (!valid(dobj))
  player:unfiltered_tell("Either that is ambiguous or it does not exist.");
  player:clear_tell_filter_instructions();
  return;
endif
if (!$object_utils:has_callable_verb(dobj, "tell_filter"))
  player:unfiltered_tell("That object does not have a callable :tell_filter verb, and thus can not be used as a tell-filter.");
  player:clear_tell_filter_instructions();
  return;
endif
message = "Tell-filter set to %t (%[#t]), which is owned by %n (%[#n]).";
player:unfiltered_tell($string_utils:pronoun_sub(message, dobj.owner, dobj));
player:unfiltered_tell("Be aware that this object receives most text directed at you, and can modify it before it reaches you.");
player.tell_filter_hook = dobj;
player:clear_tell_filter_instructions();
.

@verb #33337:"clear_tell_filter_instructions" this none this rx
@program #33337:clear_tell_filter_instructions
if (caller != this)
  return E_PERM;
else
  if (valid(this.tell_filter_hook))
    player:unfiltered_tell("Type @unset-tell-filter to clear your tell-filter.");
  endif
endif
.

@verb #33337:"@unset-tell-filter*-hook @clear-tell-filter*-hook" none none none r
@program #33337:@unset-tell-filter-hook
player.tell_filter_hook = $nothing;
player:tell("Tell-filter cleared.");
.

@verb #33337:"tell" this none this rx
@program #33337:tell
if (0)
  cache_correct = 0;
  for slice in (callers())
    if (#90332 in slice)
      if (cache_correct && (!cache))
        return;
      elseif (cache_correct && cache)
        "nothing. my kingdom for a break statement.";
      else
        cache = this:pc_option("no_ostracism");
        if (!cache)
          return;
        endif
      endif
    endif
  endfor
endif
if ($recycler:valid(this.tell_filter_hook))
  filtered = this.tell_filter_hook:tell_filter(tostr(@args));
  if (typeof(filtered) == STR)
    return pass(filtered);
  else
    return;
  endif
elseif (valid(this.tell_filter_hook))
  this.tell_filter_hook = #-1;
  "E's managed to get a Recyclable into eir tell filter hook.  GC it. --yduJ";
endif
return pass(@args);
.

@verb #33337:"linesplit" this none this rx
@program #33337:linesplit
if (valid(this.tell_filter_hook))
  filtered = this.tell_filter_hook:linesplit_filter(@args);
  if (typeof(filtered) != ERR)
    return filtered;
  endif
endif
return pass(@args);
.

@verb #33337:"who(old)" any none none rxd
@program #33337:who(old)
"Quinn's WHO. Usage: WHO [idle-minutes-included]";
"                        [    default == 5m    ]";
idles = tonum(dobjstr) * 60;
idles = (idles < 1) ? 300 | idles;
su = $string_utils;
who = connected_players();
wholist = {};
for x in (who)
  l = x.location;
  hoot = idle_seconds(x);
  if (hoot <= idles)
    t = (tonum(l) < 1) ? "nothing (#-1)" | l.name;
    l = (length(t) > 12) ? t[1..12] | t;
    l = su:left(l, 12, ".");
    n = (length(x.name) > 12) ? x.name[1..12] | x.name;
    n = su:left(n, 12, ".");
    "xinfo = l + n + \":\" + tostr(x.gender, \" \")[1..1] + \"|\" + t;";
    xinfo = ((l + n) + "|") + t;
    wholist = {@wholist, xinfo};
  endif
endfor
wholist = $list_utils:sort(wholist);
sortee = {};
for z in (wholist)
  sortee = {@sortee, z[13..length(z)]};
endfor
col = (length(sortee) < 11) ? 1 | 2;
player:tell_lines(su:columnize(sortee, col));
.

@verb #33337:"#33337:@audit(old)" any any any rx
@program #33337:#33337:@audit(old)
"Copied from APHiD (#31783):@audit Tue Mar 16 10:52:05 1993 PST";
"Usage:  @audit [player] [from <start>] [to <end>] [for <matching string>]";
set_task_perms(player);
dobj = $string_utils:match_player(dobjstr);
if (!dobjstr)
  dobj = player;
elseif ($command_utils:player_match_result(dobj, dobjstr)[1])
  return;
endif
dobjwords = $string_utils:words(dobjstr);
if (args[1..length(dobjwords)] == dobjwords)
  args = args[length(dobjwords) + 1..length(args)];
endif
if (!(parse_result = $code_utils:_parse_audit_args(@args)))
  player:tell("Usage:  @audit [player] [from <start>] [to <end>] [for<match>]");
  return;
endif
start = parse_result[1];
end = parse_result[2];
match = parse_result[3];
player:tell("Objects owned by ", valid(dobj) ? dobj.name | dobj, ((" (from #" + tostr(start)) + " to #") + tostr(end), match ? " matching " + match | "", ")", ":");
count = 0;
for i in (dobj.owned_objects)
  if ((start <= tonum(i)) && (tonum(i) <= end))
    o = toobj(i);
    if ($command_utils:running_out_of_time())
      suspend(0);
    endif
    if (valid(o) && (o.owner == dobj))
      found = 0;
      names = {o.name, @o.aliases};
      while (names && (!found))
        if (index(names[1], match))
          found = 1;
        endif
        names = listdelete(names, 1);
      endwhile
      if (found)
        if (valid(o.location))
          loc = (" [" + o.location.name) + "]";
        elseif ($object_utils:has_property(o, "dest") && $object_utils:has_property(o, "source"))
          if (!valid(o.source))
            source = "Nowhere";
          else
            source = o.source.name;
          endif
          if (!valid(o.dest))
            destin = "Nowhere";
          else
            destin = o.dest.name;
          endif
          srclen = (length(source) < 20) ? length(source) | 19;
          destlen = (length(destin) < 20) ? length(destin) | 19;
          loc = ((" " + source[1..srclen]) + "->") + destin[1..destlen];
        elseif ($object_utils:isa(o, $room))
          loc = "";
        else
          loc = " [Nowhere]";
        endif
        if (length(loc) > 41)
          loc = loc[1..37] + "..]";
        endif
        namelen = (length(o.name) < 30) ? length(o.name) | 29;
        player:tell($string_utils:left(o, 7), $string_utils:left(o.name[1..namelen], 30), $string_utils:left(loc, 15));
        count = count + 1;
      endif
    endif
  endif
endfor
player:tell("Total: ", count, " object", (count == 1) ? "." | "s.");
.

@verb #33337:"@pc-opt*ions @pcopt*ions" any any any
@program #33337:@pc-options
"@pc-option <option> [is] <value>   sets <option> to <value>";
"@pc-option <option>=<value>        sets <option> to <value>";
"@pc-option +<option>     sets <option>   (usually equiv. to <option>=1";
"@pc-option -<option>     resets <option> (equiv. to <option>=0)";
"@pc-option !<option>     resets <option> (equiv. to <option>=0)";
"@pc-option <option>      displays value of <option>";
if (player != this)
  player:tell("You can't set options on other players.");
  return;
endif
what = "pc";
options = what + "_options";
option_pkg = #40525;
set_option = ("set_" + what) + "_option";
if (!args)
  player:notify_lines({("Current " + what) + " options:", "", @option_pkg:show(this.(options), option_pkg.names)});
  return;
elseif (typeof(presult = option_pkg:parse(args)) == STR)
  player:notify(presult);
  return;
else
  if (length(presult) > 1)
    if (typeof(sresult = this:(set_option)(@presult)) == STR)
      player:notify(sresult);
      return;
    elseif (!sresult)
      player:notify("No change.");
      return;
    endif
  endif
  player:notify_lines(option_pkg:show(this.(options), presult[1]));
endif
.

@verb #33337:"message_length" this none this
@program #33337:message_length
":message_length(LIST message_body) => Length of message in `lines', which is arbitrarily defined as $player:linelen() characters.";
body = args[1];
body = (typeof(body) == LIST) ? body | {body};
mlen = 0;
for line in (body)
  mlen = mlen + length(tostr(line));
endfor
return mlen / $player:linelen();
.

@verb #33337:"time_stamp_msg" this none this
@program #33337:time_stamp_msg
":time_stamp_msg(NUM)  =>  string of NUM as time converted to this player's favored time format";
"Will be overridden on subclasses.";
return ctime(args[1]);
.

@verb #33337:"msg_text(verbose)" this none this
@program #33337:msg_text(verbose)
":msg_text(@msg) => message in text form (suitable for printing)";
"This verb gives warning and escape from long messages, primitive crosspost skipping, and an alternate display format.";
"";
"In place of a ctime() call to display message times, this:time_stamp_msg() is used, in order for subclasses to override.";
"";
"Copied from Revenant Player Class (#5409):msg_text by Quinn (#19845) Mon Feb  8 01:33:39 1993 PST";
"Hacked on by Jonny to use pc option package.";
"Hacked on further to do flames refusal mechanism.";
"Hacked more to skip all the fancy checks if invoked with @peek.";
"Hacked on even more to skip messages crossposted to more than n lists.";
"Hacked on more to add an option to flat-out skip long messages without prompting.";
from = args[2];
fromobj = $mail_agent:parse_address_field(from);
if ((typeof(fromobj) == LIST) && (length(fromobj) == 1))
  fromobj = fromobj[1];
else
  fromobj = #-1;
endif
subject = args[4];
body = args[5..length(args)];
skip_crossposts = #40525:get(this.pc_options, "skip_crossposts");
maxlen = #40525:get(this.pc_options, "max_message_length");
recips = args[3];
invoking_verb = callers()[length(callers())][2];
override_everything = invoking_verb == "@peek";
if (!override_everything)
  max_count = #40525:get(this.pc_options, "ignore_crossposts");
  if (max_count)
    mailing_lists = 0;
    remaining_recips = " " + recips;
    while (pos = index(remaining_recips, " *"))
      remaining_recips = remaining_recips[pos + 2..length(remaining_recips)];
      mailing_lists = mailing_lists + 1;
    endwhile
  endif
  if (this:refuses_action(fromobj, "flames"))
    body = {"", ("[ Flame from " + from) + " skipped. ]", ""};
  elseif (max_count && (mailing_lists > max_count))
    body = {"", ("[ Ignored due to crosspost limit; mailing list count: " + tostr(mailing_lists)) + " ]", ""};
  elseif (skip_crossposts && (index(recips, ",") || index(recips, " and ")))
    if (args[1..4] in this.crosspost_list)
      body = {"", "[ Previously seen text omitted. ]", ""};
    else
      crosspost_list_length = #40525:get(this.pc_options, "crosspost_list_length");
      this.crosspost_list = mr = setadd(this.crosspost_list, args[1..4]);
      if ((lmr = length(mr)) > crosspost_list_length)
        this.crosspost_list = mr[lmr - crosspost_list_length..lmr];
      endif
    endif
  endif
endif
if (((!override_everything) && maxlen) && ((length = this:message_length(body)) > maxlen))
  prompt = #40525:get(this.pc_options, "prompt_for_long_posts");
  if (prompt)
    if (!$command_utils:yes_or_no(tostr("The following message from ", from, " concerning \"", subject, "\" is ", length, " lines long.  Do you still wish to read it?")))
      body = {"", "[ Long message skipped. ]", ""};
    endif
  else
    body = {"", "[ Long message skipped. ]", ""};
  endif
endif
$command_utils:suspend_if_needed(0);
return {tostr("Date:    ", this:time_stamp_msg(args[1])), tostr("From:    ", from), tostr("To:      ", args[3]), @(args[4] == " ") ? {} | {tostr("Subject: ", subject)}, @body};
.

@verb #33337:"set_pc_option" this none this
@program #33337:set_pc_option
if (caller != this)
  return E_PERM;
endif
new = #40525:set(this.pc_options, @args);
if (typeof(new) == LIST)
  this.pc_options = new;
  return 1;
else
  return new;
endif
.

@verb #33337:"refusable_actions" this none this
@program #33337:refusable_actions
return {@pass(@args), "entry", "flames"};
.

@verb #33337:"refuses_action_flames" this none this
@program #33337:refuses_action_flames
return 1;
.

@verb #33337:"refuses_action_entry" this none this
@program #33337:refuses_action_entry
return 1;
.

@verb #33337:"implements_entry_refusal" this none this
@program #33337:implements_entry_refusal
return 1;
.

@verb #33337:"friends_of" this none this
@program #33337:friends_of
return {};
.

@verb #33337:"receive_page" this none this
@program #33337:receive_page
result = pass(@args);
argstr = dobjstr = iobjstr = prepstr = "";
return result;
.

@verb #33337:"erase_paranoid_data" this none this
@program #33337:erase_paranoid_data
pc_opt = #40525;
if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
  return E_PERM;
elseif (!pc_opt:get(this.pc_options, "paranoid_data"))
  pass(@args);
endif
.

@verb #33337:"pc_option" this none this rxd #4292
@program #33337:pc_option
":pc_option(name)";
"Returns the value of the specified pc option";
if ((caller == this) || $perm_utils:controls(caller_perms(), this))
  return #40525:get(this.pc_options, args[1]);
else
  return E_PERM;
endif
.

@verb #33337:"disfunc" this none this
@program #33337:disfunc
this:clear_crosspost_list();
pass(@args);
.

@verb #33337:"moveto" this none this
@program #33337:moveto
if (player == #72441)
  "lose";
  return 0;
else
  return pass(@args);
endif
.

@verb #33337:"msg_text" this none this rxd #26947
@program #33337:msg_text
":msg_text(@msg) => message in text form (suitable for printing)";
"This verb gives warning and escape from long messages, primitive crosspost skipping, and an alternate display format.";
"";
"In place of a ctime() call to display message times, this:time_stamp_msg() is used, in order for subclasses to override.";
"";
"Copied from Revenant Player Class (#5409):msg_text by Quinn (#19845) Mon Feb  8 01:33:39 1993 PST";
"Hacked on by Jonny to use pc option package.";
"Hacked on further to do flames refusal mechanism.";
"Hacked more to skip all the fancy checks if invoked with @peek.";
"Hacked on even more to skip messages crossposted to more than n lists.";
"Hacked on more to add an option to flat-out skip long messages without prompting.";
from = args[2];
fromobj = $mail_agent:parse_address_field(from);
if ((typeof(fromobj) == LIST) && (length(fromobj) == 1))
  fromobj = fromobj[1];
else
  fromobj = #-1;
endif
subject = args[4];
body = args[5..length(args)];
skip_crossposts = #40525:get(this.pc_options, "skip_crossposts");
maxlen = #40525:get(this.pc_options, "max_message_length");
recips = args[3];
invoking_verb = callers()[length(callers())][2];
override_everything = invoking_verb == "@peek";
if (!override_everything)
  max_count = #40525:get(this.pc_options, "ignore_crossposts");
  if (max_count)
    mailing_lists = 0;
    remaining_recips = " " + recips;
    while (pos = index(remaining_recips, " *"))
      remaining_recips = remaining_recips[pos + 2..length(remaining_recips)];
      mailing_lists = mailing_lists + 1;
    endwhile
  endif
  if (this:refuses_action(fromobj, "flames"))
    lines = 0;
    for line in (body)
      lines = (lines + 1) + (length(line) / 80);
    endfor
    return {tostr("    [ Flame from ", from, " skipped: ", lines, " lines. ]")};
    body = {"", ("[ Flame from " + from) + " skipped. ]", ""};
  elseif (max_count && (mailing_lists > max_count))
    body = {"", ("[ Ignored due to crosspost limit; mailing list count: " + tostr(mailing_lists)) + " ]", ""};
  elseif (skip_crossposts && (index(recips, ",") || index(recips, " and ")))
    if (args[1..4] in this.crosspost_list)
      body = {"", "[ Previously seen text omitted. ]", ""};
    else
      crosspost_list_length = #40525:get(this.pc_options, "crosspost_list_length");
      this.crosspost_list = mr = setadd(this.crosspost_list, args[1..4]);
      if ((lmr = length(mr)) > crosspost_list_length)
        this.crosspost_list = mr[lmr - crosspost_list_length..lmr];
      endif
    endif
  endif
endif
if (((!override_everything) && maxlen) && ((length = this:message_length(body)) > maxlen))
  prompt = #40525:get(this.pc_options, "prompt_for_long_posts");
  if (prompt)
    if (!$command_utils:yes_or_no(tostr("The following message from ", from, " concerning \"", subject, "\" is ", length, " lines long.  Do you still wish to read it?")))
      body = {"", "[ Long message skipped. ]", ""};
    endif
  else
    body = {"", "[ Long message skipped. ]", ""};
  endif
endif
$command_utils:suspend_if_needed(0);
return {tostr("Date:    ", this:time_stamp_msg(args[1])), tostr("From:    ", from), tostr("To:      ", args[3]), @(args[4] == " ") ? {} | {tostr("Subject: ", subject)}, @body};
.

@verb #33337:"busted-dash-verb" any any any rxd
@program #33337:busted-dash-verb
name = verb[2..length(verb)];
who = player.location:match_object(name);
argstr = $code_utils:argstr(verb, args, argstr);
if (!valid(who))
  player.location:announce_all(player.name, " [", name, "]: ", argstr);
else
  player.location:announce_all(player.name, " [to ", who.name, "]: ", argstr);
endif
.

@verb #33337:"`*" any any any rxd
@program #33337:`
name = verb[2..length(verb)];
who = player.location:match_object(name);
if ($command_utils:object_match_failed(who, name))
  return;
endif
player.location:announce_all(player.name, " [to ", who.name, "]: ", argstr);
return;
"Say something out loud, directed at someone or something.";
"Usage:";
"  `target message";
"Example:";
"  Munchkin is talking to Kenneth, who's in the same room with him.  He types:";
"      `kenneth What is the frequency?";
"  The room sees:";
"       Munchkin [to Kenneth]: What is the frequency?";
.

@verb #33337:"clear_crosspost_list" this none this rxd #26947
@program #33337:clear_crosspost_list
(caller == this) || lose;
this.crosspost_list = {};
.

@verb #33337:"do_out_of_band_command" this none this
@program #33337:do_out_of_band_command
return;
"Until somebody explains to me why tracebacks are the best diagnostic for having no MCP handler.";
.

@verb #33337:"notify_33337" this none this
@program #33337:notify_33337
if (caller != #106616)
  return E_PERM;
endif
return this:notify(@args);
.

@verb #33337:"@who" any any any rxd
@program #33337:@who
"Copied from generic player (#6):@who by ur-Rog (#6349) Tue Sep  1 10:04:21 1998 PDT";
if (caller != player)
  return E_PERM;
endif
plyrs = args ? listdelete($command_utils:player_match_result($string_utils:match_player(args), args), 1) | connected_players();
if (!plyrs)
  return;
elseif (length(plyrs) > 200)
  player:tell("You have requested a listing of ", length(plyrs), " players.  Please either specify individual players you are interested in, to reduce the number of players in any single request, or else use the `@users' command instead.  The lag thanks you.");
  return;
endif
laundry = #106616;
if (1 || (random(100) < 30))
  "not now honey...I have to run by the laundry...";
  util = laundry;
else
  util = $code_utils;
endif
util:show_who_listing(plyrs);
.

@verb #33337:"@who-anon" any any any rxd
@program #33337:@who-anon
"Copied from generic player (#6):@who by ur-Rog (#6349) Tue Sep  1 10:04:21 1998 PDT";
if (caller != player)
  return E_PERM;
endif
plyrs = args ? listdelete($command_utils:player_match_result($string_utils:match_player(args), args), 1) | connected_players();
if (!plyrs)
  return;
elseif (length(plyrs) > 100)
  player:tell("You have requested a listing of ", length(plyrs), " players.  Please either specify individual players you are interested in, to reduce the number of players in any single request, or else use the `@users' command instead.  The lag thanks you.");
  return;
endif
laundry = #106616;
if (random(100) < 100)
  "not now honey...I have to run by the laundry...";
  util = laundry;
else
  util = $code_utils;
endif
util:show_who_listing(plyrs);
.

"***finished***