nakedmudv3.0/
nakedmudv3.0/lib/
nakedmudv3.0/lib/logs/
nakedmudv3.0/lib/misc/
nakedmudv3.0/lib/players/
nakedmudv3.0/lib/pymodules/
nakedmudv3.0/lib/txt/
nakedmudv3.0/lib/world/
nakedmudv3.0/lib/world/examples/
nakedmudv3.0/lib/world/examples/mproto/
nakedmudv3.0/lib/world/examples/oproto/
nakedmudv3.0/lib/world/examples/reset/
nakedmudv3.0/lib/world/examples/rproto/
nakedmudv3.0/lib/world/examples/trigger/
nakedmudv3.0/lib/world/limbo/
nakedmudv3.0/lib/world/limbo/rproto/
nakedmudv3.0/src/alias/
nakedmudv3.0/src/char_vars/
nakedmudv3.0/src/editor/
nakedmudv3.0/src/example_module/
nakedmudv3.0/src/help/
nakedmudv3.0/src/set_val/
nakedmudv3.0/src/socials/
nakedmudv3.0/src/time/
//*****************************************************************************
//
// char_gen.c
//
// Contains all of the functions neccessary for generating a new character. 
// Different muds will handle this process in wildly different ways. As such,
// I figured it would be good to localize all of the login details to a single 
// file for people to tailor to their specific mud. It also makes updating to 
// newer versions a bit easier. Your character generation process should be
// laid out here. A basic framework is given, but it could use lots of work. In
// fact, it is crap and could use LOTS of work. I encourage people to write 
// their own login procedure and submit their designs to me so I can develop a 
// better general method for later versions of the mud.
//
//*****************************************************************************

#include "mud.h"
#include "utils.h"
#include "socket.h"
#include "account.h"
#include "character.h"
#include "room.h"
#include "world.h"
#include "save.h"
#include "races.h"
#include "handler.h"
#include "inform.h"
#include "hooks.h"



//*****************************************************************************
// local functions, defines, structures, and the like
//*****************************************************************************

// functions in the char creation procedure
void char_ask_name(SOCKET_DATA *sock, char *arg);
void char_ask_sex (SOCKET_DATA *sock, char *arg);
void char_ask_race(SOCKET_DATA *sock, char *arg);


//
// List all of the races available during creation
void list_races(SOCKET_DATA *sock) {
  send_to_socket(sock, "Available races are:\r\n");
  send_to_socket(sock, "%s", raceGetList(TRUE));
  send_to_socket(sock, "\r\n\r\nPlease enter your choice: ");
}


//
// Character names must be at least 4 characters long, and no more than 12.
// The name must only be composed of alphanumeric characters
bool check_char_name(const char *name) {
  int i, size = strlen(name);
  if (size < 3 || size > 12)
    return FALSE;
  for (i = 0; i < size; i++)
    if (!isalpha(name[i])) 
      return FALSE;
  return TRUE;
}


//
// Query for the character's name.
void char_ask_name(SOCKET_DATA *sock, char *arg) {
  CHAR_DATA *ch = NULL;

  // check for a legal name
  if(!check_char_name(arg))
    text_to_buffer(sock, 
		   "Sorry, that was an illegal name. Please pick another.\r\n"
		   "What is your name? ");

  // a character with this name already exists
  else if(player_exists(arg))
    text_to_buffer(sock,
		   "A character with this name already exists.\r\n"
		   "What is your name? ");

  // someone's already creating a character with this name
  else if(player_creating(arg))
    text_to_buffer(sock, "Someone is already creating a player with that name."
		   "\r\nTry again: ");

  // we're OK to make this new character
  else {
    ch = newChar();

    // give the player it's name 
    *arg = toupper(*arg);
    charSetName(ch, arg);

    // and room description. In the future, we may want
    // to consider allowing players to set their own rdescs 
    char rdesc[SMALL_BUFFER];
    sprintf(rdesc, "%s is here.", arg);
    charSetRdesc(ch, rdesc);

    // socket <-> player 
    charSetSocket(ch, sock);
    socketSetChar(sock, ch);

    // prepare for next step 
    text_to_buffer(sock, "What is your sex (M/F/N)? ");
    socketReplaceInputHandler(sock, char_ask_sex, NULL);
  }
}


//
// Ask for the character's sex. 
void char_ask_sex (SOCKET_DATA *sock, char *arg) {
  switch(toupper(*arg)) {
  case 'F':
    charSetSex(socketGetChar(sock), SEX_FEMALE);
    break;
  case 'M':
    charSetSex(socketGetChar(sock), SEX_MALE);
    break;
  case 'N':
    charSetSex(socketGetChar(sock), SEX_NEUTRAL);
    break;
  default:
    text_to_buffer(sock, "\r\nInvalid sex. Try again (M/F/N) :");
    return;
  }

  // onto race choosing
  socketReplaceInputHandler(sock, char_ask_race, NULL);
  list_races(sock);
}


//
// Pick a race for our new character
void char_ask_race(SOCKET_DATA *sock, char *arg) {
  if(!arg || !*arg || !raceIsForPC(arg))
    send_to_socket(sock, "Invalid race! Please try again: ");
  else {
    charSetRace(socketGetChar(sock), arg);
    charResetBody(socketGetChar(sock));

    // give the character a unique id 
    int next_char_uid = mudsettingGetInt("puid") + 1;
    mudsettingSetInt("puid", next_char_uid);
    charSetUID(socketGetChar(sock), next_char_uid);
    
    // if it's the first player, give him all priviledges
    if(charGetUID(socketGetChar(sock)) == 1)
      bitSet(charGetUserGroups(socketGetChar(sock)),
	     "admin, builder, scripter, player, playtester");

    // add the character to the game 
    char_to_game(socketGetChar(sock));
    
    log_string("New player: %s has entered the game.", 
	       charGetName(socketGetChar(sock)));
    
    // and into the game 
    // pop the input handler for char creation and add the one for
    // playing the game
    socketReplaceInputHandler(sock, handle_cmd_input, show_prompt);
    text_to_buffer(sock, bufferString(motd));
    
    // we should do some checks here to make sure the start room exists
    char_to_room(socketGetChar(sock), worldGetRoom(gameworld, START_ROOM));
    look_at_room(socketGetChar(sock), charGetRoom(socketGetChar(sock)));
    
    // and register him as a valid player
    register_player(socketGetChar(sock));
    
    //************************************************************
    //******                 VERY IMPORTANT                 ******
    //************************************************************
    // add this character to our account list
    accountPutChar(socketGetAccount(sock), charGetName(socketGetChar(sock)));
    save_account(socketGetAccount(sock));

    // run entrance hooks
    ROOM_DATA      *room = charGetRoom(socketGetChar(sock));
    hookRun("enter", socketGetChar(sock), room, NULL);
  }
}



//*****************************************************************************
// implementation of char_gen.c
//*****************************************************************************
void start_char_gen(SOCKET_DATA *sock) {
  text_to_buffer(sock, "What is your character's name? ");
  socketPushInputHandler(sock, char_ask_name, NULL);
}