Dump of #26026 (Generic Super_HUH Player)

@create #33337 named Generic Super_Huh Player:Generic Super_Huh Player
@prop #26026."pets" {} rc
@prop #26026."puppets" {} rc
@prop #26026."known_objects" {} r
;;#26026.("last_read_pc_news") = 0
"#26026.("last_player_paged") => E_PERM (Permission denied)
"#26026.("idle_watched") => E_PERM (Permission denied)
"#26026.("crosspost_list") => E_PERM (Permission denied)
;;#26026.("spoof_attribution") = "     --"
"#26026.("idle_messages") => E_PERM (Permission denied)
"#26026.("respond_to") => E_PERM (Permission denied)
;;#26026.("moved_by") = {}
;;#26026.("sessile") = 0
"#26026.("witnessing") => E_PERM (Permission denied)
;;#26026.("rooms") = {{"Living", #17}, {"Dining", #28}, {"Library", #1670}, {"Pool", #1428}}
"#26026.("messages_going") => E_PERM (Permission denied)
;;#26026.("mail_options") = {"sticky", {"@mail", "new"}}
"#26026.("current_message") => E_PERM (Permission denied)
"#26026.("messages") => E_PERM (Permission denied)
;;#26026.("features") = {#55317, #30203, #40842, #26787}
"#26026.("previous_connection") => E_PERM (Permission denied)
"#26026.("email_address") => E_PERM (Permission denied)
;;#26026.("help") = #55502
"#26026.("linebuffer") => E_PERM (Permission denied)
"#26026.("current_folder") => E_PERM (Permission denied)
"#26026.("all_connect_places") => E_PERM (Permission denied)
"#26026.("last_connect_place") => E_PERM (Permission denied)
"#26026.("lines") => E_PERM (Permission denied)
"#26026.("ownership_quota") => E_PERM (Permission denied)
"#26026.("password") => E_PERM (Permission denied)
"#26026.("size_quota") => E_PERM (Permission denied)
"#26026.("last_password_time") => E_PERM (Permission denied)
"#26026.("last_connect_attempt") => E_PERM (Permission denied)
"#26026.("key") => E_PERM (Permission denied)
;;#26026.("aliases") = {"Generic Super_Huh Player"}
;;#26026.("description") = {"This player class essentially extends the parser through clever use of :my_huh.  It allows you to @remember and @forget objects so you can refer to them even if they aren't in the room and you've forgotten the number; it also allows you to tell your puppets and pets (as listed in the .puppets and .pets properties) what to do with commands like \"Watson, come here\"."}
;;#26026.("object_size") = {12074, 1141286558}

@verb #26026:"@known*_objects @known*-objects" any none none rxd
@program #26026:@known_objects
"Usage:  @known_objects [<name>]";
"List your known objects matching <name>, or all of them.";
if (known = this:known_objects(dobjstr))
  len = max(length("Object"), length(tostr(max_object()))) + 1;
  player:tell($string_utils:left("Object", len), "Name");
  player:tell($string_utils:left("------", len), "----");
  for object in (known)
    player:tell($string_utils:left(tostr(object), len), object.name);
  endfor
  player:tell($string_utils:left("------", len), "----");
elseif (dobjstr)
  player:tell("No known objects matching \"", dobjstr, "\".");
else
  player:tell("No known objects.");
endif
.

@verb #26026:"@remember" any none none
@program #26026:@remember
"Usage: @remember <object>";
"Add an object to your .known_objects list.";
if (player != this)
  player:tell("I'm sorry, your memory isn't that good.");
elseif (dobjstr)
  if (!$command_utils:object_match_failed(dobj, dobjstr))
    if (dobj in player.known_objects)
      player:tell("You already know ", dobjstr, " (", dobj, ").");
    else
      player:set_known_objects(setadd(player.known_objects, dobj));
      player:tell(dobj, " (", dobj.name, ") remembered.");
    endif
  endif
else
  player:tell("Usage:  @remember <object>");
endif
.

@verb #26026:"@forget" any none none
@program #26026:@forget
"Usage: @forget <object>";
"Remove an object from your .known_objects list.";
if (player != this)
  player:tell("How can you forget what you never knew in the first place?");
elseif (dobjstr)
  known = player.known_objects;
  if (!valid(dobj))
    dobj = $string_utils:match(dobjstr, known, "name", known, "aliases");
  endif
  if (!$command_utils:object_match_failed(dobj, dobjstr))
    if (dobj in player.known_objects)
      player:set_known_objects(setremove(player.known_objects, dobj));
      player:tell(dobj, " (", dobj.name, ") forgotten.");
    else
      player:tell("You can't forget ", dobjstr, " (", dobj, ") because you don't know it now.");
    endif
  endif
else
  player:tell("Usage:  @forget <object>");
endif
.

@verb #26026:"set_known_objects" this none this
@program #26026:set_known_objects
"Set player.known_objects.";
if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
  return E_PERM;
endif
this.known_objects = args[1];
.

@verb #26026:"my_huh" this none this rx #24442
@program #26026:my_huh
permissions = (((caller == this) || $perm_utils:controls(caller_perms(), this)) && $command_utils:validate_feature(@args)) ? this | $no_one;
if (ret = pass(@args))
  return ret;
endif
verb = args[1];
pass = args[2];
if (dobj == $failed_match)
  dobj = this:match_environment(dobjstr);
endif
if (iobj = $failed_match)
  iobj = this:match_environment(iobjstr);
endif
plist = {"any", prepstr ? $code_utils:full_prep(prepstr) | "none"};
dlist = dobjstr ? {"any"} | {"none", "any"};
ilist = iobjstr ? {"any"} | {"none", "any"};
for y in ({@dobjstr ? this:known_objects(dobjstr) | {}, @iobjstr ? this:known_objects(iobjstr) | {}})
  if (valid(loc = $object_utils:has_callable_verb(y, verb)[1]))
    template = verb_args(loc, verb);
    if ("this" in template)
      dobj_match = 0;
      if (template[1] == "this")
        for alias in ({y.name, @y.aliases})
          dobj_match = dobj_match || (index(alias, dobjstr) == 1);
        endfor
      endif
      iobj_match = 0;
      if (template[3] == "this")
        for alias in ({y.name, @y.aliases})
          iobj_match = iobj_match || (index(alias, iobjstr) == 1);
        endfor
      endif
      if ((((template[1] in dlist) || dobj_match) && (template[2] in plist)) && ((template[3] in ilist) || iobj_match))
        if (dobj_match)
          dobj = y;
        endif
        if (iobj_match)
          iobj = y;
        endif
        set_task_perms(permissions);
        y:(verb)(@pass);
        return 1;
      endif
    endif
  endif
endfor
if (verb[length(verb)] == ",")
  name = verb[1..length(verb) - 1];
  puppet = $string_utils:match(name, this.puppets, "name", this.puppets, "aliases");
  pet = $string_utils:match(name, this.pets, "name", this.pets, "aliases");
  if (($ambiguous_match in {puppet, pet}) || (valid(puppet) && valid(pet)))
    player:tell("I'm not sure which puppet or pet you're referring to.");
  elseif (valid(puppet))
    set_task_perms(permissions);
    puppet:do(argstr);
  elseif (valid(pet))
    set_task_perms(permissions);
    iobjstr = argstr;
    argstr = (name + " to ") + iobjstr;
    pet:ask(@$string_utils:words(argstr));
  else
    return 0;
  endif
  return 1;
endif
.

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

@verb #26026:"known_objects" this none this
@program #26026:known_objects
"known_objects(name)";
"Match name against this.known_objects aliases; return a list of those objects which match.";
"If !name, return the whole list.";
name = args[1];
if (!name)
  return this.known_objects;
endif
matches = {};
for object in (this.known_objects)
  if (!valid(object))
    this.known_objects = setremove(this.known_objects, object);
  elseif ((name in object.aliases) || ($string_utils:find_prefix(name, object.aliases) != 0))
    matches = {@matches, object};
  endif
endfor
return matches;
.

@verb #26026:"@known*_objects" any for any rxd
@program #26026:@known_objects
"@known*_objects [<name>] for <player>";
"List <player>'s known objects matching <name>.";
who = $string_utils:match_player(iobjstr);
if ((!$command_utils:player_match_failed(who, iobjstr)) && $Object_utils:has_verb(who, "@known_objects"))
  player:tell("Checking known objects for ", who:title(), "...");
  who:("@known_objects")();
else
  player:tell(who:titlec(), " doesn't remember things easily.");
endif
.

@verb #26026:"match_environment" this none this rx
@program #26026:match_environment
"Match something around the player.";
match = args[1];
mo = valid(this.location) ? this.location:match_object(match) | $string_utils:match_object(match, this.location);
if (mo != $failed_match)
  return mo;
else
  return this:known_object(match);
endif
ko = this:known_object(match);
if ($ambiguous_match in {mo, ko})
  return $ambiguous_match;
endif
if (valid(mo))
  if (valid(ko))
    return $ambiguous_match;
  else
    return mo;
  endif
endif
if (valid(ko))
  return ko;
endif
return $failed_match;
.

@verb #26026:"features" this none this
@program #26026:features
"features(name)";
"Match name against this.features aliases; return a list of those objects which match.";
"If !name, return the whole list.";
name = args[1];
if (!name)
  return this.features;
endif
matches = {};
for object in (this.features)
  if (!valid(object))
    this.features = setremove(this.features, object);
  elseif ((name in object.aliases) || ($string_utils:find_prefix(name, object.aliases) != 0))
    matches = {@matches, object};
  endif
endfor
return matches;
.

@verb #26026:"my_match_object" this none this rx
@program #26026:my_match_object
"my_match_object(string[, location])";
mo = $string_utils:match_object(@{@args, this.location}[1..2], this);
if (mo != $failed_match)
  return mo;
else
  return this:known_object(args[1]);
endif
ko = this:known_object(args[1]);
if ($ambiguous_match in {mo, ko})
  return $ambiguous_match;
endif
if (valid(mo))
  if (valid(ko))
    return $ambiguous_match;
  else
    return mo;
  endif
endif
if (valid(ko))
  return ko;
endif
return $failed_match;
.

@verb #26026:"feature" this none this
@program #26026: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 #26026:"find_verbs_on" this none this
@program #26026:find_verbs_on
return {@pass(@args), @this.known_objects};
.

"***finished***