"note: you will need to change all the #2587 to your MOO's"; " object bound to $g.genhistory. Also, change all the #111"; " to a programmer in your MOO, and change all the #112 to "; " a wizard in your MOO. Read the material on Dollar Bay "; " with 'look $g.genhistory' for more complete instructions"; @prop #2587."explore" {} rc @prop #2587."goal" {} rc @prop #2587."tutor" {} rc @prop #2587."action" {} rc @prop #2587."rooms" {} rc ;;#2587.("explore") = {} ;;#2587.("goal") = {} ;;#2587.("tutor") = {} ;;#2587.("action") = {} ;;#2587.("rooms") = {} ;;#2587.("texture") = "smooth" ;;#2587.("image_url") = "defaultgthing" ;;#2587.("detail_prefix") = "detail" ;;#2587.("aliases") = {"Generic History", "history"} ;;#2587.("description") = {"The Dollar Bay (was Geology explorer's) history record", "Note: history for each player is recorded on a separate object;", " that object is referenced from the player's .history property.", "", " The following verbs are defined for managing player history", "", "time_goal_assigned: returns time of last goal assignment, zero if not found", "time_room_entered: returns time of latest room entry, zero if not found", "acts_this_goal: returns list of explorers actions since most recent goal assigned", "acts_this_room: returns list of explorers actions since room entered", "acts_this_session: returns list of explorers actions since logging on", "initialize: set up player's new history object", "connect_times: returns a list of connect times from player history", "create_hist: a one-timer, called from convert_hist, to implement the new history protocol", "convert_hist: a one-timer, to convert from the old history protocol, no longer used", "fix_history_props: a one-time repair function", "merge_lists: a utility that merges two history lists by timestamp and returns merged list;", " useful, for example, to review a player's complete history (or parts of it)", "", "Also note: history objects are ONLY modified by the $g.game_player:update_history verb"} ;;#2587.("object_size") = {0, 0} @verb #2587:"time_goal_assigned" none none none rxd #111 @args #2587:"time_goal_assigned" none none none @chown #2587:time_goal_assigned #111 @chmod #2587:time_goal_assigned rxd @program #2587:time_goal_assigned "time_goal_assigned"; ""; "returns time of last goal assignment"; "returns zero if not found"; ""; history = this; entry = length(history.goal); ""; "Work back through the list until goal assignment found"; while ((entry > 0) && (history.goal[entry][2] != "goal")) entry = entry - 1; endwhile if (entry <= 0) return 0; endif return history.goal[entry][1]; . @verb #2587:"time_room_entered" none none none rxd #111 @args #2587:"time_room_entered" none none none @chown #2587:time_room_entered #111 @chmod #2587:time_room_entered rxd @program #2587:time_room_entered "time_room_entered"; ""; "returns time of latest room entry"; "returns zero if not found"; ""; history = this; entry = length(history.explore); ""; "Work back through the list until enter is found"; while ((entry > 0) && (history.explore[entry][2] != "enter")) entry = entry - 1; endwhile if (entry <= 0) return 0; endif return history.explore[entry][1]; . @verb #2587:"acts_this_goal" none none none rxd #111 @args #2587:"acts_this_goal" none none none @chown #2587:acts_this_goal #111 @chmod #2587:acts_this_goal rxd @program #2587:acts_this_goal "acts_this_goal"; "returns list of explorers actions since goal assigned"; ""; history = this; action_list = {}; assigned = history:time_goal_assigned(); entry = length(history.action); ""; "Work back through the list until time is less than when goal assigned"; while ((entry > 0) && (history.action[entry][1] > assigned)) action_list = {history.action[entry], @action_list}; entry = entry - 1; endwhile return action_list; . @verb #2587:"acts_this_room" none none none rxd #111 @args #2587:"acts_this_room" none none none @chown #2587:acts_this_room #111 @chmod #2587:acts_this_room rxd @program #2587:acts_this_room "acts_this_room"; "returns list of explorers actions since room entered"; ""; history = this; action_list = {}; entered = history:time_room_entered(); entry = length(history.action); ""; "Work back through the list until time is less than when room entered"; while ((entry > 0) && (history.action[entry][1] > entered)) action_list = {history.action[entry], @action_list}; entry = entry - 1; endwhile return action_list; . @verb #2587:"acts_this_session" none none none rxd #111 @args #2587:"acts_this_session" none none none @chown #2587:acts_this_session #111 @chmod #2587:acts_this_session rxd @program #2587:acts_this_session "acts_this_session"; "returns list of explorers actions since logging on"; ""; history = this; action_list = {}; connected = history.owner.last_connect_time; entry = length(history.action); ""; "Work back through the list until time is less than connect time"; while ((entry > 0) && (history.action[entry][1] > connected)) $command_utils:suspend_if_needed(0); action_list = {history.action[entry], @action_list}; entry = entry - 1; endwhile return action_list; . @verb #2587:"initialize" none none none rxd @args #2587:"initialize" none none none @chmod #2587:initialize rxd @program #2587:initialize "initialize"; ""; if ((caller == this) || $perm_utils:controls(caller_perms(), this)) set_task_perms(player); player:tell(" Initializing ", this.owner.name + " History"); this.name = this.owner.name + " history object"; this.aliases = {this.name, "History", "history"}; this.description = ((("The " + this.name) + "'s history record (") + tostr(this)) + ")"; return pass(@args); else return E_PERM; endif . @verb #2587:"connect_times" none none none rxd #111 @args #2587:"connect_times" none none none @chown #2587:connect_times #111 @chmod #2587:connect_times rxd @program #2587:connect_times "connect_times"; ""; "returns a list of connect times from player history"; "last entry is current time"; ""; history = this; connect_list = {}; ""; for entry in (history.explore) $command_utils:suspend_if_needed(0); if (entry[2] == "connect") connect_list = {@connect_list, entry[1]}; endif endfor connect_list = {@connect_list, time()}; return connect_list; . @verb #2587:"merge_lists" none none none rxd @args #2587:"merge_lists" none none none @chmod #2587:merge_lists rxd @program #2587:merge_lists "merge_lists"; "merges two history lists by timestamp and returns merged list"; ""; if (length(args) != 2) player:tell("Usage: merge_lists( list1, list2 )"); else list1 = args[1]; list2 = args[2]; index1 = 1; index2 = 1; merge_list = {}; time = 1; length1 = length(list1); length2 = length(list2); ""; while ((index1 <= length1) && (index2 <= length2)) if (list1[index1][time] <= list2[index2][time]) merge_list = {@merge_list, list1[index1]}; index1 = index1 + 1; else merge_list = {@merge_list, list2[index2]}; index2 = index2 + 1; endif endwhile if (index1 > length1) while (index2 <= length2) merge_list = {@merge_list, list2[index2]}; index2 = index2 + 1; endwhile else while (index1 <= length1) merge_list = {@merge_list, list1[index1]}; index1 = index1 + 1; endwhile endif return merge_list; endif . @verb #2587:"list_succ_goals" none none none rxd #112 @args #2587:"list_succ_goals" none none none @chown #2587:list_succ_goals #112 @chmod #2587:list_succ_goals rxd @program #2587:list_succ_goals ""; " list_succ_goals: review a player's history and return a list of goals they have accomplished "; ""; if (!args) player:tell("Usage: list_succ_goals (OBJ ) "); elseif (length(args) != 1) player:tell("Usage: list_succ_goals (OBJ ) "); else histobj = args[1]; goalhist = histobj.goal; succ_list = {}; for entry in (goalhist) $command_utils:suspend_if_needed(0); if (((length(entry) == 4) && (entry[2] == "goal")) && (entry[4] != 0)) succ_list = setadd(succ_list, entry[3].goal_object); elseif (((length(entry) == 5) && (entry[2] == "guess")) && (entry[5] != 0)) succ_list = setadd(succ_list, entry[4]); endif endfor return succ_list; endif . @verb #2587:"replay_history" none none none rxd #112 @args #2587:"replay_history" none none none @chown #2587:replay_history #112 @chmod #2587:replay_history rxd @program #2587:replay_history ""; " replay_history: print a transcript of a player's history record "; ""; " player:tell(\"Sorry, replay_history is disabled at this time: contact slator@badlands.nodak.edu with questions\"); "; " return; "; if (!args) player:tell("Usage: $g.genhistory:replay_history ( player ) "); elseif (length(args) != 1) player:tell("Usage: $g.genhistory:replay_history ( player ) "); elseif (!valid(args[1])) player:tell("Error: replay_history: invalid arg: ", args[1]); elseif (typeof(args[1].history) != OBJ) player:tell("Error: replay_history: invalid history: ", args[1].history, " on ", args[1]); else history = this; explr = args[1]; exhst = explr.history; goalcnt = actioncnt = explorecnt = tutorcnt = 1; goaltm = actiontm = exploretm = tutortm = $maxint; player:tell("Complete history record for ", $string_utils:nn(explr), " as of ", ctime()); while ((((length(exhst.goal) >= goalcnt) || (length(exhst.action) >= actioncnt)) || (length(exhst.explore) >= explorecnt)) || (length(exhst.tutor) >= tutorcnt)) $command_utils:suspend_if_needed(0); goaltm = (length(exhst.goal) >= goalcnt) ? exhst.goal[goalcnt][1] | $maxint; actiontm = (length(exhst.action) >= actioncnt) ? exhst.action[actioncnt][1] | $maxint; exploretm = (length(exhst.explore) >= explorecnt) ? exhst.explore[explorecnt][1] | $maxint; tutortm = (length(exhst.tutor) >= tutorcnt) ? exhst.tutor[tutorcnt][1] | $maxint; nexttm = min(goaltm, actiontm, exploretm, tutortm); " hack to fudge the early goal history problem, 16nov98, bms"; if ((goaltm != $maxint) && (nexttm == exhst.goal[goalcnt][1])) if (goalcnt == 1) player:tell(this:short_ctime(goaltm), " assigned original goal: ", exhst.goal[goalcnt][3].name); else history:replay_goal(exhst.goal[goalcnt]); endif goalcnt = goalcnt + 1; elseif ((actiontm != $maxint) && (nexttm == exhst.action[actioncnt][1])) history:replay_action(exhst.action[actioncnt]); actioncnt = actioncnt + 1; elseif ((exploretm != $maxint) && (nexttm == exhst.explore[explorecnt][1])) history:replay_explore(exhst.explore[explorecnt]); explorecnt = explorecnt + 1; elseif ((tutortm != $maxint) && (nexttm == exhst.tutor[tutorcnt][1])) history:replay_tutor(exhst.tutor[tutorcnt]); tutorcnt = tutorcnt + 1; endif endwhile player:tell("End of ", $string_utils:nn(explr), " history record"); endif . @verb #2587:"replay_goal" none none none rxd #112 @args #2587:"replay_goal" none none none @chown #2587:replay_goal #112 @chmod #2587:replay_goal rxd @program #2587:replay_goal ""; " replay_goal: print a formatted message for a history/goal entry"; " was: player:tell(toliteral(exhst.goal[goalcnt]));"; ""; tu = $time_utils; glntry = args[1]; tmstmp = this:short_ctime(glntry[1]); if (glntry[2] == "goal") " hack to fudge the early goal history problem, 16nov98, bms "; player:tell(tmstmp, " Previously assigned goal solved -- new goal assigned"); player:tell(tmstmp, " assigned ", glntry[3].name, " scoring ", glntry[4], " points"); elseif (glntry[2] == "correct") player:tell(tmstmp, " reported goal ", $g.game_thing:return_short_name(glntry[3]), " as ", glntry[4].name); elseif (glntry[2] == "guess") player:tell(tmstmp, " reported ", $g.game_thing:return_short_name(glntry[3]), " as ", glntry[4].name, " scoring ", glntry[5], " points"); else player:tell(toliteral(glntry)); endif . @verb #2587:"short_ctime" this none this rxd #112 @args #2587:"short_ctime" this none this @chown #2587:short_ctime #112 @program #2587:short_ctime ""; " short_ctime: to save space on the output monitor "; ""; timearg = args[1]; if (typeof(timearg) == NUM) rtime = ctime(timearg); elseif (typeof(timearg) != STR) rtime = $string_utils:space(16, "?"); else rtime = tostr(timearg); endif return ((rtime[5..7] + rtime[9..10]) + "/") + rtime[12..16]; . @verb #2587:"replay_explore" none none none rxd #112 @args #2587:"replay_explore" none none none @chown #2587:replay_explore #112 @chmod #2587:replay_explore rxd @program #2587:replay_explore ""; " replay_explore: print a formatted message for a history/explore entry"; " was: player:tell(toliteral(exhst.goal[goalcnt]));"; ""; tu = $time_utils; su = $string_utils; exntry = args[1]; tmstmp = this:short_ctime(exntry[1]); if (exntry[2] == "enter") player:tell(tmstmp, " entered ", su:space(15), su:uppercase(su:nn(exntry[3]))); elseif (exntry[2] == "connect") player:tell(tmstmp, " connected ", su:space(6), " TO MOO "); elseif (exntry[2] == "exit") " for now, print nothing "; else player:tell(toliteral(exntry)); endif . @verb #2587:"replay_action" this none this rxd #112 @args #2587:"replay_action" this none this @chown #2587:replay_action #112 @program #2587:replay_action ""; " replay_action: print a formatted message for a history/action entry"; " was: player:tell(toliteral(exhst.goal[goalcnt]));"; ""; tu = $time_utils; su = $string_utils; acntry = args[1]; tmstmp = this:short_ctime(acntry[1]); if (acntry[2] == "look") " format of look has apparently changed from third element of type list to "; " to a 3+ element list. Code changed to match, bms, 27sep99 "; if (length(acntry) > 3) player:tell(tmstmp, " looked at ", su:nn(acntry[3]), " in ", su:nn(acntry[4])); elseif (length(acntry) == 3) player:tell(tmstmp, " looked at ", su:nn(acntry[3])); else player:tell(tmstmp, " looked at the surroundings"); endif elseif (acntry[2] == "purchase") player:tell(tmstmp, " purchased ", acntry[3].name, " for $", acntry[5]); elseif (acntry[2] == "drop") player:tell(tmstmp, " dropped ", su:nn(toobj(acntry[3][1]))); elseif (acntry[2] in {"hit", "scratch", "streak", "pour", "touch", "trash", "taste", "smell"}) actor = acntry[3]; actee = acntry[4]; if (length(acntry) > 4) player:tell(tmstmp, " ", acntry[2], " ", su:nn(actee), " with ", su:nn(actor), " results: ", toliteral(acntry[5])); else player:tell(tmstmp, " ", acntry[2], " ", su:nn(actee), " with ", su:nn(actor), " results not recorded."); endif elseif (acntry[2] in {"view"}) actor = $g.game_thing:return_short_name(acntry[3]); actee = $g.game_thing:return_short_name(acntry[4]); " not reporting the lengthy 10x property for view -- it's a waste of space "; player:tell(tmstmp, " ", acntry[2], " using ", actor, " and ", actee); else player:tell(toliteral(acntry)); endif . @verb #2587:"replay_tutor" none none none rxd #112 @args #2587:"replay_tutor" none none none @chown #2587:replay_tutor #112 @chmod #2587:replay_tutor rxd @program #2587:replay_tutor ""; " replay_tutor: print a formatted message for a history/tutor entry"; " was: player:tell(toliteral(exhst.goal[goalcnt]));"; ""; tu = $time_utils; su = $string_utils; tutory = args[1]; tmstmp = this:short_ctime(tutory[1]); if (tutory[2] == "help") if (length(tutory) < 3) player:tell(tmstmp, " Help "); else player:tell(tmstmp, " Help ", su:from_list(tutory[3..$])); endif elseif (tutory[2] == "Equipment Tutor") player:tell(tmstmp, " ", tutory[2], " says ", tutory[5], " to find ", tutory[3].name); elseif (tutory[2] == "Exploration Tutor") player:tell(tmstmp, " ", tutory[2], " says ", tutory[5], " of ", tutory[3].name); else player:tell(toliteral(tutory)); endif . @verb #2587:"time_on_task" none none none rxd #112 @args #2587:"time_on_task" none none none @chown #2587:time_on_task #112 @chmod #2587:time_on_task rxd @program #2587:time_on_task ""; " time_on_task: count the time on the planet for a player "; " .explore data is a sequence of 'connect' records with intervening "; " room 'enter' and room 'exit' records. Disconnect times are unreliable "; " and therefore not recorded in a player's history "; ""; if (!args) player:tell("Usage: $g.genhistory:time_on_task ( player ) "); elseif (length(args) != 1) player:tell("Usage: $g.genhistory:time_on_task ( player ) "); else plyr = args[1]; if ((((!valid(plyr)) || (plyr.history == 0)) || (!valid(plyr.history))) || (typeof(plyr.history.explore) != LIST)) return; endif hrec = plyr.history.explore; histlen = length(hrec); twentyminutes = 60 * 20; recnt = 1; " skip over records until the first 'connect' is found "; " 'connect' is USUALLY the first record in the history "; while ((recnt <= histlen) && (hrec[recnt][2] != "connect")) $command_utils:suspend_if_needed(0); recnt = recnt + 1; endwhile concnt = 1; recnt = 2; totime = 0; while (recnt < histlen) $command_utils:suspend_if_needed(0); etime = hrec[recnt][1] - hrec[recnt - 1][1]; recnt = recnt + 1; if (etime < twentyminutes) totime = totime + etime; endif if (hrec[recnt][2] == "connect") concnt = concnt + 1; endif endwhile return totime; endif . @verb #2587:"secs_to_ctime" none none none rxd #112 @args #2587:"secs_to_ctime" none none none @chown #2587:secs_to_ctime #112 @chmod #2587:secs_to_ctime rxd @program #2587:secs_to_ctime ""; " secs_to_ctime: convert seconds to an english time format "; ""; timetot = args[1]; week = ((7 * 24) * 60) * 60; day = (24 * 60) * 60; hour = 60 * 60; minute = 60; weeks = days = hours = minutes = 0; if (timetot > week) weeks = timetot / week; timetot = timetot - (weeks * week); endif if (timetot > day) days = timetot / day; timetot = timetot - (days * day); endif if (timetot > hour) hours = timetot / hour; timetot = timetot - (hours * hour); endif if (timetot > minute) minutes = timetot / minute; timetot = timetot - (minutes * minute); endif seconds = timetot; if (weeks == 0) wstr = ""; elseif (weeks == 1) wstr = " 1 week "; else wstr = tostr(weeks) + " weeks "; endif if (days == 0) dstr = ""; elseif (days == 1) dstr = "1 day "; else dstr = tostr(days) + " days "; endif if (hours == 0) hstr = ""; elseif (hours == 1) hstr = "1 hour "; else hstr = tostr(hours) + " hours "; endif if (minutes == 0) mstr = ""; elseif (minutes == 1) mstr = "1 minute "; else mstr = tostr(minutes) + " minutes "; endif if (seconds == 0) sstr = ""; elseif (seconds == 1) sstr = "1 second "; else sstr = tostr(seconds) + " seconds "; endif return (((wstr + dstr) + hstr) + mstr) + sstr; . @verb #2587:"show_time_on_task" none none none rxd #112 @args #2587:"show_time_on_task" none none none @chown #2587:show_time_on_task #112 @chmod #2587:show_time_on_task rxd @program #2587:show_time_on_task ""; " show_time_on_task: display time records from history objects "; ""; if (!args) player:tell("Usage: $g.genhistory:show_time_on_task ( class [ all ] ) "); return; elseif (length(args) > 2) player:tell("Usage: $g.genhistory:show_time_on_task ( class [ all ] ) "); return; elseif (length(args) == 2) allflag = 1; class = args[1]; if (length(children(class)) == 0) class_list = {class}; else class_list = children(class); endif elseif (length(args) == 1) allflag = 0; class = args[1]; if (length(children(class)) == 0) class_list = {class}; else class_list = children(class); endif else player:tell("show_time_on_task: Error: Cannot process args: ", argstr); return; endif " in order to facilitate partial credit, sort by scores, 9Dec98, bms "; sort_indx = sort_list = {}; sort2_indx = {}; otto_list = {}; otto_bags = {}; current_sort = {}; current_sort_indx = {}; for plyr in (class_list) if (!($g.retail_player:get_total_score(plyr) in otto_list)) otto_list = {@otto_list, $g.retail_player:get_total_score(plyr)}; endif endfor otto_list = $list_utils:sort_suspended(0, otto_list); for n in (otto_list) otto_bags = {@otto_bags, {}}; endfor player:tell(toliteral(otto_list)); player:tell(toliteral(otto_bags)); for plyr in (class_list) indx = $g.retail_player:get_total_score(plyr) in otto_list; current_sort = {}; current_sort_indx = {}; current_sort = otto_bags[indx]; current_sort = {@current_sort, plyr}; for n in (current_sort) current_sort_indx = {@current_sort_indx, $g.genhistory:time_on_task(n)}; endfor "player:tell(toliteral(current_sort));"; "player:tell(toliteral(current_sort_indx));"; my_sort = $list_utils:sort_suspended(0, current_sort, current_sort_indx); otto_bags[indx] = my_sort; endfor player:tell(toliteral(otto_list)); player:tell(toliteral(otto_bags)); for a in (otto_list) player:tell(("Players with " + tostr(a)) + " points"); for b in (otto_bags[a in otto_list]) player:tell((("Player " + b.name) + " had a time on task of ") + tostr($g.genhistory:time_on_task(b))); endfor endfor return; for plyr in (class_list) $command_utils:suspend_if_needed(0); sort_indx = {@sort_indx, $g.retail_player:get_total_score(plyr)}; endfor sort_list = $list_utils:sort_suspended(0, class_list, sort_indx); sort_list = $list_utils:reverse_suspended(sort_list); for plyr in (sort_list) $command_utils:suspend_if_needed(0); plyrtot = $g.retail_player:get_total_score(plyr); if (allflag == 0) if (plyrtot > 0) player:tell("Time on Task for ", $string_utils:nn(plyr), " as of ", ctime()); totime = $g.genhistory:time_on_task(plyr); player:tell(" ", $g.genhistory:secs_to_ctime(totime), "- scoring ", plyrtot, " points"); endif else player:tell("Time on Task for ", $string_utils:nn(plyr), " as of ", ctime()); totime = $g.genhistory:time_on_task(plyr); if (totime > 0) player:tell(" ", $g.genhistory:secs_to_ctime(totime), "- scoring ", plyrtot, " points"); else player:tell(" None", "- scoring ", plyrtot, " points"); endif endif endfor . @verb #2587:"tutors_this_session" this none this @args #2587:"tutors_this_session" this none this @program #2587:tutors_this_session "tutors_this_session"; "returns list of tutor visits since logging on"; ""; history = this; action_list = {}; connected = history.owner.last_connect_time; entry = length(history.tutor); ""; "Work back through the list until time is less than connect time"; while ((entry > 0) && (history.tutor[entry][1] > connected)) action_list = {history.tutor[entry], @action_list}; entry = entry - 1; endwhile return action_list; . @verb #2587:"count_reports" this none this @args #2587:"count_reports" this none this @program #2587:count_reports ""; " count_reports: return the guess count for a player "; ""; if (!args) player:tell("Usage: $g.genhistory:count_reports ( player )"); elseif (length(args) != 1) player:tell("Usage: $g.genhistory:count_reports ( player )"); else repcnt = 0; plyr = args[1]; if (((valid(plyr) && (plyr.history != 0)) && valid(plyr.history)) && (typeof(plyr.history.goal) == LIST)) for entry in (plyr.history.goal) if (entry[2] in {"guess", "correct", "goal"}) repcnt = repcnt + 1; endif endfor endif return repcnt; endif . @verb #2587:"count_movements" this none this @args #2587:"count_movements" this none this @program #2587:count_movements ""; " count_movements: return the movement count for a player "; ""; if (!args) player:tell("Usage: $g.genhistory:count_movements ( player )"); elseif (length(args) != 1) player:tell("Usage: $g.genhistory:count_movements ( player )"); else repcnt = 0; plyr = args[1]; if (((valid(plyr) && (plyr.history != 0)) && valid(plyr.history)) && (typeof(plyr.history.explore) == LIST)) for entry in (plyr.history.explore) $command_utils:suspend_if_needed(0); if (entry[2] == "enter") repcnt = repcnt + 1; endif endfor endif return repcnt; endif . @verb #2587:"count_experiments" this none this @args #2587:"count_experiments" this none this @program #2587:count_experiments ""; " count_experiments: return the experiment count for a player "; ""; if (!args) player:tell("Usage: $g.genhistory:count_experiments ( player )"); elseif (length(args) != 1) player:tell("Usage: $g.genhistory:count_experiments ( player )"); else repcnt = 0; explist = {"bite", "heft", "hit", "irradiate", "measure", "pour", "powderize", "process", "scratch", "smell", "streak", "taste", "touch", "view"}; plyr = args[1]; if (((valid(plyr) && (plyr.history != 0)) && valid(plyr.history)) && (typeof(plyr.history.action) == LIST)) for entry in (plyr.history.action) $command_utils:suspend_if_needed(0); if (entry[2] in explist) repcnt = repcnt + 1; endif endfor endif return repcnt; endif . @verb #2587:"time_task_calc" none none none rxd #112 @args #2587:"time_task_calc" none none none @chown #2587:time_task_calc #112 @chmod #2587:time_task_calc rxd @args #2587:"moves_this_goal" none none none @chown #2587:moves_this_goal #111 @chmod #2587:moves_this_goal rxd @program #2587:moves_this_goal "USAGE: moves_this_goal()"; "returns list of explorers moves since goal assigned"; ""; history = this; explore_list = {}; assigned = history:time_goal_assigned(); entry = length(history.explore); ""; "Work back through the list until time is less than when goal assigned"; while ((entry > 0) && (history.explore[entry][1] > assigned)) $command_utils:suspend_if_needed(0); if (history.explore[entry][2] == "enter") explore_list = {history.explore[entry], @explore_list}; endif entry = entry - 1; endwhile return explore_list; . @verb #2587:"moves_this_visit" none none none rxd #112 @args #2587:"moves_this_visit" none none none @chown #2587:moves_this_visit #111 @chmod #2587:moves_this_visit rxd @program #2587:moves_this_visit "USAGE: moves_this_visit()"; "returns list of explorers moves this visit"; ""; history = this; explore_list = {}; connect_times = history:connect_times(); n = length(connect_times); connected = connect_times[n]; entry = length(history.explore); ""; "Work back through the list until time is less than when explorer connected"; while ((entry > 0) && (history.explore[entry][1] > connected)) $command_utils:suspend_if_needed(0); if (history.explore[entry][2] == "enter") explore_list = {history.explore[entry], @explore_list}; endif entry = entry - 1; endwhile return explore_list; .