@create #77399 named Bovine Familiar FO:Bovine Familiar FO,dcf
@prop #15870."notify_task" 0 r
@prop #15870."notify_tasks" {} r
;;#15870.("notify_tasks") = {661168078}
@prop #15870."gm_utils" #27326 rc
@prop #15870."quinn_utils" #34283 r
;;#15870.("help_msg") = "Some magick words bestowed upon faithful Bovine Illuminati, to help them in their quests."
;;#15870.("feature_verbs") = {"score", "inspect", "pot", "@rpg", "@gms", "@claimed"}
;;#15870.("guest_ok") = 1
"#15870.("key") => E_PERM (Permission denied)
;;#15870.("aliases") = {"Bovine Familiar FO", "dcf"}
;;#15870.("description") = "A small cow with draconic wings.  It moos happily to you, ready to help make LambdaMOO a better place for gamers."
;;#15870.("object_size") = {11991, 1141286591}

@verb #15870:"sc*ore health ht co*ndition" any none none rxd
@program #15870:score
"sc*ore [<character>]       => health & readied equipment";
this:update_usage(verb, player, args);
if ($object_utils:has_callable_verb(player.location, verb))
  return player.location:(verb)(@args);
endif
this.gm_utils:score();
.

@verb #15870:"@rpg" any any any rxd
@program #15870:@rpg
"@rpg [limiter]";
"Lists all Bovine Illuminati online and either wounded, fatigued, or in an RPG-room.";
"`limiters' should be one of `here' or a list of player names.";
"An asterisk (*) by a room name means it's an RPG room.";
people = data = {};
RPG = $local.rpg;
gms = $set_utils:difference(RPG.gms, RPG.private_gms);
dungeon = RPG.dungeon;
if (!args)
  people = $set_utils:intersection(connected_players(), RPG.pcs);
else
  if (here = "here" in args)
    args = listdelete(args, here);
  endif
  if (args && (!(people = listdelete($command_utils:player_match_result($string_utils:match_player(args), args), 1))))
    return;
  endif
  if (here)
    people = $set_utils:union(people, player.location:contents());
  endif
endif
if (!people)
  player:tell("Nobody matches the given limiters.");
  return E_NONE;
endif
for dude in (people)
  if (valid(doll = RPG:get_doll(dude)))
    class = (gm = dude in gms) ? "GM" | "PC";
    where = valid(room = dude.location) ? (dr = (room.owner in gms) && $object_utils:isa(room, dungeon)) ? tostr("* ", room:title(dude)) | tostr("  ", room:title(dude)) | "-- limbo --";
    status = {doll:get_att("inj") ? "wounded" | "", doll:get_att("ins") ? "fatigued" | ""};
    try
      position = $code_utils:verb_or_property(room, "resting", dude) ? "resting" | ($code_utils:verb_or_property(room, "sleeping", dude) ? "sleeping" | "");
    except (ANY)
      position = "???";
    endtry
    status = {@status, (((agg = this:combatants(dude)) && (doll:get_att("last_action") > (time() - 30))) ? tostr("fighting ", agg[1].name, " ") | "") || position};
    if (((status = $list_utils:setremove_all(status, "")) || dr) || gm)
      data = {@data, {class, dude.name, where, ((idletime = `idle_seconds(dude) ! ANY => -1') >= 0) ? this:abbr_time(idletime) | "gone", $string_utils:english_list(status, "")}};
    endif
  endif
  $command_utils:suspend_if_needed(1);
endfor
head = {"Cls", "Name", "Location", "Idle", "Status"};
player:tell_lines(this:graph(head, data, 3, {0, 0, 24}));
.

@verb #15870:"ins*pect" any any any rx
@program #15870:inspect
"ins*pect <character> -- Shows `mirror stats' on given character, plus a list of possible commands executable upon them.";
this:update_usage(verb, player, args);
what = dobjstr ? player:my_match_object(dobjstr) | player;
if ($command_utils:object_match_failed(what, dobjstr))
  return E_INVARG;
elseif (!(player in what.location:contents()))
  player:tell($string_utils:pronoun_sub("You must be in the same room as %n in order to inspect %o.", what));
  return E_NACC;
endif
addb = $local.rpg;
player:tell(" ", what:title());
if (valid(addb:get_doll(what)))
  this.gm_utils:mirror(what);
  addb:look_health(what);
  if ((!$object_utils:isa(what, addb.monster)) || (!what.animal))
    addb:look_gear(what);
  endif
else
  player:tell("( Not of the Bovine Illuminati )");
endif
verbs = {};
v = -1;
while ((info = verb_info(what, tostr(v = v + 1))) != E_VERBNF)
  if (((vargs = verb_args(what, tostr(v))) && (vargs != {"this", "none", "this"})) && ("this" in vargs))
    verbs = {@verbs, tostr("\"", info[3], "\"")};
  endif
endwhile
if (verbs)
  player:tell("Possible Commands: ", $string_utils:english_list(verbs, "None"));
endif
.

@verb #15870:"@gms @GMS @G_Ms" any none none rxd
@program #15870:@gms
"@gms      => all connected Game-Masters of the Bovine Illuminati";
"@gms all  => all Game-Masters";
"@g_ms     => all connected Grand_Masters: elders of the Bovine Illuminati.";
"@g_ms all => all Grand_Masters.";
"@GMS (capitalised) will also show Grand_Masters.";
this:update_usage(verb, player, args);
set = strcmp(verb, "@gms") ? (mode = #2693) || $local.rpg.grand_masters | ((mode = #46) || #46.gms);
if ((!args) || (args[1] != "all"))
  set = $set_utils:intersection(connected_players(), set);
endif
if (set)
  this.notify_tasks = setadd(this.notify_tasks, task_id());
  $code_utils:show_who_listing(set);
  this.notify_tasks = setremove(this.notify_tasks, task_id());
else
  player:tell((mode == #2693) ? "None of Grand_Master's incarnations" | "No Game-Masters", " are currently logged in.");
  player:tell("Use `@G_Ms all' to get the full list.");
endif
.

@verb #15870:"notify tell" this none this
@program #15870:notify
if (task_id() in this.notify_tasks)
  return player:tell(@args);
endif
.

@verb #15870:"graph abbr_time" this none this
@program #15870:graph
return this.quinn_utils:(verb)(@args);
.

@verb #15870:"combatants" this none this
@program #15870:combatants
return this.gm_utils:(verb)(@args);
.

@verb #15870:"pot*ential" any none none rxd
@program #15870:potential
"pot";
"Show your potential for improving random physical and mental attributes.";
if (!dobjstr)
  who = player;
else
  who = player:my_match_object(dobjstr);
  if ($match_utils:object_match_failed(who, dobjstr, player.location:contents()))
  endif
endif
this.gm_utils:look_potential(who);
.

@verb #15870:"@claimed" any none none rxd
@program #15870:@claimed
"@claimed <character>";
"Show all RPG objects claimed by the given character.";
RPG = $local.rpg;
matched = RPG:match_character(dobjstr || player.name);
if (RPG:character_match_failed(matched, dobjstr))
  return;
endif
char = matched[1];
doll = matched[2];
claimed = doll:claimed_objects();
if (!claimed)
  player:tell($string_utils:pronoun_sub("%N %<claims> nothing.", (player == char) ? $you | char));
  return E_NONE;
endif
player:tell($string_utils:pronoun_sub("Objects %n %<has> claimed include:", (player == char) ? $you | char));
weapon = RPG.weapon;
armour = RPG.armour;
for c in (claimed)
  parents = $object_utils:ancestors(c);
  if (weapon in parents)
    flags = "W";
  elseif (armour in parents)
    flags = "A";
  else
    flags = " ";
  endif
  player:tell(tostr("  ", flags, ": ", c:title(), " (", c, ")"));
endfor
player:tell(("Total of " + tostr(length(claimed))) + " object(s).");
.

@verb #15870:"active_players" this none this
@program #15870:active_players
":active_players()";
"Return a list of active RPG players.  'Active' is defined as a user with a valid RPG doll who is:";
" wounded, insane, or fatigued, OR";
" in an RPG dungeon room, OR";
" fighting within the past 30 seconds";
rpg = $local.rpg;
obu = $object_utils;
dun = rpg.dungeon;
gms = rpg.gms;
tim = time() - 30;
pcs = {};
for u in (connected_players())
  if (!valid(doll = rpg:get_doll(u)))
  elseif (u in gms)
    pcs = {@pcs, u};
  elseif (obu:isa(u.location, dun))
    pcs = {@pcs, u};
  elseif ((doll:get_att("inj") || doll:get_att("ins")) || doll:get_att("fat"))
    pcs = {@pcs, u};
  elseif ((agg = this:combatants(u)) && (doll:get_att("last_action") > tim))
    pcs = {@pcs, u};
  endif
endfor
return pcs;
.

@verb #15870:"@rpg-old" any any any rxd
@program #15870:@rpg-old
"@rpg [limiter]";
"Lists all Bovine Illuminati online and either wounded, fatigued, or in an RPG-room.";
"`limiters' should be one of `here' or a list of player names.";
"An asterisk (*) by a room name means it's an RPG room.";
this:update_usage(verb, player, args);
people = data = {};
head = {"Cls", "Name", "Location", "Idle", "Status"};
rpg = $local.rpg;
gms = rpg.gms;
if (!args)
  people = connected_players();
else
  if (here = "here" in args)
    args = listdelete(args, here);
  endif
  if (args && (!(people = listdelete($command_utils:player_match_result($string_utils:match_player(args), args), 1))))
    return;
  endif
  if (here)
    people = $set_utils:union(people, player.location:contents());
  endif
endif
if (!people)
  player:tell("Nobody matches the given limiters.");
  return E_NONE;
endif
for dude in (people)
  if (valid(doll = rpg:get_doll(dude)))
    class = (gm = dude in gms) ? "GM" | "PC";
    where = valid(room = dude.location) ? (dr = $object_utils:isa(room, rpg.dungeon)) ? tostr("* ", room:title(dude)) | tostr("  ", room:title(dude)) | "-- limbo --";
    status = {doll:get_att("inj") ? "wounded" | "", doll:get_att("ins") ? "fatigued" | ""};
    position = $code_utils:verb_or_property(room, "resting", dude) ? "resting" | ($code_utils:verb_or_property(room, "sleeping", dude) ? "sleeping" | "");
    status = {@status, (((agg = this:combatants(dude)) && (doll:get_att("last_action") > (time() - 30))) ? tostr("fighting ", agg[1].name, " ") | "") || position};
    if (((status = $list_utils:setremove_all(status, "")) || dr) || gm)
      data = {@data, {class, dude.name, where, this:abbr_time(idle_seconds(dude)), $string_utils:english_list(status, "")}};
    endif
  endif
  $command_utils:suspend_if_needed(1);
endfor
player:tell_lines(this:graph(head, data, 3, {0, 0, 24}));
.

"***finished***