@verb $player:"@debug" any any any rd #36
@program $player:@debug
"Copied from generic player (#6):@edit by Hacker (#36) Sat Mar  2 20:46:13 1996 
 EST";
"Calls the debugger on verbs, the note editor on properties, and on anything 
 else assumes it's an object for which you want to edit the .description.";
if (!args)
  ((player in $note_editor.active) ? $note_editor | 
 $verb_editor):invoke(dobjstr, verb);
elseif ($code_utils:parse_verbref(args[1]))
  if (player.programmer)
    $debug:invoke(argstr, verb);
  else
    player:notify("You need to be a programmer to do this.");
    player:notify("If you want to become a programmer, talk to a wizard.");
    return;
  endif
else
  $note_editor:invoke(dobjstr, verb);
endif
.
@prop $debug."verbnames" {} ""
@prop $debug."objects" {} ""
@prop $debug."taskids" {} ""
;;$debug.("readable") = {0}
;;$debug.("times") = {869171726}
;;$debug.("stateprops") = {{"taskids", 0}, {"objects", {}}, {"verbnames", {}}, 
 {"texts", {}}, {"changes", 0}, {"inserting", {}}, {"readable", 0}}
;;$debug.("depart_msg") = "%N is sick and tired of verbs that don't work 
 properly, and vanishes in a puff of logic."
;;$debug.("return_msg") = "%N appears in a puff of logic, smiling pleasantly."
;;$debug.("who_location_msg") = "%L [debugging verbs]"
;;$debug.("blessed_task") = 397385293
;;$debug.("aliases") = {"Debugging Room"}
;;$debug.("description") = {}
;;$debug.("object_size") = {0, 0}
@verb $debug:"init_session" this none this
@program $debug:init_session
"Copied from Verb Editor (#48):init_session by Hacker (#36) Sat Mar  2 20:53:39 
 1996 EST";
if (this:ok(who = args[1]))
  object = args[2];
  vname = args[3];
  if (`this:load(who, args[4]) ! E_TYPE => E_TYPE' == E_TYPE)
    player:tell("That verb either doesn't exist or is set -x.");
    return E_TYPE;
  endif
  this.verbnames[who] = {vname};
  this.objects[who] = {object};
  this.active[who]:tell("Now editing ", this:working_on(who), ".");
endif
.
@verb $debug:"parse_invoke" this none this
@program $debug:parse_invoke
"Copied from Verb Editor (#48):parse_invoke by Hacker (#36) Sat Mar  2 20:57:59 
 1996 EST";
":parse_invoke(string,v)";
"  string is the commandline string to parse to obtain the obj:verb to edit";
"  v is the actual command verb used to invoke the editor";
" => {object, verbname, verb_code} or error";
vref = $string_utils:words(args[1]);
if ((!vref) || (!(spec = $code_utils:parse_verbref(vref[1]))))
  player:tell("Usage: ", args[2], " object:verb");
  return;
endif
if (argspec = listdelete(vref, 1))
  if (typeof(pas = $code_utils:parse_argspec(@argspec)) == LIST)
    if (pas[2])
      player:tell("I don't understand \"", $string_utils:from_list(pas[2], " 
 "), "\"");
      return;
    endif
    argspec = {@pas[1], "none", "none"}[1..3];
    argspec[2] = $code_utils:full_prep(argspec[2]) || argspec[2];
  else
    player:tell(pas);
    return;
  endif
endif
if (!$command_utils:object_match_failed(object = 
 player:my_match_object(spec[1], this:get_room(player)), spec[1]))
  vnum = $code_utils:find_verb_named(object, vname = spec[2], 0);
  if (argspec)
    while ((vnum >= 0) && (verb_args(object, tostr(vnum)) != argspec))
      vnum = $code_utils:find_verb_named(object, vname, vnum + 1);
    endwhile
    if (vnum >= 0)
      code = this:fetch_verb_code(object, tostr(vnum));
    else
      code = E_VERBNF;
    endif
  else
    code = this:fetch_verb_code(object, tostr(vnum));
  endif
  if (typeof(code) == ERR)
    player:tell((code != E_VERBNF) ? code | "That object does not define that 
 verb", argspec ? " with those args" | "", ", or the verb is set -x.");
    return code;
  else
    return {object, argspec ? {vname, @argspec} | vname, code};
  endif
endif
return 0;
.
@verb $debug:"fetch_verb_code" this none this rx #2
@program $debug:fetch_verb_code
"WIZARDLY";
set_task_perms(player);
if (!index(verb_info(args[1], args[2])[2], "x"))
  return E_VERBNF;
endif
return verb_code(args[1], args[2], !player:edit_option("no_parens"));
.
@verb $debug:"go run resume con*tinue" none none none rd #2
@program $debug:go
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (!this.taskids[who])
  player:tell("You haven't started a verb yet.");
  return E_QUOTA;
endif
if (`resume(this.taskids[who]) ! E_INVARG => 1')
  player:tell("The verb has been stopped.");
  this.inserting[who] = {};
  return E_QUOTA;
endif
suspend(0);
.
@verb $debug:"s*tep" any any any rd #2
@program $debug:step
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (!(args && (number = tonum(argstr))))
  number = 1;
endif
for iter in [1..number]
  if (!this.taskids[who])
    player:tell("You haven't started a verb yet.");
    return E_QUOTA;
  endif
  if (`task_step(this.taskids[who]) ! E_INVARG => 1')
    player:tell("The verb has been stopped.");
    this.taskids[who] = {};
    return E_QUOTA;
  endif
  suspend(0);
  if (!`tf = task_frames(this.taskids[who]) ! E_INVARG => 0')
    this.taskids[who] = {};
    return E_QUOTA;
  endif
  if (length(tf) == 1)
    resume(this.taskids[who]);
  elseif ((length(tf) - 1) < length(this.texts[who]))
    this.objects[who] = this.objects[who][1..$ - 1];
    this.verbnames[who] = this.verbnames[who][1..$ - 1];
    this.texts[who] = this.texts[who][1..$ - 1];
    this.inserting[who] = this.inserting[who][1..$ - 1];
  else
    qi = this:index_of_task_in_queue(this.taskids[who]);
    qt = queued_tasks();
    this.inserting[who][$] = qt[qi][8] + 1;
  endif
endfor
.
@verb $debug:"load" this none this
@program $debug:load
"Copied from Generic Editor (#49):load by Hacker (#36) Sun Mar  3 02:39:07 1996 
 EST";
texts = args[2];
if (!(fuckup = this:ok(who = args[1])))
  return fuckup;
elseif (typeof(texts) == STR)
  texts = {texts};
elseif ((typeof(texts) != LIST) || (length(texts) && (typeof(texts[1]) != STR)))
  return E_TYPE;
endif
this.texts[who] = {texts};
this.inserting[who] = {2};
this.changes[who] = 0;
this.readable[who] = 0;
this.times[who] = time();
.
@verb $debug:"lis*t view" any any any
@program $debug:list
"Copied from Generic Editor (#49):list by Hacker (#36) Sun Mar  3 02:42:47 1996 
 EST";
nonum = 0;
if (verb == "view")
  if (!args)
    l = {};
    for i in [1..length(this.active)]
      if (this.readable[i])
        l = {@l, this.active[i]};
      endif
    endfor
    if (l)
      player:tell("Players having readable texts in this editor:  ", 
 $string_utils:names_of(l));
    else
      player:tell("No one has published anything in this editor.");
    endif
    return;
  elseif ($command_utils:player_match_result(plyr = 
 $string_utils:match_player(args[1]), args[1])[1])
    "...no such player";
    return;
  elseif ((!(who = this:loaded(plyr))) || (!this:readable(who)))
    player:tell(plyr.name, "(", plyr, ") has not published anything in this 
 editor.");
    return;
  endif
  args = listdelete(args, 1);
elseif (!(who = this:loaded(player)))
  player:tell(this:nothing_loaded_msg());
  return;
endif
len = length(this.texts[who][$]);
ins = this.inserting[who][$];
window = 8;
if (len < (2 * window))
  default = {"1-$"};
elseif (ins <= window)
  default = {tostr("1-", 2 * window)};
else
  default = {tostr(window, "_-", window, "^"), tostr(2 * window, "$-$")};
endif
if (typeof(range = this:parse_range(who, default, @args)) != LIST)
  player:tell(tostr(range));
elseif (range[3] && (!(nonum = "nonum" == $string_utils:trim(range[3]))))
  player:tell("Don't understand this:  ", range[3]);
elseif (nonum)
  player:tell_lines(this.texts[who][$][range[1]..range[2]]);
else
  for line in [range[1]..range[2]]
    this:list_line(who, line);
    if ($command_utils:running_out_of_time())
      suspend(0);
      if (!(who = this:loaded(player)))
        player:tell("ack!  something bad happened during a suspend...");
        return;
      endif
    endif
  endfor
  if ((ins > len) && (len == range[2]))
    player:tell("^^^^");
  endif
endif
.
@verb $debug:"list_line" this none this
@program $debug:list_line
"Copied from Generic Editor (#49):list_line by Hacker (#36) Sun Mar  3 02:45:22 
 1996 EST";
if (this:ok(who = args[1]))
  f = 1 + ((line = args[2]) in {(ins = this.inserting[who][$]) - 1, ins});
  player:tell($string_utils:right(line, 3, " _^"[f]), ":_^"[f], " ", 
 this.texts[who][$][line]);
endif
.
@verb $debug:"parse_range" this none this
@program $debug:parse_range
"Copied from Generic Editor (#49):parse_range by Hacker (#36) Sun Mar  3 
 02:46:48 1996 EST";
"parse_range(who,default,@args) => {from to rest}";
numargs = length(args);
if (!(fuckup = this:ok(who = args[1])))
  return fuckup;
elseif (!(last = length(this.texts[who][$])))
  return this:no_text_msg();
endif
default = args[2];
r = 0;
while (default && (LIST != typeof(r = this:parse_range(who, {}, default[1]))))
  default = listdelete(default, 1);
endwhile
if (typeof(r) == LIST)
  from = r[1];
  to = r[2];
else
  from = to = 0;
endif
saw_from_to = 0;
not_done = 1;
a = 2;
while (((a = a + 1) <= numargs) && not_done)
  if (args[a] == "from")
    if ((a == numargs) || (!(from = this:parse_number(who, args[a = a + 1], 
 0))))
      return "from ?";
    endif
    saw_from_to = 1;
  elseif (args[a] == "to")
    if ((a == numargs) || (!(to = this:parse_number(who, args[a = a + 1], 1))))
      return "to ?";
    endif
    saw_from_to = 1;
  elseif (saw_from_to)
    a = a - 1;
    not_done = 0;
  elseif (i = index(args[a], "-"))
    from = this:parse_number(who, args[a][1..i - 1], 0);
    to = this:parse_number(who, args[a][i + 1..length(args[a])], 1);
    not_done = 0;
  elseif (f = this:parse_number(who, args[a], 0))
    from = f;
    if ((a == numargs) || (!(to = this:parse_number(who, args[a + 1], 1))))
      to = from;
    else
      a = a + 1;
    endif
    not_done = 0;
  else
    a = a - 1;
    not_done = 0;
  endif
endwhile
if (from < 1)
  return tostr("from ", from, "?  (out of range)");
elseif (to > last)
  return tostr("to ", to, "?  (out of range)");
elseif (from > to)
  return tostr("from ", from, " to ", to, "?  (backwards range)");
else
  return {from, to, $string_utils:from_list(args[a..numargs], " ")};
endif
.
@verb $debug:"parse_number" this none this
@program $debug:parse_number
"Copied from Generic Editor (#49):parse_number by Hacker (#36) Sun Mar  3 
 02:48:14 1996 EST";
"parse_number(who,string,before)   interprets string as a line number.  In the 
 event that string is `.', `before' tells us which line to use.  Return 0 if 
 string is bogus.";
if (!(fuckup = this:ok(who = args[1])))
  return fuckup;
endif
last = length(this.texts[who][$]);
ins = this.inserting[who][$] - 1;
string = args[2];
after = !args[3];
if (!string)
  return 0;
elseif ("." == string)
  return ins + after;
elseif (!(i = index("_^$", string[slen = length(string)])))
  return tonum(string);
else
  start = {ins + 1, ins, last + 1}[i];
  n = 1;
  if ((slen > 1) && (!(n = tonum(string[1..slen - 1]))))
    return 0;
  elseif (i % 2)
    return start - n;
  else
    return start + n;
  endif
endif
.
@verb $debug:"index_of_task_in_queue" this none this rxd #2
@program $debug:index_of_task_in_queue
if (!(args && (typeof(i = args[1]) == INT)))
  return E_INVARG;
endif
for taski in [1..length(qt = queued_tasks())]
  if (qt[taski][1] == i)
    return taski;
  endif
endfor
return 0;
.
@verb $debug:"step_in i*n" any any any rd #2
@program $debug:step_in
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (!(args && (number = tonum(argstr))))
  number = 1;
endif
for iter in [1..number]
  if (!this.taskids[who])
    player:tell("You haven't started a verb yet.");
    return E_QUOTA;
  endif
  if (`task_step_in(this.taskids[who]) ! E_INVARG => 1')
    player:tell("The verb has been stopped.");
    this.taskids[who] = 0;
    return E_QUOTA;
  endif
  suspend(0);
  if (!`tf = task_frames(this.taskids[who]) ! E_INVARG => 0')
    this.taskids[who] = 0;
    return E_QUOTA;
  endif
  qi = this:index_of_task_in_queue(this.taskids[who]);
  qt = queued_tasks();
  if (length(tf) == 1)
    resume(this.taskids[who]);
  elseif ((length(tf) - 1) > length(this.texts[who]))
    newobject = qt[qi][6];
    this.objects[who] = {@this.objects[who], newobject};
    newverbname = qt[qi][7];
    this.verbnames[who] = {@this.verbnames[who], newverbname};
    if (`newverbcode = this:fetch_verb_code(newobject, newverbname) ! E_PERM => 
 0')
      this.texts[who] = {@this.texts[who], newverbcode};
    else
      this.texts[who] = {@this.texts[who], 
 $list_utils:make(length(verb_code(newobject, newverbname)), "Unreadable 
 Verb...")};
    endif
    this.inserting[who] = {@this.inserting[who], 2};
    player:tell("Stepped into ", newobject, ":", newverbname, ".");
  elseif ((length(tf) - 1) < length(this.texts[who]))
    this.objects[who] = this.objects[who][1..$ - 1];
    this.verbnames[who] = this.verbnames[who][1..$ - 1];
    this.texts[who] = this.texts[who][1..$ - 1];
    this.inserting[who] = this.inserting[who][1..$ - 1];
    player:tell("Stepped out.");
  else
    this.inserting[who][$] = qt[qi][8] + 1;
  endif
endfor
.
@verb $debug:"step_out o*ut" any any any rd #2
@program $debug:step_out
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (!(args && (number = tonum(argstr))))
  number = 1;
endif
for iter in [1..number]
  if (!this.taskids[who])
    player:tell("You haven't started a verb yet.");
    return E_QUOTA;
  endif
  if (`task_step_out(this.taskids[who]) ! E_INVARG => 1')
    player:tell("The verb has been stopped.");
    this.taskids[who] = 0;
    return E_QUOTA;
  endif
  suspend(0);
  if (!`tf = task_frames(this.taskids[who]) ! E_INVARG => 0')
    this.taskids[who] = 0;
    return E_QUOTA;
  endif
  if (length(tf) == 1)
    resume(this.taskids[who]);
  else
    this.objects[who] = this.objects[who][1..$ - 1];
    this.verbnames[who] = this.verbnames[who][1..$ - 1];
    this.texts[who] = this.texts[who][1..$ - 1];
    this.inserting[who] = this.inserting[who][1..$ - 1];
  endif
endfor
.
@verb $debug:"d*ebug" any none none
@program $debug:debug
"Copied from Verb Editor (#48):edit by Hacker (#36) Mon Mar  4 14:09:17 1996 
 EST";
if (!args)
  player:tell("debug what?");
else
  this:invoke(argstr, verb);
endif
.
@verb $debug:"v*ariables" any any any rd #2
@program $debug:variables
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (!(args && (targvar = argstr)))
  targvar = "";
endif
if (!this.taskids[who])
  player:tell("You haven't started a verb yet.");
  return E_QUOTA;
endif
su = $string_utils;
if (targvar)
  for var in (task_frames(this.taskids[who])[1])
    if (var[1] == targvar)
      player:tell(var[1], " : ", su:print(var[3]));
    endif
  endfor
else
  varlist = 
 {"_________Variable_:_Value_____________-__________Variable_:_Value____________
 "};
  newline = 1;
  vartypes = {"INT", "NUM", "FLOAT", "OBJ", "STR", "LIST", "ERR"};
  for var in (task_frames(this.taskids[who])[1])
    if (!(var[1] in vartypes))
      if (newline)
        varlist = listappend(varlist, tostr(su:right(var[1], 17), " : ", 
 (var[2] == 6) ? "<Uninitialized>" | su:left(su:print(var[3]), 17)));
        newline = 0;
      else
        varlist[$] = tostr(varlist[$], " - ", su:right(var[1], 17), " : ", 
 (var[2] == 6) ? "<Uninitialized>" | su:left(su:print(var[3]), 17));
        newline = 1;
      endif
    endif
  endfor
  if (length(varlist) > 1)
    for v in (varlist)
      player:tell(v);
    endfor
  endif
endif
.
@verb $debug:"m*odify_variable" any any any rd #2
@program $debug:modify_variable
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (!this.taskids[who])
  player:tell("You haven't started a verb yet.");
  return E_QUOTA;
endif
if (length(words = $string_utils:explode(argstr, ":")) != 2)
  player:tell("Usage: ", verb, " <varname> : <newvalue>");
  return E_INVARG;
endif
words[1] = $string_utils:trim(words[1]);
words[2] = $string_utils:trim(words[2]);
verbowner = verb_info(this.objects[who][$], this.verbnames[who][$])[1];
if ((!(player == verbowner)) && (!player.wizard))
  player:tell("You don't have permission to modify variables in this verb.");
  return E_PERM;
endif
if ((words[1] in {"INT", "NUM", "FLOAT", "OBJ", "STR", "LIST", "ERR"}) || 
 ((words[1] in {"player", "caller"}) && (!player.wizard)))
  player:tell("You don't have permission to modify that variable.");
  return E_PERM;
endif
if (!(v = $string_utils:to_value(words[2]))[1])
  player:tell("$string_utils:to_value() couldn't parse that value.");
  return E_INVARG;
endif
words[2] = v[2];
if (`alter_variable(this.taskids[who], 1, words[1], words[2]) ! E_VARNF => 1')
  player:tell("That variable does not exist in this verb.");
  return E_VARNF;
endif
player:tell(words[1], " : ", $string_utils:print(words[2]));
.
@verb $debug:"start begin" none none none rd #2
@program $debug:start
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (this.taskids[who])
  player:tell("You already have ", this.objects[who][$], ":", 
 this.verbnames[who][$], " running!");
  return E_QUOTA;
endif
this.inserting[who] = {2};
fork (0)
  this.taskids[who] = task_id();
  suspend();
  this.objects[who][$]:(this.verbnames[who][$])();
  this.texts[who] = this.texts[who][1..1];
  this.objects[who] = this.objects[who][1..1];
  this.verbnames[who] = this.verbnames[who][1..1];
  this.inserting[who] = {2};
  this.taskids[who] = 0;
  player:tell("*** Verb Debugging Finished ***");
endfork
suspend(0);
task_step_in(this.taskids[who]);
player:tell("*** Verb Started ***");
.
@verb $debug:"done q*uit pause" none none none rxd #2
@program $debug:done
if (who = this:loaded(player))
  if (this.taskids[who])
    player:tell("You have a verb running. Do you wish to kill it? (default is 
 to let it finish normally)");
    if ($command_utils:yes_or_no())
      if (`kill_task(this.taskids[who]) ! E_INVARG => 1')
        player:tell("The verb has already been stopped.");
        this.inserting[who] = {};
      else
        player:tell("Killed.");
      endif
    else
      if (`resume(this.taskids[who]) ! E_INVARG => 1')
        player:tell("The verb has already been stopped.");
        this.inserting[who] = {};
      else
        player:tell("Resumed.");
      endif
    endif
  endif
endif
suspend(0);
pass(@args);
.
@verb $debug:"abort" none none none rd #2
@program $debug:abort
if (!(who = this:loaded(player)))
  player:tell("Something's screwed up...");
  return E_PERM;
endif
if (!this.taskids[who])
  player:tell("You haven't started a verb yet.");
  return E_QUOTA;
endif
if (`kill_task(this.taskids[who]) ! E_INVARG => 1')
  player:tell("The verb has already been stopped.");
  this.inserting[who] = {};
  return E_QUOTA;
endif
player:tell("Killed.");
this.taskids[who] = 0;
.
"***finished***
