/* $Header: /belch_a/users/rearl/tinymuck/src/RCS/player.c,v 1.6 90/09/28 12:24:42 rearl Exp $ */

/*
 * $Log:	player.c,v $
 * Revision 1.6  90/09/28  12:24:42  rearl
 * Added check for NULL in add_hash().
 * 
 * Revision 1.5  90/09/18  08:01:03  rearl
 * Hash functions introduced for player lookup.
 * 
 * Revision 1.4  90/09/16  04:42:39  rearl
 * Preparation code added for disk-based MUCK.
 * 
 * Revision 1.3  90/08/27  03:32:10  rearl
 * Minor initialization stuff for newly created players.
 * 
 * Revision 1.2  90/08/11  04:07:12  rearl
 * *** empty log message ***
 * 
 * Revision 1.1  90/07/19  23:03:57  casie
 * Initial revision
 * 
 *
 */

#include "copyright.h"
#include "config.h"

#include "db.h"
#include "params.h"
#include "interface.h"
#include "externs.h"

static hash_tab player_list[PLAYER_HASH_SIZE];

dbref lookup_player(const char *name)
{
  hash_data *hd;

  if ((hd = find_hash(name, player_list, PLAYER_HASH_SIZE)) == NULL)
    return NOTHING;
  else
    return (hd -> dbval);
}

dbref connect_player(const char *name, const char *password)
{
  dbref player;
  
  if((player = lookup_player(name)) == NOTHING) return NOTHING;
  if(DBFETCH(player)->sp.player.password
     && *DBFETCH(player)->sp.player.password
     && strcmp(DBFETCH(player)->sp.player.password, password)) return NOTHING;
  return player;
}

dbref create_player(const char *name, const char *password)
{
  dbref player;
  
  if(!ok_player_name(name) || !ok_password(password)) return NOTHING;
  
  /* else he doesn't already exist, create him */
  player = new_object();

  /* initialize everything */
  NAME(player) = alloc_string(name);
  DBFETCH(player)->location = PLAYER_START;	/* home */
  FLAGS(player) = TYPE_PLAYER;
#ifdef BUILDER_ALL   /* make players builders by default */
  FLAGS(player) |= BUILDER;
#endif /* BUILDER_ALL */
#ifdef MUCKER_ALL
  FLAGS(player) |= MUCKER;
#endif
  OWNER(player) = player;
  DBFETCH(player)->link = PLAYER_START;
  DBFETCH(player)->exits = NOTHING;
  DBFETCH(player)->sp.player.pennies = NEW_PLAYER_PENNIES;
  DBFETCH(player)->sp.player.password = alloc_string(password);
  DBFETCH(player)->curr_prog = NOTHING;
  DBFETCH(player)->insert_mode = 0;
  DBFETCH(player)->run = 0;
  
  /* link him to PLAYER_START */
  PUSH(player, DBFETCH(PLAYER_START)->contents);
  add_player(player);
  DBDIRTY(player);
  DBDIRTY(PLAYER_START);
  
  return player;
}

void do_password(dbref player, const char *old, const char *newobj)
{
  if(!DBFETCH(player)->sp.player.password
     || strcmp(old, DBFETCH(player)->sp.player.password)) {
    notify(player, "Bad old password.");
  } else if(!ok_password(newobj)) {
    notify(player, "Bad new password.");
  } else {
    free((void *) DBFETCH(player)->sp.player.password);
    DBSTORE(player, sp.player.password, alloc_string(newobj));
    notify(player, "Password changed.");
  }
}

void clear_players(void)
{
  kill_hash(player_list, PLAYER_HASH_SIZE);
  return;
}

void delete_player(dbref who)
{
  (void) free_hash(NAME(who), player_list, PLAYER_HASH_SIZE);
  return;
}

void add_player(dbref who)
{
  hash_data hd;

  hd.dbval = who;
  if (add_hash(NAME(who), hd, player_list, PLAYER_HASH_SIZE) == NULL)
    panic("Out of memory.");
  else
    return;
}