dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
/*  -*- LPC -*-  */
/*
 * $Locker:  $
 * $Id: team.c,v 1.3 1999/10/28 02:22:12 ceres Exp $
 * $Log: team.c,v $
 * Revision 1.3  1999/10/28 02:22:12  ceres
 * tweaks
 *
 * Revision 1.2  1998/07/13 04:29:44  pinkfish
 * Fixed up a couple of things that shouldmake it stop giving empty team lists...
 *
 * Revision 1.1  1998/01/06 05:03:33  ceres
 * Initial revision
 * 
*/
#define CREATOR "Ceres"
/**
 * This handler deals with grouping players into teams. Teams are entirely
 * optional.  The handler deals with creating, joining, leaving and ending
 * teams.  It also provides functions to find out who's a member of which
 * team etc.<p>
 *
 * Commands will be available to do group things (group chatting, group
 * health etc.) By default team members will protect each other and follow
 * the leader.
 *
 * @author Ceres
 * @started June 96
 */

#include <login_handler.h>

#define SHADOW "/std/shadows/misc/team"
#define MAX_GROUP_SIZE 5

class group {
  object leader;    // the team leader
  int policy;       // the follow policy
  object *members;  // list of members
  int locked;       // is this group open to new members
}

mapping groups,     // all the teams
        members;    // which team each player is a member of

private void check_group(string g_name);
private void disband_group(string g_name, string p_name);
private void tidy_members(string g_name);

/** @ignore yes */
void create() {
  members = ([ ]);
  groups = ([ ]);
} /* create() */

/** @ignore yes */
void dest_me() {
  destruct(this_object());
} /* dest_me() */

/**
 * When a player leaves the game automatically remove them from their team.
 * this function is called automatically by the login handler for every
 * player who leaves the game
 * @param p_name the player name who is leaving
 * @param type the type of action being preformed
 * @see /obj/handlers/login_handler
 */
void leaving(string p_name, string type) {
  class group record;
  string g_name;

  if((type != "logout") || (!members[p_name]))
    return;

  g_name = members[p_name];
  record = (class group)groups[g_name];

  map_delete(members, p_name);

  if(!record)
    return;
  
  // no leader? Then disband the group.
  if((record->leader == 0) || ((record->leader)->query_name() == p_name)) {
     disband_group(g_name, p_name);

#ifdef LOG_FILE    
    log_file(LOG_FILE, sprintf("%s %s has left the game, the %s has been "
                             "disbanded.\n", ctime(time()), p_name, g_name));
#endif    

  } else {
#ifdef LOG_FILE
    log_file(LOG_FILE, sprintf("%s %s left the game while a member of the %s\n",
                             ctime(time()), p_name, g_name));
#endif    
    record->members = delete(record->members,
                             member_array(0, record->members), 1);
  }
  return;
} /* leaving() */

/* Group modification functions */

/**
 * This method creates a new team.
 * @param g_name the name of the group
 * @param leader the leader of the group (object)
 * @param policy the policy of the group
 * @see end_group()
 */
int new_group(string g_name, object leader, int policy) {
  class group record;
  
  if(!undefinedp(groups[g_name]))
    return 0;

  record = new(class group);

  record->leader = leader;
  record->policy = policy;
  record->members = ({ leader });

  groups[g_name] = record;

  members[leader->query_name()] = g_name;

  leader->set_title( "TEAM", "Team Leader of "+ g_name );
   clone_object( SHADOW )->setup_shadow( leader );

#ifdef LOG_FILE
  log_file(LOG_FILE, sprintf("%s %s created by %s\n", ctime(time()),
                           g_name, leader->query_name()));
#endif  
  return 1;
} /* new_group() */

/**
 * This method ends a group.  Closes it, finishes it, done, finito.
 * @param g_name the name of the group to close
 * @see new_group()
 */
int end_group(string g_name) {
  class group record;
  object player;
  
  if(undefinedp(groups[g_name]))
    return 0;

  record = groups[g_name];
  
  // mark all group members as not being members of a group anymore
   foreach( player in record->members )
      if ( player ) {
         map_delete( members, player->query_name() );
         player->remove_title( "TEAM" );
         player->destruct_team_shadow();
      }
   
  
  map_delete(groups, g_name);

#ifdef LOG_FILE
  log_file(LOG_FILE, sprintf("%s %s disbanded\n", ctime(time()), g_name));
#endif  
  return 1;
} /* end_group() */

// join an already existing team
/**
 * This method joins a player into an existing group.
 * @param g_name the name of the group to join
 * @param player the player to join to the group
 * @see new_group()
 * @see end_group()
 * @see leave_group()
 */
int join_group(string g_name, object player) {
  class group record;

  if(undefinedp(groups[g_name]))
    return 0;

  record = groups[g_name];
  record->members += ({ player });

  members[player->query_name()] = g_name;

   player->set_title( "TEAM", "Team Member of "+ g_name );
   clone_object( SHADOW )->setup_shadow( player );

#ifdef LOG_FILE
  log_file(LOG_FILE, sprintf("%s %s joined by %s\n", ctime(time()),
                           g_name, player->query_name()));
#endif  
  return 1;
} /* join_group() */

// leave a team
/**
 * This method removes a player from the group.
 * @param g_name the name of the group to leave
 * @param player the player to leave the group
 * @see join_group()
 */
int leave_group(string g_name, object player) {
  class group record;
  
  if(player) {
    map_delete(members, player->query_name());

      player->remove_title( "TEAM" );
      player->destruct_team_shadow();

#ifdef LOG_FILE
    log_file(LOG_FILE, sprintf("%s %s left by %s\n", ctime(time()), g_name,
                             player->query_name()));
#endif    
  }

  if(undefinedp(groups[g_name]))
    return 0;

  record = groups[g_name];

  if(member_array(player, record->members) == -1)
    return -1;

  record->members = delete(record->members,
                           member_array(player, record->members), 1);

  return 1;
} /* leave_group() */


/* Group interrogation functions. */

/**
 * This method determine the owner (leader)  of a team.
 * @param g_name the name of the group to get the owner for
 * @return the object refering to the owner
 * @see query_members()
 * @see query_policy()
 */
object query_owner(string g_name) {
  class group record;

  if(undefinedp(groups[g_name]))
    return 0;

  record = (class group)groups[g_name];

  return record->leader;
} /* query_owner() */

/**
 * This method returns the members of the team.
 * @param g_name the name of the group to get the member of
 * @return the members names as strings
 * @see query_owner()
 * @see query_policy()
 * @see query_leader()
 */
object *query_members(string g_name) {
  class group record;
  
  if(undefinedp(groups[g_name]))
    return 0;

  tidy_members(g_name);

  record = groups[g_name];

  return (object *)record->members;

} /* query_members() */

/**
 * This method returns the policy of the team
 * @param g_name the name of the team
 * @return the policy of the team
 * @see query_members()
 * @see query_leader()
 */
int query_policy(string g_name) {
  class group record;
  
  if(undefinedp(groups[g_name]))
    return 0;

  record = groups[g_name];
  return (int)record->policy;

} /* query_policy() */

/**
 * This method finds out which team player is a member of.
 * @param player the player to find the team of
 * @return the team they are a member of
 */
string query_group(object player) {
  if(undefinedp(members[player->query_name()]))
    return 0;

  return members[player->query_name()];
} /* query_group() */

/**
 * This method determine if a team exists.
 * @param g_name the name of the team
 * @return 1 if the team exists, 0 if not
 * @see new_group()
 * @see query_group()
 */
int test_group(string g_name) {
  if(undefinedp(groups[g_name]))
    return 0;

  return 1;
} /* test_group() */

/**
 * This method checks if its ok to join a group.
 * @param g_name the name of the group
 * @return 1 if the team is full, 0 if not
 * @see join_group()
 */
int query_full(string g_name) {
  class group record;
  object member;
  
  if(undefinedp(groups[g_name]))
    return 0;

  tidy_members(g_name);
  
  record = (class group)groups[g_name];
  
  if(sizeof(record->members) >= MAX_GROUP_SIZE)
    return 1;

  return 0;
} /* query_full() */

/**
 * This method determines if the team is locked.
 * @param g_name the name of the team to test
 * @return 1 if locked, 0 if unlocked
 * @see set_locked()
 */
int query_locked(string g_name) {
  class group record;

  if(undefinedp(groups[g_name]))
    return 0;

  record = (class group)groups[g_name];
  return (record->locked);
} /* query_locked() */

/**
 * This method sets the lock flag on the team.
 * @param g_name the name of the team
 * @param lock the new lock flag
 * @see query_locked()
 */
int set_locked(string g_name, int lock) {
  class group record;

  if(undefinedp(groups[g_name]))
    return 0;

  record = (class group)groups[g_name];
  record->locked = lock;

  return 1;
} /* set_locked() */

// Admin functions for creators

/**
 * This methor returns the list all the current teams.
 * @return an array of all the current team
 */
string *list_groups() {
  string frog;

  foreach (frog in keys(groups)) {
    check_group(frog);
  }
  return keys(groups);
} /* list_groups() */

/* These methods are specificaly for sanity purposes. */
private void disband_group(string g_name, string p_name) {
  class group record;
  object person;
  object member;

  record = (class group)groups[g_name];
  // go through the team members removing them from their team and
  // removing their followers and protectors
  foreach(member in record->members) {

    if(!member) // just in case
      break;
    
    map_delete(members, member->query_name());
    
    foreach(person in member->query_protectors())
      member->remove_protector(person);

    foreach(person in member->query_followers())
      member->remove_follower(person);

    tell_object(member, p_name+" has left the game and so the "+g_name+
                " has been disbanded.\n");
  }
  map_delete(groups, g_name);
} /* disband_group() */

// This method checks the group to see if it has any bad members, ie: 0's.
private void check_group(string g_name) {
  class group record;

  record = (class group)groups[g_name];
  if (record->leader == 0) {
    /* Kill the group. */
    disband_group(g_name, "Your leader");
  } else {
    record->members -= ({ 0 });
  }
} /* check_group() */

private void tidy_members(string g_name) {
  class group record;
  object member;

  record = (class group)groups[g_name];

  foreach(member in record->members)
    if(!member)
      record->members -= ({ 0 });
}