Dump of #7680 (Generic Puppet)

@create $gendered_object named Generic Puppet:Generic Puppet
@prop #7680."seek_failed_msg" "%n bounces off a topographical barrier, and into the room." rc
@prop #7680."seek_arrive_msg" "%n arrives, of necessity by an ugly method." rc
@prop #7680."seek_leave_msg" "%n leaves, of necessity by an ugly method." rc
@prop #7680."home2" #11 rc
@prop #7680."home" #1138 rc
@prop #7680."brief" 0 rc
@prop #7680."debug" 0 rc
@prop #7680."simulating" 1 rc
@prop #7680."command_ok" {} rc
"#7680.("listen_actions") => E_PERM (Permission denied)
@prop #7680."monitor_ok" {} rc
@prop #7680."echo_prefix_msg" "  (%n) " rc
@prop #7680."tell_forward" {} r
@prop #7680."linelen" 79 rc
@prop #7680."feature_pc" #7069 rc
"#7680.("key") => E_PERM (Permission denied)
;;#7680.("aliases") = {"Generic Puppet"}
;;#7680.("object_size") = {18040, 1141286558}

@verb #7680:"com*mand" this to any rxd #78
@program #7680:command
"command <puppet> to <cmdline>";
"Command the puppet to `do' the given command line, processing it as if it were a command issued by a player.";
"who = (callers() && (caller != this)) ? caller_perms() | player;";
who = callers() ? caller_perms() | player;
set_task_perms(who);
if (this:command_ok(who))
  text = substitute("%1", $sysobj:match(argstr, ("%<" + prepstr) + "%> *%(.+%)$"));
  if (text)
    who:tell("You transmit the command \"", text, "\" to ", this.name, ".");
    this:do(text);
  else
    who:tell("Transmit what to ", this.name, "?");
  endif
else
  who:tell($string_utils:pronoun_sub("%n %<ignores> your command.", this));
  return E_PERM;
endif
.

@verb #7680:"mon*itor" this none none rxd
@program #7680:monitor
"mon*itor <puppet>";
"Have everything heard by the puppet relayed back to you.";
who = (callers() && (caller != this)) ? caller_perms() | player;
if (this:monitor_ok(who))
  this:add_monitor(who);
  this:tell(who.name, " starts monitoring.");
else
  who:tell($string_utils:pronoun_sub("%n %<doesn't> want you monitoring %o.", this));
  this:tell($string_utils:nn(who), " is refused permission to monitor.");
  return E_PERM;
endif
.

@verb #7680:"ign*ore" this none none rxd
@program #7680:ignore
"ignore <puppet>";
"Stop monitoring the puppet.";
who = (callers() && (caller != this)) ? caller_perms() | player;
if (who in this.tell_forward)
  this:tell(who.name, " stops monitoring.");
  this:remove_monitor(who);
else
  who:tell("You aren't listening to ", this.name, ".");
endif
.

@verb #7680:"tell" this none this
@program #7680:tell
pass(@args);
this:tell2(@args);
.

@verb #7680:"moveto" this none this
@program #7680:moveto
"Do a fake :look_self check with the puppet as `player'.";
{dest} = args;
old = this.location;
if ((this == $local.puppet) && ((old == this.home) || (dest != this.home)))
  return E_PERM;
endif
pass(dest);
where = this.location;
if ((this.tell_forward && (where != old)) && valid(where))
  this:call_as_puppet(where, "look_self", {this.brief});
endif
"Quinn 09-DEC-93 0223: Added call_as_puppet line to prevent weird spoofs.";
"THX (#105941) - Thu Dec 14, 2000 - Put in a check for $local.puppet so it doesn't get moved willy-nilly.";
.

@verb #7680:"wh*isper" any to this rxd
@program #7680:whisper
this:tell(player.name, " whispers, \"", dobjstr, "\"");
player:tell("You whisper, \"", dobjstr, "\" to ", this.name, ".");
.

@verb #7680:"acceptable" this none this
@program #7680:acceptable
{what} = args;
return !is_player(what);
.

@verb #7680:"look_self" this none this
@program #7680:look_self
pass(@args);
if (this.simulating)
  if ((time = this:idle_time()) == 999999999)
    player:tell($string_utils:pronoun_sub("%S %<is> sleeping.", this));
  elseif (time < 120)
    player:tell($string_utils:pronoun_sub("%S %<is> awake and %<looks> alert.", this));
  else
    time = $string_utils:from_seconds(time);
    player:tell($string_utils:pronoun_sub(("%S %<is> awake, but %<has> been %<staring off into space> for " + time) + ".", this));
  endif
  if (this.contents)
    player:tell("Carrying:");
    for thing in (this.contents)
      player:tell("  ", thing:title());
    endfor
  endif
endif
.

@verb #7680:"sweep_msg" this none this
@program #7680:sweep_msg
if (y = setremove(this.tell_forward, player))
  return "is listening for " + $string_utils:nn_list(y);
endif
.

@verb #7680:"monitor_ok command_ok" this none this
@program #7680:monitor_ok
{who} = args;
return who in {this.owner, $code_utils:verb_loc().owner, @this.(verb)};
.

@verb #7680:"idle_time" this none this
@program #7680:idle_time
time = 999999999;
for who in (setadd((typeof(y = this.command_ok) == LIST) ? y | {}, this.owner))
  if (((who in connected_players()) && ((who in this.tell_forward) || (who.location == this.location))) && (time > (y = idle_seconds(who))))
    time = y;
  endif
endfor
return time;
.

@verb #7680:"seek" any none none rxd
@program #7680:seek
return this.feature_pc:(verb)(@args);
.

@verb #7680:"tell2" this none this rx #49853
@program #7680:tell2
if (typeof(set_task_perms(this.owner)) == ERR)
  return E_PERM;
endif
for q in (this.tell_forward)
  q:tell($string_utils:pronoun_sub(this.echo_prefix_msg, this), @args);
endfor
text = tostr(@args);
for q in (this.listen_actions)
  if (y = $string_utils:match_string(text, q[1]))
    fork (0)
      comm = q[2][random(length(q[2]))];
      if (typeof(y) == LIST)
        for w in (y)
          comm = strsub(comm, "%" + tostr(w in y), w);
        endfor
      endif
      this:do(comm, @q[3..length(q)]);
      return;
    endfork
  endif
endfor
.

@verb #7680:"is_listening" this none this rxd #49853
@program #7680:is_listening
for x in (this.tell_forward)
  if (x:is_listening())
    return 1;
  endif
endfor
return 0;
.

@verb #7680:"linelen" this none this
@program #7680:linelen
"Copied from generic player (#6):linelen by Hacker (#18105) Fri Oct 30 15:50:47 1992 PST";
return abs(this.linelen);
.

@verb #7680:"i inv*entory" none none none rxd
@program #7680:i
"originally from $player:inv";
if (this.contents)
  c = this.contents;
  longear = {};
  gear = {};
  width = player:linelen();
  half = width / 2;
  player:tell("Carrying:");
  for thing in (c)
    cx = tostr(" ", thing:title());
    if (length(cx) > half)
      longear = {@longear, cx};
    else
      gear = {@gear, cx};
    endif
  endfor
  this:tell_lines($string_utils:columnize(gear, 2, width));
  this:tell_lines(longear);
else
  this:tell("You are empty-handed.");
endif
.

@verb #7680:"parse_command" this none this
@program #7680:parse_command
":parse_command(cmdline-string) Pass to $string_utils by default.";
$local.rpg:s_i_n(0);
return $string_utils:parse_command(@args);
"THX (#105941) - Wed Dec 20, 2000 - Stuffed a suspend check in 'ere.";
.

@verb #7680:"call_as_puppet" this none this rxd #2487
@program #7680:call_as_puppet
"-- WIZARDLY --";
":call_as_puppet(object, verbname, args)";
"Calls the given verb, after setting 'player' to this 'puppet'.";
if ((caller == this) || $perm_utils:controls(caller_perms(), this))
  actual = player;
  player = this;
  result = this:call(this, @args);
  player = actual;
  return result;
else
  return E_PERM;
endif
.

@verb #7680:"add_monitor" this none this
@program #7680:add_monitor
":add_monitor(who)";
if ((caller == this) || $perm_utils:controls(caller_perms(), this))
  {who} = args;
  if (who != this)
    return this.tell_forward = setadd(this.tell_forward, who);
  endif
else
  return E_PERM;
endif
.

@verb #7680:"remove_monitor" this none this
@program #7680:remove_monitor
":remove_monitor(who)";
if ((caller == this) || $perm_utils:controls(caller_perms(), this))
  {who} = args;
  return this.tell_forward = setremove(this.tell_forward, who);
else
  return E_PERM;
endif
.

@verb #7680:"my_match_object" this none this
@program #7680:my_match_object
"Copied from generic player (#6):my_match_object by ur-Rog (#6349) Mon May  5 16:29:14 1997 PDT";
":my_match_object(string [,location])";
return $string_utils:match_object(@{@args, this.location}[1..2], this);
.

@verb #7680:"my_match_recipient" this none this
@program #7680:my_match_recipient
return $failed_match;
.

@verb #7680:"do" this none this rxd #49853
@program #7680:do
if (this:command_ok(cp = caller_perms()) || (caller == this))
  who = cp.wizard ? player | cp;
  {text, @now} = args;
  brev = {"\"", ":", ";", "?"};
  rep = {"say ", "emote ", "eval", "help"};
  if (indx = `text[1] ! E_RANGE => " "' in brev)
    text = rep[indx] + text[2..$];
  endif
  if ((y = this:parse_command(text, this)) && valid(this.location))
    player = this;
    {verb, d, p, i, a, s} = y;
    {dobj, dobjstr} = d;
    {prep, prepstr} = p;
    {iobj, iobjstr} = i;
    {args, argstr} = a;
    verbargs = {s, {dobj, prep, iobj}};
    if (this:find_verb(player, verb, @verbargs))
      "this:call(who, player, verb, args, @now);";
      this:call_as_puppet(player, verb, args, @now);
    elseif (this:find_verb(player.location, verb, @verbargs))
      "this:call(who, player.location, verb, args, @now);";
      this:call_as_puppet(player.location, verb, args, @now);
    elseif (this:find_verb(dobj, verb, @verbargs))
      "this:call(who, dobj, verb, args, @now);";
      this:call_as_puppet(dobj, verb, args, @now);
    elseif (this:find_verb(iobj, verb, @verbargs))
      "this:call(who, iobj, verb, args, @now);";
      this:call_as_puppet(iobj, verb, args, @now);
    else
      "Comment out for now; should replace with correct huh sequence.";
      "this:call_as_puppet(who, player.location, \"huh2\", {verb, args}, @now)";
      "... Rog suggests:";
      "this:call(who, $command_utils, \"do_huh\", {verb, args}, @now);";
      "Recent change as per 6178-6182 on *wiz Ho_Yan 8/23/99. And above lines too.";
      this:call_as_puppet($command_utils, "do_huh", {verb, args}, @now);
    endif
  else
    "1/15/96, Heathcliff";
    this:tell("I don't understand that.");
  endif
else
  return E_PERM;
endif
"Mooshie (#106469) - Sat Dec 27, 1997 - Sped up, 1.8.0 conventions, etc.";
.

@verb #7680:"find_verb" this none this
@program #7680:find_verb
{where, vrb, match, split, @rest} = args;
if (valid(where) && (def = $object_utils:has_verb(where, vrb)))
  {def} = def;
  if (`{first, second, third} = `verb_args(def, vrb) ! E_PERM' ! E_TYPE' in {{"this", "none", "this"}, E_TYPE})
    return 0;
    "make sure to exclude this none this verbs";
  endif
  {ds, ps, is} = match;
  {do, pn, io} = split;
  {owner, perms, name} = verb_info(def, vrb);
  return index(perms, "x") && (((((first == "this") && (where == do)) || (first in ds)) || (second in ps)) && (((third == "this") && (where == io)) || (third in is)));
endif
return 0;
"Mooshie (#106469) - Wed Jan 21, 1998 - Complete overhaul. That was a bit too much indexing for my liking.";
"Profane (#30788) - Fri Oct 19, 2001 - Trap for !r verbs";
.

@verb #7680:"initialize" this none this rxd #49853
@program #7680:initialize
if ((caller == this) || $perm_utils:controls(caller_perms(), this))
  "Grump 6/22/93: took out #24222.puppets initialization -- what was it here for?";
  this.home = this.owner.home;
  this.debug = 0;
  this.command_ok = {};
  this.listen_actions = {};
  this.monitor_ok = {};
  this.tell_forward = {};
  pass(@args);
else
  return E_PERM;
endif
"Mooshie (#106469) - Thu Jan 22, 1998 - Updated the security a bit and moved the pass() call *inside* the security, where we want it.";
.

@verb #7680:"call" this none this rxd #49853
@program #7680:call
if (caller_perms().wizard)
  {who, what, vrb, pass, @rest} = args;
  set_task_perms(who.wizard ? $no_one | who);
  return what:(vrb)(@pass);
else
  return E_PERM;
endif
"Mooshie (#106469) - Thu Jan 22, 1998 - New version.";
.

@verb #7680:"is_home" this none this
@program #7680:is_home
":is_home() => 1 or 0";
{home, loc} = {this.home, this.location};
home = (typeof(home) == OBJ) ? home | loc;
if ((loc == home) || (loc == `home.dest ! E_PROPNF, E_INVIND => loc'))
  return 1;
endif
return 0;
.

@verb #7680:"enterfunc exitfunc" this none this
@program #7680:enterfunc
return 1;
.

"#7680:29 --- Permission denied";
"***finished***