A dump of #1140 (clock)

@create $root_class named Master Clock:master,clock
@prop #1140."recycler" #6565 rc
"#1140.("burning") => E_PERM (Permission denied)
@prop #1140."depots" {} rc
;;#1140.("depots") = {#175}
@prop #1140."going" {} rc
@prop #1140."last_cycle" 1141685372 rc
@prop #1140."last_cycle2" 1141686249 rc
@prop #1140."resurrection_task" 1734019461 r
@prop #1140."resurrection_queue" {} r
;;#1140.("resurrection_queue") = {{#52484, 1141082078}, {#26608, 1141684100}, {#26388, 1141145668}, {#5632, 1141684074}, {#53798, 1141671684}, {#4981, 1141684119}, {#51765, 1141684079}, {#7057, 1141686031}, {#52165, 1141684096}}
@prop #1140."resurrection_queue_pos" 10 r
@prop #1140."monster_orphans" {} rc
@prop #1140."storm_task" 1396710213 r
"#1140.("old_pcs") => E_PERM (Permission denied)
"#1140.("old_dolls") => E_PERM (Permission denied)
"#1140.("new_direction_msg") => E_PERM (Permission denied)
"#1140.("old_direction_msg") => E_PERM (Permission denied)
@prop #1140."archive_interval" 604800 r
@prop #1140."db_feature" #2470 rc
@prop #1140."clean_susa" 0 r
@prop #1140."cycle_task" 1222405917 rc
@prop #1140."next_rebirth" 1079617055 r
@prop #1140."next_heal" 1141687594 r
@prop #1140."next_att_check" 1141686849 r
"#1140.("key") => E_PERM (Permission denied)
;;#1140.("aliases") = {"master", "clock"}
;;#1140.("object_size") = {33393, 1141286558}

@verb #1140:"heal" this none this
@program #1140:heal
":heal() -> Decrement damage monitors on all dolls.";
"We set .inj directly here (in defiance of possible lifelinks) because it's faster and it doesn't happen frequently enough to get our knickers in a twist over it.  - THX";
if ((rpg = $local.rpg):is_grandmaster(caller_perms()))
  if (rpg.active_players)
    {c_u, last_cycle, rpg_doll} = {$command_utils, this.last_cycle, rpg.doll};
    factor = random(50) - 1;
    for doll in (rpg.dolls)
      rpg:s_i_f_i_n();
      if ((parent(doll) == rpg_doll) && (doll.last_action < last_cycle))
        {inj, ins, fat, end, wil} = {doll.inj, doll.ins, doll.fat, doll.end, doll.wil};
        if (!doll.deathless)
          doll.inj = `max(0, inj - end) ! E_TYPE => 0';
          doll.inj || clear_property(doll, "inj");
        endif
        doll.ins = `max(0, (ins - ((ins + factor) / 50)) - wil) ! E_TYPE => 0';
        doll.ins || clear_property(doll, "ins");
        doll.fat = `max(0, (fat - ((fat + (2 * factor)) / 50)) - (((wil + end) + end) / 2)) ! E_TYPE => 0';
        doll.fat || clear_property(doll, "fat");
      endif
    endfor
  else
    return;
  endif
else
  return E_PERM;
endif
"Profane 17-AUG-97 809PDT -- new 1.8 version";
"THX (#105941) - Sun Apr 12, 1998 - Made this a bit speedier in CPU usage.";
.

@verb #1140:"cycle" this none this
@program #1140:cycle
":cycle() => Run the universal RPG healing task.";
"New paradigm: don't use a suspended background task. Have #49444:rest call this.";
if ((time() < this.next_heal) || $code_utils:task_valid(this.cycle_task))
  return E_NONE;
elseif (caller_perms() == (rpg = $local.rpg).owner)
  if (rpg.gm_lag < rpg.idle_threshold)
    fork x (5)
      this.next_heal = time() + 2222;
      this:heal();
      this.last_cycle = time();
    endfork
    this.cycle_task = x;
  endif
else
  return E_PERM;
endif
.

@verb #1140:"collect" this none this
@program #1140:collect
":collect(OBJ parent) => loops through kids of PARENT and adds those in $nowhere to the .going list. One can then recycle all these kids via :flush";
if (caller_perms() == this.owner)
  {from} = args;
  rpg = $local.rpg;
  for thing in ($object_utils:descendants(from))
    where = thing.location;
    if (where == $nowhere)
      player:tell(thing.name, "(", thing, ") at ", where, " _not_ added to list.");
    elseif (($room in rpg:parents(where)) && (!(where in this.depots)))
      this.going = {@this.going, thing};
      player:tell(thing.name, "(", thing, ") in ", where.name, "(", where, ") added to hit list.");
    endif
  endfor
endif
.

@verb #1140:"flush" none none none rxd
@program #1140:flush
":flush() -> recycle everything in this.going, which is set via :collect";
if (caller_perms() == this.owner)
  rpg = $local.rpg;
  return;
  for thing in (this.going)
    player:tell(thing.name, "(", thing, ") is being recycled.");
    rpg.recycler:_recycle(thing);
  endfor
  this.going = {};
endif
"THX (#105941) - Sat Mar 24, 2001 - disabled.  what the heck was this supposed to do?";
.

@verb #1140:"restore_ATTs" this none this
@program #1140:restore_ATTs
":restore_ATTs(OBJ monster that triggered execution) -> Return temporarily modified atts on dolls to their original value.";
{monster} = args;
(rpg = $local.rpg):secure();
past_day = time() - (40 * rpg.idle_threshold);
active_players = 0;
for doll in (setremove(rpg.dolls, `monster.doll ! E_PROPNF => $nothing'))
  if (doll.last_action > past_day)
    rpg:s_i_n();
    try
      doll:check_schedule();
      if (is_player(doll.character))
        active_players = active_players + 1;
      endif
    except (ANY)
      "Doll got recycled during suspend. Oh well.";
    endtry
  endif
endfor
rpg.active_players = active_players;
"Isagi 30-SEP-94 4:07P Added";
"Irin Sat Sep 28 14:26:40 1996 PDT -- Changed att_schedule to doll:check_schedule.";
"THX 18-Jun-1997  -- Hacked to check only dolls that have done anything in the past 24 hours.";
"THX 21-Sept-1997  -- Added a counter to determine how many players are active and store that value in rpg.active_players.";
"THX (#105941) - Sun Apr 15, 2001 - Changed this to be triggered (via :check_schedule) by a monster moving through a secure exit.  Removed that monster from the schedule checking so it doesn't look too \"busy\".";
.

@verb #1140:"check_schedule" this none this
@program #1140:check_schedule
":check_schedule() -- run the universal RPG stat-restoring cycle.";
if ((time() < this.next_att_check) || $login.checkpoint_in_progress)
  return E_NONE;
elseif (caller_perms() == (rpg = $local.rpg).owner)
  this.next_att_check = (time() + 600) + rpg.gm_lag;
  if (rpg.gm_lag < rpg.idle_threshold)
    this:restore_ATTs(@args);
    this.last_cycle2 = time();
  endif
  "archiver = rpg.archiver;";
  "if (archiver.last_doll_archive + this.archive_interval < time())";
  "  archiver.last_doll_archive = time();";
  "  \"... :doll_archive will set this, too, but we ...\";";
  "  \"... don't want this verb calling it more than...\";";
  "  \"... once while it's still running            ...\";";
  "  fork (rpg.gm_lag)";
  "    archiver:doll_archive();";
  "  endfork";
  "endif";
else
  return E_PERM;
endif
"Isagi 30-SEP-94 4:43P Added  This scheduler (hopefully) runs every ten minutes";
"THX1138 20-Jun-1997 --  Added a call to .gm_lag to back this task off a bit if G_M is really lagged.  Every 10 minutes is desirable, but not essential.";
"Mooshie (#106469) - Sat Oct 30, 1999 - Added a hook for the doll archival task. Seemed an appropriate place.";
"THX (#105941) - Sun Apr 15, 2001 - Changed this to be triggered instead of cycling eternally.";
"Profane (#30788) - Wed Jun 13, 2001 - NBCi go boom, we not have new archive site yet, no doll archive for joo. suck it up.";
.

@verb #1140:"cycle3(obsolete)" this none this
@program #1140:cycle3(obsolete)
":cycle3() => Continuously check this.death_queue for monsters to resurrect.";
if ((caller != this) && (!caller_perms().wizard))
  return E_PERM;
elseif ($code_utils:task_valid(this.resurrection_task))
  return E_NACC;
endif
this.resurrection_task = task_id();
cemetery = (rpg = $local.rpg).cemetery;
while (this.resurrection_queue)
  ".resurrection_queue structure: LIST of {OBJ beastie, NUM time it died}";
  suspend(this.resurrection_interval);
  pos = ((p = this.resurrection_queue_pos) > length(this.resurrection_queue)) ? 1 | p;
  try
    {beast, time} = this.resurrection_queue[pos];
  except (E_RANGE)
    "Means we have a blank resurrection queue";
    break;
  endtry
  if ((((!rpg:is_monster(beast)) || (beast.location != cemetery)) || (typeof(`gestate = beast.gestate ! E_PROPNF, E_PERM') != NUM)) || (gestate < 0))
    "What the heck is it doin in the queue?";
    this.resurrection_queue = listdelete(this.resurrection_queue, pos);
  elseif (this:not_checkpoint() && (time() >= (time + gestate)))
    "Bring it back to life.";
    fork (4 + rpg.gm_lag)
      if (!beast.alive)
        try
          beast:birth();
        except x (ANY)
          "Notify the beast's owner";
          $mail_agent:send_message(this, {beast.owner}, {"Error birthing " + $string_utils:nn(beast), {#4044}}, ($string_utils:from_value(x, 1, 5) + " ") + tostr(beast));
        endtry
      endif
    endfork
    this.resurrection_queue = listdelete(this.resurrection_queue, pos);
    this.monster_orphans = setadd(this.monster_orphans, beast);
    if (this.clean_susa)
      this:susaclean();
      this.clean_susa = 0;
    endif
    "If all is well the cemetery's :exitfunc will remove the beast from the orphans list.";
  elseif ((!this.clean_susa) && (!this:not_checkpoint()))
    this.clean_susa = 1;
  elseif (time() >= ((time + gestate) - this.resurrection_interval))
    "... do nothing this critter will be born next pass ... ";
  else
    this.resurrection_queue_pos = pos + 1;
  endif
  this.resurrection_interval = (60 + min(rpg.idle_threshold, 3 * rpg.gm_lag)) - (length(this.resurrection_queue) * (!this.clean_susa));
endwhile
"StarDancer -  7:17 15-Aug-1996 EDT - changed test from beast.alive to testing if the critter's in the cemetery.";
"Profane 20-AUG-96 0920PDT -- orphan stuff.";
"THX 16-Apr-1997 --  Changed $object_utils:is(beast, $local.rpg.monster) to rpg:is_monster(beast) and shaved off a few ticks.";
"THX 21-Jun-1997 --  Added a dynamic to the .resurrection_interval; the code can now add up to two additional minutes to the interval if G_M is really lagged.";
"Profane 8-AUG-97 2110PDT -- check .alive inside the forked birth task";
"Profane (#30788) - Mon Oct  6 17:49:28 1997 PDT - Added mail message in case of error in birthing.";
"THX 11-Dec-1997  -- Added a conditional that lets the queue hang back if the critter it's looking at will be birthed next pass through.";
"THX (#105941) - Tue Nov  9, 1999 - Don't birth during checkpoint.  Clean Susa before resuming.";
.

@verb #1140:"resurrect(obsolete)" this none this
@program #1140:resurrect(obsolete)
":resurrect() -- start the monster resurrection cycle.";
if (!(caller_perms() in $local.rpg.grand_masters))
  return E_PERM;
elseif ($code_utils:task_valid(id = this.resurrection_task))
  kill_task(id);
else
  fork (5)
    this:cycle3();
  endfork
  return 1;
endif
.

@verb #1140:"add_death" this none this
@program #1140:add_death
":add_death(OBJ dead beast, [NUM time it died]) -- Add beast to queue for ressurection, time of death defaults to now.";
(rpg = $local.rpg):secure();
this.resurrection_queue = (typeof(this.resurrection_queue) == ERR) ? {} | this.resurrection_queue;
if ((!valid(beast = args[1])) || (!rpg:is_monster(beast)))
  ret = E_NACC;
elseif ((typeof(gestate = beast.gestate) != NUM) || (gestate < 0))
  ret = E_RANGE;
elseif (ret = $list_utils:iassoc(beast, this.resurrection_queue, 1))
else
  time = (length(args) > 2) ? (typeof(args[2]) == NUM) ? args[2] | time() | time();
  pos = this.resurrection_queue_pos;
  ret = length(this.resurrection_queue = listinsert(this.resurrection_queue, {beast, time}, pos));
  this.resurrection_queue_pos = pos + 1;
endif
"if ((!$code_utils:task_valid(this.resurrection_task)) && this.resurrection_queue)";
"  force_input(this.owner, \";$local.rpg.clock:resurrect()\");";
"this:resurrect();";
"endif";
return ret;
"THX (#105941) - Thu Mar 12, 1998 - Added a force_input so that G_M takes 'possession' of the queue checking.";
"THX (#105941) - Sun Apr 15, 2001 - Removed the resurrect cycle restart code.  Now triggered by cemetery enterfunc instead.";
.

@verb #1140:"remove_death" this none this
@program #1140:remove_death
":remove_death(OBJ dead beast) -- remove beast from resurrection queue";
$local.rpg:secure();
if (pos = $list_utils:iassoc(beast = args[1], this.resurrection_queue, 1))
  return length(this.resurrection_queue = listdelete(this.resurrection_queue, pos));
else
  return E_NONE;
endif
.

@verb #1140:"check_cycles" this none this
@program #1140:check_cycles
":check_cycles() -> called by ~vacuum:cycle, checks other continous forked RPG tasks and starts them up if they're dead.";
$local.rpg:secure();
tasks = queued_tasks();
c1 = c2 = mtask = ltask = ctask = 1;
for item in (tasks)
  if ((item[7] == "cycle") && (item[6] == this))
    "c1 = 0;";
    "elseif ((item[7] == \"cycle2\") && (item[6] == this))";
    "  c2 = 0;";
    "elseif ((item[7] == \"my_suspend\") && (item[6] == #94427))";
    "  mtask = 0;";
  elseif ((item[7] == "my_suspend") && (item[6] == #48923))
    ltask = 0;
    "elseif ((item[7] == \"cycle\") && (item[6] == $local.rpg.vacuum))";
    "  \"ctask = 0;\";";
  endif
endfor
"c1 ? this:cycle() | \"\";";
"Restart main healing cycle task";
"c2 ? this:cycle2() | \"\";";
"Restart att restoration cycle";
"mtask ? #94427:pump() | \"\";";
"Restart magnetic object heart";
ltask ? #48923:pump() | "";
"Restart light source heart";
"ctask ? $local.rpg.vacuum:cycle() | \"\";";
"Restart object cleanup/recyling cycle";
"((!$code_utils:task_valid(this.resurrection_task)) && this.resurrection_queue) ? this:cycle3() | \"\";";
"Restart monster ressurection cycle, if there are any monsters to be resurrected.";
"Profane 5-AUG-96 1547PDT -- Added";
"Profane (#30788) - Wed Mar 18, 1998 - simplify security";
"THX (#105941) - Sun Apr 15, 2001 - Commented out cycle(), cycle2(), cycle3(), and vacuum:cycle() tasks that are now on triggers.";
.

@verb #1140:"new_direction" this none this
@program #1140:new_direction
if (!(rpg = $local.rpg):is_grandmaster(caller_perms()))
  return E_PERM;
else
  "Save all player's dolls, move their equipment away, and give them new dolls.";
  rpg.doll.paralyzed = 1;
  pcs = rpg.pcs;
  dolls = rpg.dolls;
  this.old_pcs = this.old_dolls = {};
  for i in [1..length(rpg.pcs)]
    if (is_player(rpg.pcs[i]))
      this.old_pcs = listappend(this.old_pcs, rpg.pcs[i]);
      this.old_dolls = listappend(this.old_dolls, rpg.dolls[i]);
      pcs = setremove(pcs, rpg.pcs[i]);
      dolls = setremove(dolls, rpg.dolls[i]);
    endif
    rpg:time_stop(rpg:gm_lag());
  endfor
  if (length($set_utils:union(this.old_pcs, pcs)) != length(rpg.pcs))
    return E_NACC;
  endif
  "OK, at this point PCS contains all monsters, and DOLLS contains all monster dolls. OLD_PCS and OLD_DOLLS contain the same, only for players.";
  "Time to move the equipment (to the doll, for simplicity).";
  for i in [1..length(this.old_pcs)]
    dude = this.old_pcs[i];
    doll = this.old_dolls[i];
    claimed = doll:claimed_objects();
    carried = rpg.user_utils.quinn:class_list(dude.contents, rpg.thing);
    for item in ({@claimed, @carried})
      `item:moveto(doll) ! ANY';
      "if (item.location != doll)";
      "  return E_INVIND;";
      "endif";
      rpg:time_stop(rpg:gm_lag());
    endfor
  endfor
  "OK items now stowed. Issue new dolls.";
  "First redo rpg.pcs and rpg.dolls";
  rpg.pcs = pcs;
  rpg.dolls = dolls;
  for dude in (this.old_pcs)
    rpg:def_pc(dude);
    rpg:time_stop(rpg:gm_lag());
  endfor
  $mail_agent:send_message(this.owner, {rpg.news, #21259}, "LambdaMOO RPG Takes a New Direction", this.new_direction_msg);
  q = queued_tasks();
  for item in (q)
    if (q[6] == rpg.vacuum)
      kill_task(q[1]);
    endif
  endfor
  rpg.doll.paralyzed = 0;
endif
.

@verb #1140:"old_direction" this none this
@program #1140:old_direction
if (!(rpg = $local.rpg):is_grandmaster(caller_perms()))
  return E_PERM;
else
  "put it all back..";
  rpg.doll.paralyzed = 1;
  for i in [1..length(rpg.pcs)]
    who = rpg.pcs[i];
    if (j = who in this.old_pcs)
      old_doll = rpg.dolls[i];
      doll = this.old_dolls[j];
      rpg.pcs[i] = doll;
      for item in (doll.contents)
        `item:moveto(who) ! ANY';
        rpg:time_stop(rpg:gm_lag());
      endfor
      old_doll.character = #-1;
      `rpg.recycler:_recycle(old_doll) ! ANY';
    endif
  endfor
  $mail_agent:send_message(this.owner, {rpg.news, #21259}, "LambdaMOO RPG Takes an Old Direction", this.old_direction_msg);
  q = queued_tasks();
  if (!(i = rpg.vacuum in $list_utils:slice(q, 6)))
    rpg.vacuum:cycle();
  endif
  rpg.doll.paralyzed = 0;
endif
.

@verb #1140:"old_heal" this none this
@program #1140:old_heal
":heal() -> Decrement damage monitors on all dolls.";
if ((rpg = $local.rpg):is_grandmaster(caller_perms()))
  if (!rpg.active_players)
    return;
  endif
  factor = random(50) - 1;
  for doll in (rpg.dolls)
    $command_utils:suspend_if_needed(2 * rpg:gm_lag());
    if ((parent(doll) == rpg.doll) && (doll.last_action < this.last_cycle))
      {inj, ins, fat, end, wil} = {doll.inj, doll.ins, doll.fat, doll.end, doll.wil};
      if (!doll.deathless)
        doll.inj = `max(0, inj - end) ! E_TYPE => 0';
      endif
      doll.ins = `max(0, (ins - ((ins + factor) / 50)) - wil) ! E_TYPE => 0';
      doll.fat = `max(0, (fat - ((fat + (2 * factor)) / 50)) - (((wil + end) + end) / 2)) ! E_TYPE => 0';
    endif
  endfor
else
  return E_PERM;
endif
"Profane 17-AUG-97 809PDT -- new 1.8 version";
.

@verb #1140:"not_checkpoint" this none this
@program #1140:not_checkpoint
return !$login.checkpoint_in_progress;
.

@verb #1140:"susaclean" this none this
@program #1140:susaclean
"Copied from THX's GM FO (#98965):@susa by THX (#105941) Tue Nov  9 11:20:28 1999 PST";
rpg = $local.rpg;
{susa, bad, trash} = {rpg.object_db.obj_money[1].owner, {}, $garbage};
for t in (susa.owned_objects)
  rpg:s_i_f_i_n();
  if (((!valid(t)) || (!valid(parent(t)))) || (parent(t) == trash))
    bad = {@bad, t};
  endif
endfor
quiet = caller == this;
if (bad)
  quiet || player:tell("The following bad objects were found in ", susa.name, "'s owned_objects: ", $string_utils:nn(bad));
  for t in (bad)
    susa:cleanup(t);
  endfor
else
  quiet || player:tell("No invalid or $garbage items were found on ", susa.name, "'s owned_objects list.");
endif
quiet ? $byte_quota_utils:summarize_one_user(susa) | $byte_quota_utils:do_summary(susa);
.

@verb #1140:"cycle(old)" this none this
@program #1140:cycle(old)
":cycle() => Run the universal RPG healing task.";
if (caller_perms() == (rpg = $local.rpg).owner)
  next = 1800 + random(900);
  fork (next)
    this:cycle();
    if (rpg.gm_lag < rpg.idle_threshold)
      this:heal();
      this.last_cycle = time();
    endif
  endfork
endif
.

@verb #1140:"rebirth" this none this
@program #1140:rebirth
if ((time() < this.next_rebirth) || (!this.resurrection_queue))
  return E_NONE;
endif
cemetery = (rpg = $local.rpg).cemetery;
if (caller != cemetery)
  return E_PERM;
elseif ($code_utils:task_valid(this.resurrection_task) && $code_utils:owns_task(this.resurrection_task, rpg.owner))
  return E_NACC;
elseif ($list_utils:iassoc("read_lines_escape", queued_tasks(), 7))
  return E_QUOTA;
endif
this.resurrection_task = task_id();
".resurrection_queue structure: LIST of {OBJ beastie, NUM time it died}";
pos = ((p = this.resurrection_queue_pos) > length(this.resurrection_queue)) ? 1 | p;
try
  {beast, time} = this.resurrection_queue[pos];
except (E_RANGE)
  "Means we have a blank resurrection queue";
endtry
this.next_rebirth = (this.next_rebirth + (60 + min(rpg.idle_threshold, 3 * rpg.gm_lag))) - (length(this.resurrection_queue) * (!this.clean_susa));
if ((((!rpg.object_db:is_monster(beast)) || (beast.location != cemetery)) || (typeof(`gestate = beast.gestate ! E_PROPNF, E_PERM') != NUM)) || (gestate < 0))
  "What the heck is it doin in the queue?";
  this.resurrection_queue = listdelete(this.resurrection_queue, pos);
elseif (this:not_checkpoint() && (time() >= (time + gestate)))
  "Bring it back to life.";
  fork (3 + rpg.gm_lag)
    if (!beast.alive)
      try
        force_input(this.owner, tostr("quietbirth ", beast));
      except x (ANY)
        "Notify the beast's owner";
        $mail_agent:send_message(this, {beast.owner}, {"Error birthing " + $string_utils:nn(beast), {rpg.object_db.bugs}}, ($string_utils:from_value(x, 1, 5) + " ") + tostr(beast));
      endtry
    endif
  endfork
  this.resurrection_queue = listdelete(this.resurrection_queue, pos);
  this.monster_orphans = setadd(this.monster_orphans, beast);
  if (this.clean_susa)
    this:susaclean();
    this.clean_susa = 0;
  endif
  "If all is well the cemetery's :exitfunc will remove the beast from the orphans list.";
elseif ((!this.clean_susa) && (!this:not_checkpoint()))
  this.clean_susa = 1;
elseif (this.next_rebirth >= (time + gestate))
  "... do nothing this critter will be born next pass ... ";
else
  this.resurrection_queue_pos = pos + 1;
endif
"THX (#105941) - Sun Apr 15, 2001 - Moved essential code from this:cycle3() and altered it to trigger from cemetery's enterfunc.   G_M force_inputs the birth call so player's won't get the TBs.";
"THX (#105941) - Wed Apr 18, 2001 - Put a $code_utils:owns_task() in there too.  Doesn't take many ticks and doesn't run often.";
.

@verb #1140:"cycle2(obsolete)" this none this
@program #1140:cycle2(obsolete)
":cycle2() -- run the universal RPG stat-restoring cycle.";
if (caller_perms() == (rpg = $local.rpg).owner)
  fork (600 + rpg.gm_lag)
    this:cycle2();
    if (rpg.gm_lag < rpg.idle_threshold)
      this:restore_ATTs();
      this.last_cycle2 = time();
    endif
    archiver = rpg.archiver;
    if ((archiver.last_doll_archive + this.archive_interval) < time())
      archiver.last_doll_archive = time();
      "... :doll_archive will set this, too, but we ...";
      "... don't want this verb calling it more than...";
      "... once while it's still running            ...";
      fork (0)
        archiver:doll_archive();
      endfork
    endif
  endfork
endif
"Isagi 30-SEP-94 4:43P Added  This scheduler (hopefully) runs every ten minutes";
"THX1138 20-Jun-1997 --  Added a call to :gm_lag() to back this task off a bit if G_M is really lagged.  Every 10 minutes is desirable, but not essential.";
"Mooshie (#106469) - Sat Oct 30, 1999 - Added a hook for the doll archival task. Seemed an appropriate place.";
.

"***finished***