/* -*- 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 });
}