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***