/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik Strfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Thanks to abaddon for proof-reading our comm.c and pointing out bugs. * * Any remaining bugs are, of course, our work, not his. :) * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ****************************************************************************/ /**************************************************************************** * This file is just the stock nanny() function ripped from comm.c. It * * seems to be a popular task for new mud coders, so what the heck? * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #include <sys/time.h> #endif #include <ctype.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <unistd.h> /* OLC -- for close read write etc */ #include <stdarg.h> /* printf_to_char */ #include "merc.h" #include "interp.h" #include "recycle.h" #include "tables.h" #if defined(macintosh) || defined(MSDOS) extern const char echo_off_str[]; extern const char echo_on_str[]; extern const char go_ahead_str[]; #endif #if defined(unix) #include <fcntl.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #include "telnet.h" extern const char echo_off_str[]; extern const char echo_on_str[]; extern const char go_ahead_str[]; #endif /* * OS-dependent local functions. */ #if defined(macintosh) || defined(MSDOS) void game_loop_mac_msdos args ((void)); bool read_from_descriptor args ((DESCRIPTOR_DATA * d)); bool write_to_descriptor args ((int desc, char *txt, int length)); #endif #if defined(unix) void game_loop_unix args ((int control)); int init_socket args ((int port)); void init_descriptor args ((int control)); bool read_from_descriptor args ((DESCRIPTOR_DATA * d)); bool write_to_descriptor args ((int desc, char *txt, int length)); #endif /* * * Other local functions (OS-independent). * */ bool check_parse_name args ((char *name)); bool check_reconnect args ((DESCRIPTOR_DATA * d, char *name, bool fConn)); bool check_playing args ((DESCRIPTOR_DATA * d, char *name)); /* * Global variables. */ extern DESCRIPTOR_DATA *descriptor_list; /* All open descriptors */ extern DESCRIPTOR_DATA *d_next; /* Next descriptor in loop */ extern FILE *fpReserve; /* Reserved file handle */ extern bool god; /* All new chars are gods! */ extern bool merc_down; /* Shutdown */ extern bool wizlock; /* Game is wizlocked */ extern bool newlock; /* Game is newlocked */ extern char str_boot_time[MAX_INPUT_LENGTH]; extern time_t current_time; /* time of this pulse */ /* * Deal with sockets that haven't logged in yet. */ void nanny (DESCRIPTOR_DATA * d, char *argument) { DESCRIPTOR_DATA *d_old, *d_next; ACCOUNT_DATA *account; char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; CHAR_DATA *ch; // char *pwdnew; char *pwdnew, *option; char *p; bool fOld; int iClass, race, i, weapon, god; extern int mud_telnetga, mud_ansicolor; /* Delete leading spaces UNLESS character is writing a note */ if (d->connected != CON_NOTE_TEXT) { while ( isspace(*argument) ) argument++; } ch = d->character; switch (d->connected) { default: bug ("Nanny: bad d->connected %d.", d->connected); close_socket (d); return; case CON_ANSI: if (argument[0] == '\0' || UPPER (argument[0]) == 'Y') { d->ansi = TRUE; send_to_desc ("{RAnsi enabled!{x\n\r", d); // d->connected = CON_GET_NAME; d->connected = CON_ACCOUNT_NAME; { extern char *help_greeting; if (help_greeting[0] == '.') send_to_desc (help_greeting + 1, d); else send_to_desc (help_greeting, d); } break; } if (UPPER (argument[0]) == 'N') { d->ansi = FALSE; send_to_desc ("Ansi disabled!\n\r", d); // d->connected = CON_GET_NAME; d->connected = CON_ACCOUNT_NAME; { extern char *help_greeting; if (help_greeting[0] == '.') send_to_desc (help_greeting + 1, d); else send_to_desc (help_greeting, d); } break; } else { send_to_desc ("Do you want ANSI? (Y/n) ", d); return; } // case CON_GET_NAME: case CON_ACCOUNT_NAME: if (argument[0] == '\0') { close_socket (d); return; } // argument[0] = UPPER (argument[0]); // if (!check_parse_name (argument)) if ( check_ban( d->host, BAN_ALL) ) { // send_to_desc ("Illegal name, try another.\n\rName: ", d); write_to_buffer(d, "Your site has been banned from this mud\n\r", 0); close_socket(d); return; } // fOld = load_char_obj (d, argument); // ch = d->character; // // if (IS_SET (ch->act, PLR_DENY)) // { argument = capitalize(argument); if (!check_parse_name(argument)) { // sprintf (log_buf, "Denying access to %s@%s.", argument, // d->host); // log_string (log_buf); // send_to_desc ("You are denied access.\n\r", d); // close_socket (d); write_to_buffer( d, "Illegal account name, try another.\n\r" "What is your account name? ", 0 ); return; } // if (check_ban (d->host, BAN_PERMIT) // && !IS_SET (ch->act, PLR_PERMIT)) if (strlen(argument) < 3 || (account = load_account(argument)) == NULL) { // send_to_desc ("Your site has been banned from this mud.\n\r", // d); /* wizlock */ if (wizlock) { write_to_buffer(d, "Currently wizlocked.\n\r", 0); close_socket (d); return; } // if (check_reconnect (d, argument, FALSE)) // { // fOld = TRUE; account = alloc_account(); account->owner = str_dup(argument); d->account = account; d->connected = CON_CONFIRM_ACCOUNT; sprintf(buf, "Do you wish to create a new account" " called '%s' (yes|no)? ", argument); write_to_buffer(d, buf, 0); return; } // else d->account = account; if (account->denied > current_time) { // if (wizlock && !IS_IMMORTAL (ch)) sprintf(log_buf, "Denying access to %s@%s.", account->owner, d->host); log_string(log_buf); write_to_buffer(d, "You are denied access.\n\r", 0); close_socket(d); return; } /* wizlock */ if (wizlock && account->level < ADMIN_ACCOUNT) { // send_to_desc ("The game is wizlocked.\n\r", d); write_to_buffer(d, "Currenly wizlocked.\n\r", 0); close_socket (d); return; } /* ask for password */ write_to_buffer(d, "Please enter password: ", 0); write_to_buffer(d, echo_off_str, 0); d->connected = CON_GET_OLD_PASSWORD; break; case CON_NEW_PLAYER: argument[0] = UPPER (argument[0]); if (!check_parse_name (argument) || player_exists(argument) ) { send_to_desc ("Illegal name, try another.\n\rName: ", d); return; } fOld = load_char_obj( d, argument ); ch = d->character; if (fOld) { /* Old player */ // send_to_desc ("Password: ", d); // write_to_buffer (d, echo_off_str, 0); // d->connected = CON_GET_OLD_PASSWORD; if (check_playing (d, ch->name)) return; if (check_reconnect (d, ch->name, TRUE)) return; sprintf (log_buf, "Account %s, Player %s@%s has connected.", d->account->owner, ch->name, d->host); log_string (log_buf); wiznet (log_buf, NULL, NULL, WIZ_SITES, 0, get_trust (ch)); connections_today++; if (IS_IMMORTAL (ch)) { do_function (ch, &do_help, "imotd"); d->connected = CON_READ_IMOTD; } else { do_function (ch, &do_help, "motd"); d->connected = CON_READ_MOTD; } } else { /* New player */ if (newlock) { send_to_desc ("The game is newlocked.\n\r", d); close_socket (d); return; } if (check_ban (d->host, BAN_NEWBIES)) { send_to_desc ("New players are not allowed from your site.\n\r", 0); close_socket (d); return; } sprintf (buf, "Did I get that right, %s (Y/N)? ", argument); send_to_desc (buf, d); // d->connected = CON_CONFIRM_NEW_NAME; // This is where it crashes /* save this new player */ account_new_player(d->account, d->character); save_char_obj(d->character); load_char_obj(d, argument); d->connected = CON_CONFIRM_PLAYER; return; } break; case CON_GET_OLD_PASSWORD: #if defined(unix) write_to_buffer (d, "\n\r", 2); #endif // if (strcmp (crypt (argument, ch->pcdata->pwd), ch->pcdata->pwd)) if ( str_cmp( crypt( argument, d->account->password ), d->account->password ) ) { send_to_desc ("Wrong password.\n\r", d); close_socket (d); return; } write_to_buffer (d, echo_on_str, 0); show_options(d); d->connected = CON_PICK_PLAYER; break; // if (check_playing (d, ch->name)) // return; // if (check_reconnect (d, ch->name, TRUE)) // return; // sprintf (log_buf, "%s@%s has connected.", ch->name, d->host); // log_string (log_buf); // wiznet (log_buf, NULL, NULL, WIZ_SITES, 0, get_trust (ch)); // if (ch->desc->ansi) // SET_BIT (ch->act, PLR_COLOUR); // else // REMOVE_BIT (ch->act, PLR_COLOUR); // if (IS_IMMORTAL (ch)) // { // do_function (ch, &do_help, "imotd"); // d->connected = CON_READ_IMOTD; // } // else case CON_CONFIRM_ACCOUNT: switch ( *argument ) { // do_function (ch, &do_help, "motd"); // d->connected = CON_READ_MOTD; case 'y': case 'Y': sprintf(buf, "New account created.\n\r" "Give me a password for %s: %s", d->account->owner, echo_off_str ); write_to_buffer(d, buf, 0); d->connected = CON_GET_NEW_PASSWORD; break; case 'n': case 'N': write_to_buffer(d, "Ok, what IS it, then? ", 0); close_account(d->account); d->account = NULL; d->connected = CON_ACCOUNT_NAME; break; default: write_to_buffer(d, "Please type Yes or No? ", 0); break; } break; /* RT code for breaking link */ case CON_BREAK_CONNECT: switch (*argument) { case 'y': case 'Y': for (d_old = descriptor_list; d_old != NULL; d_old = d_next) { d_next = d_old->next; if (d_old == d || d_old->character == NULL) continue; if (str_cmp (ch->name, d_old->original ? d_old->original->name : d_old-> character->name)) continue; close_socket (d_old); } if (check_reconnect (d, ch->name, TRUE)) return; send_to_desc ("Reconnect attempt failed.\n\rName: ", d); if (d->character != NULL) { free_char (d->character); d->character = NULL; } // d->connected = CON_GET_NAME; d->connected = CON_ACCOUNT_NAME; break; case 'n': case 'N': send_to_desc ("Name: ", d); if (d->character != NULL) { free_char (d->character); d->character = NULL; } // d->connected = CON_GET_NAME; d->connected = CON_ACCOUNT_NAME; break; default: send_to_desc ("Please type Y or N? ", d); break; } break; // case CON_CONFIRM_NEW_NAME: case CON_CONFIRM_PLAYER: switch (*argument) { case 'y': // case 'Y': // sprintf (buf, // "New character.\n\rGive me a password for %s: %s", // ch->name, echo_off_str); // send_to_desc (buf, d); // d->connected = CON_GET_NEW_PASSWORD; ch->desc->account->p_count++; send_to_desc ("The following races are available:\n\r ", d); /* for (race = 1; race_table[race].name != NULL; race++) { if (!race_table[race].pc_race) break; write_to_buffer (d, race_table[race].name, 0); write_to_buffer (d, " ", 1); } write_to_buffer (d, "\n\r", 0); */ send_to_desc ("{GHuman Elf Dwarf Giant \n\r ", d); send_to_desc ("{GDraconian Gnome Hobbit Kender \n\r ", d); send_to_desc ("{GTroll Pixie Half-Elf Half-Giant\n\r ", d); send_to_desc ("{GHalf-Orc Duergar Minotaur Centaur\n\r ", d); send_to_desc ("{GDrow StormGiant CloudGiant FireGiant\n\r ", d); send_to_desc ("{GFrostGiant Cyclops Hydra Rockseer\n\r ", d); send_to_desc ("{GSvirfnebli Arial Felar Githyanki\n\r ", d); send_to_desc ("{GSatyr {x\n\r", d); send_to_desc ("What is your race (help for more information)? ",d); d->connected = CON_GET_NEW_RACE; if (ch->desc->ansi) SET_BIT (ch->act, PLR_COLOUR); break; case 'n': case 'N': send_to_desc ("Ok, what IS it, then? ", d); free_char (d->character); d->character = NULL; // d->connected = CON_GET_NAME; d->connected = CON_NEW_PLAYER; break; default: send_to_desc ("Please type Yes or No? ", d); break; } break; case CON_GET_NEW_PASSWORD: #if defined(unix) write_to_buffer (d, "\n\r", 2); #endif if (strlen (argument) < 5) { send_to_desc ("Password must be at least five characters long.\n\rPassword: ", d); return; } // pwdnew = crypt (argument, ch->name); pwdnew = crypt (argument, d->account->owner); for (p = pwdnew; *p != '\0'; p++) { if (*p == '~') { send_to_desc ("New password not acceptable, try again.\n\rPassword: ", d); return; } } // free_string (ch->pcdata->pwd); // ch->pcdata->pwd = str_dup (pwdnew); // send_to_desc ("Please retype password: ", d); free_string(d->account->new_password); d->account->new_password = str_dup(pwdnew); write_to_buffer( d, "Please retype password: ", 0 ); d->connected = CON_CONFIRM_NEW_PASSWORD; break; /* free_string (ch->pcdata->pwd); ch->pcdata->pwd = str_dup (pwdnew); */ case CON_CONFIRM_NEW_PASSWORD: #if defined(unix) write_to_buffer (d, "\n\r", 2); #endif // if (strcmp (crypt (argument, ch->pcdata->pwd), ch->pcdata->pwd)) if ( strcmp( crypt( argument, d->account->owner ), d->account->new_password ) ) //if (strcmp (crypt (argument, ch->pcdata->pwd), ch->pcdata->pwd)) { send_to_desc ("Passwords don't match.\n\rRetype password: ", d); d->connected = CON_GET_NEW_PASSWORD; return; } free_string(d->account->password); d->account->password = str_dup(d->account->new_password); write_to_buffer (d, echo_on_str, 0); // send_to_desc ("The following races are available:\n\r ", d); // for (race = 1; race_table[race].name != NULL; race++) show_options(d); create_new_account(d->account); d->connected = CON_PICK_PLAYER; break; case CON_DELETE_PLAYER: if (!load_char_obj(d, argument)) { // if (!race_table[race].pc_race) write_to_buffer(d, "There is no character with that name.\n\r", 0); show_options(d); d->connected = CON_PICK_PLAYER; return; } ch = d->character; if (str_cmp(ch->pcdata->account, d->account->owner)) { free_char(ch); d->character = NULL; write_to_buffer(d, "That is not your character.\n\r", 0); show_options(d); d->connected = CON_PICK_PLAYER; return; } /* delete this character */ sprintf(buf, "%s %d", ch->name, ch->played/3600); free_string(d->account->new_password); d->account->new_password = str_dup(buf); sprintf(buf, "Are you sure you wish to delete %s [Y/N]? ", ch->name); write_to_buffer(d, buf, 0); free_char(ch); d->character = NULL; d->connected = CON_CONFIRM_DEL_PLAYER; break; // write_to_buffer (d, race_table[race].name, 0); // write_to_buffer (d, " ", 1); case CON_CONFIRM_DEL_PLAYER: switch(argument[0]) { default: write_to_buffer(d, "Please answer Yes or No.\n\rAre you sure? ", 0); break; case 'y': case'Y': { char strsave[MAX_STRING_LENGTH]; char *ptr; int len = strlen(d->account->new_password), i; /* rip out the substring (string parsing) */ strcpy(buf, d->account->players); d->account->p_count--; if ((ptr = strstr(buf, d->account->new_password)) == NULL) { sprintf(buf, "Unable to delete '%s' from account '%s'", d->account->new_password, d->account->owner); bug(buf, 0); write_to_buffer(d, "\n\rDeletion FAILED!\n\r", 0); show_options(d); d->connected = CON_PICK_PLAYER; return; } if (((i = strlen(buf)) - len) == 0) { free_string(d->account->players); d->account->players = str_dup(""); } else { i -= strlen(ptr); if (i > 0 && buf[i-1] == ' ') buf[i-1] = '\0'; else buf[i++] = '\0'; strcat(buf, &d->account->players[i + len]); free_string(d->account->players); d->account->players = str_dup(buf); } /* unlink all relevant files and save account */ one_argument(d->account->new_password, buf); buf[0] = toupper(buf[0]); for (i = 1; buf[i] != '\0'; i++) buf[i] = tolower(buf[i]); sprintf(strsave, "../accounts/%s/%s", d->account->owner, buf); unlink(strsave); save_account(d->account); write_to_buffer(d, "\n\rCharacter deleted.\n\r", 0); show_options(d); d->connected = CON_PICK_PLAYER; break; } case 'n': case 'N': show_options(d); d->connected = CON_PICK_PLAYER; break; } break; case CON_PICK_PLAYER: if (toupper(argument[0]) == 'C') { write_to_buffer(d, "What shall you be known as? ", 0); d->connected = CON_NEW_PLAYER; } else if (toupper(argument[0]) == 'D') { write_to_buffer(d, "Which player do you wish to delete? ", 0); d->connected = CON_DELETE_PLAYER; } else if (toupper(argument[0]) == 'E') { write_to_buffer(d, "What is your name?? ", 0); d->connected = CON_NEW_PLAYER; } else if (toupper(argument[0]) == 'P') { write_to_buffer(d, echo_off_str, 0); write_to_buffer(d, "Please pick a new password: ", 0); d->connected = CON_GET_NEW_PASSWORD; } else if (toupper(argument[0]) == 'Q') { write_to_buffer(d, "Come back soon.\n\r", 0); close_socket(d); } else { if ( ( option = get_option_login( d->account, d->account->players, atoi( argument ) ) ) == NULL ) { write_to_buffer(d, "That is not an option!\n\r" "What will it be? ", 0); return; } /* else if ( already_logged( d->account->owner ) ) { write_to_buffer(d, "You already have a different character" " in the game.\n\r", 0); close_socket(d); return; } */ else if (!load_char_obj(d, option)) { write_to_buffer(d, "ERROR: Your pfile is missing!\n\r", 0); close_socket(d); return; } else { ch = d->character; if (d->ansi) SET_BIT (ch->act, PLR_COLOUR); else REMOVE_BIT (ch->act, PLR_COLOUR); if (IS_IMMORTAL (ch)) { do_function (ch, &do_help, "imotd"); d->connected = CON_READ_IMOTD; } else { do_function (ch, &do_help, "motd"); d->connected = CON_READ_MOTD; } } } if ( check_reconnect( d, option, TRUE ) ) return; // write_to_buffer (d, "\n\r", 0); /* Commented out during account system intall send_to_desc ("{gHuman Elf Dwarf Giant \n\r ", d); send_to_desc ("{gDraconian Gnome Hobbit Kender \n\r ", d); send_to_desc ("{gTroll Pixie Half-Elf Half-Giant\n\r ", d); send_to_desc ("{gHalf-Orc Duergar Minotaur Centaur\n\r ", d); send_to_desc ("{gDrow StormGiant CloudGiant FireGiant\n\r ", d); send_to_desc ("{gFrostGiant Cyclops Hydra Rockseer\n\r ", d); send_to_desc ("{gSvirfnebli Arial Felar Githyanki\n\r ", d); send_to_desc ("{gSatyr \n\r", d); BlackDragon BlueDragon GreenDragon\n\r ", d); send_to_desc ("{gRedDragon WhiteDragon BrassDragon GoldDragon\n\r ", d); send_to_desc ("{gSilverDragon BronzeDragon CopperDragon{x\n\r ", d); */ // send_to_desc ("What is your race (help for more information)? ", // d); // d->connected = CON_GET_NEW_RACE; break; case CON_GET_NEW_RACE: one_argument (argument, arg); if (!strcmp (arg, "help")) { argument = one_argument (argument, arg); if (argument[0] == '\0') do_function (ch, &do_help, "race help"); else do_function (ch, &do_help, argument); send_to_desc ("What is your race (help for more information)? ", d); break; } ch = d->character; race = race_lookup (argument); if (race == 0 || !race_table[race].pc_race) { send_to_desc ("That is not a valid race.\n\r", d); send_to_desc ("The following races are available:\n\r ", d); /* for (race = 1; race_table[race].name != NULL; race++) { if (!race_table[race].pc_race) break; write_to_buffer (d, race_table[race].name, 0); write_to_buffer (d, " ", 1); } */ send_to_desc ("{GHuman Elf Dwarf Giant \n\r ", d); send_to_desc ("{GDraconian Gnome Hobbit Kender \n\r ", d); send_to_desc ("{GTroll Pixie Half-Elf Half-Giant\n\r ", d); send_to_desc ("{GHalf-Orc Duergar Minotaur Centaur\n\r ", d); send_to_desc ("{GDrow StormGiant CloudGiant FireGiant\n\r ", d); send_to_desc ("{GFrostGiant Cyclops Hydra Rockseer\n\r ", d); send_to_desc ("{GSvirfnebli Arial Felar Githyanki\n\r ", d); send_to_desc ("{GSatyr {x\n\r", d); // write_to_buffer (d, "\n\r", 0); send_to_desc ("What is your race? (help for more information) ", d); break; } ch->race = race; /* initialize stats */ for (i = 0; i < MAX_STATS; i++) ch->perm_stat[i] = pc_race_table[race].stats[i]; ch->affected_by = ch->affected_by | race_table[race].aff; ch->imm_flags = ch->imm_flags | race_table[race].imm; ch->res_flags = ch->res_flags | race_table[race].res; ch->vuln_flags = ch->vuln_flags | race_table[race].vuln; ch->form = race_table[race].form; ch->parts = race_table[race].parts; ch->weight = pc_race_table[race].weight; ch->height = pc_race_table[race].height; /* add skills */ for (i = 0; i < 5; i++) { if (pc_race_table[race].skills[i] == NULL) break; group_add (ch, pc_race_table[race].skills[i], FALSE); } /* add cost */ ch->pcdata->points = pc_race_table[race].points; ch->size = pc_race_table[race].size; send_to_desc ("What is your sex (M/F)? ", d); d->connected = CON_GET_NEW_SEX; break; case CON_GET_NEW_SEX: switch (argument[0]) { case 'm': case 'M': ch->sex = SEX_MALE; ch->pcdata->true_sex = SEX_MALE; break; case 'f': case 'F': ch->sex = SEX_FEMALE; ch->pcdata->true_sex = SEX_FEMALE; break; default: send_to_desc ("That's not a sex.\n\rWhat IS your sex? ", d); return; } // strcpy (buf, "{rSelect a class{x "); /* for (iClass = 0; iClass < MAX_CLASS; iClass++) { if (iClass > 0) strcat (buf, " "); strcat (buf, class_table[iClass].name); } */ send_to_desc ("{G Select a Class{x\n\r ", d); send_to_desc ("{G Sorcerer{x\n\r ", d); send_to_desc ("{G Bishop{x\n\r ", d); send_to_desc ("{G Ninja{x\n\r ", d); send_to_desc ("{G Hoplite{x\n\r ", d); send_to_desc ("{G Templar{x\n\r ", d); send_to_desc ("{G Avenger{x\n\r ", d); send_to_desc ("{G Lich{x\n\r ", d); send_to_desc ("{G Shaman{x\n\r ", d); send_to_desc ("{G Druid{x\n\r ", d); send_to_desc ("{G Assassin{x\n\r ", d); // strcat (buf, "]: "); // write_to_buffer (d, buf, 0); d->connected = CON_GET_NEW_CLASS; break; case CON_GET_NEW_CLASS: iClass = class_lookup (argument); if (iClass == -1) { send_to_desc ("That's not a class.\n\rWhat IS your class? ", d); return; } ch->class = iClass; sprintf (log_buf, "%s@%s new player.", ch->name, d->host); log_string (log_buf); wiznet ("Newbie alert! $N sighted.", ch, NULL, WIZ_NEWBIE, 0, 0); wiznet (log_buf, NULL, NULL, WIZ_SITES, 0, get_trust (ch)); write_to_buffer (d, echo_on_str, 0); send_to_desc ("The following gods are available:\n\r ", d); send_to_desc ("{R Good Neutral Evil {x\n\r", d); send_to_desc ("{G+--------------+---------------+----------------+ {x\n\r", d); send_to_desc ("{R Branchala Chislev Chemosh {x\n\r", d); send_to_desc ("{R Habbakuk Gilean Hiddukel {x\n\r", d); send_to_desc ("{R KiriJolith Lunitari Morgion {x\n\r", d); send_to_desc ("{R Majere Reorx Nuitari{x\n\r", d); send_to_desc ("{R Mishakal Shinare Sargonnas{x\n\r", d); send_to_desc ("{R Paladine Sirrion Takhisis{x\n\r", d); send_to_desc ("{R Solinari Zivilyn Zeboim{x\n\r", d); send_to_desc ("{G+--------------+---------------+----------------+ {x\n\r", d); /* for (god = 0; god_table[god].name != NULL; god++) { if (!god_table[god].name) break; write_to_buffer (d, god_table[god].name, 0); write_to_buffer (d, " ", 1); } write_to_buffer (d, "\n\r", 0); */ send_to_desc ("who is your god (help for more information)? ", d); d->connected = CON_GET_NEW_GOD; break; case CON_GET_NEW_GOD: // one_argument (argument, arg); god = god_lookup (argument); if (!strcmp (arg, "help")) { argument = one_argument (argument, arg); if (argument[0] == '\0') do_function (ch, &do_help, "race help"); else do_function (ch, &do_help, argument); send_to_desc ("What is your race (help for more information)? ", d); break; } if (god == -1) { send_to_desc ("That is not a valid god.\n\r", d); send_to_desc ("The following gods are available:\n\r ", d); send_to_desc ("{R Good Neutral Evil {x\n\r", d); send_to_desc ("{G+--------------+---------------+----------------+ {x\n\r", d); send_to_desc ("{R Branchala Chislev Chemosh {x\n\r", d); send_to_desc ("{R Habbakuk Gilean Hiddukel {x\n\r", d); send_to_desc ("{R KiriJolith Lunitari Morgion {x\n\r", d); send_to_desc ("{R Majere Reorx Nuitari{x\n\r", d); send_to_desc ("{R Mishakal Shinare Sargonnas{x\n\r", d); send_to_desc ("{R Paladine Sirrion Takhisis{x\n\r", d); send_to_desc ("{R Solinari Zivilyn Zeboim{x\n\r", d); send_to_desc ("{G+--------------+---------------+----------------+ {x\n\r", d); /* for (god = 0; god_table[god].name != NULL; god++) { if (!god_table[god].name) break; write_to_buffer (d, god_table[god].name, 0); write_to_buffer (d, " ", 1); } write_to_buffer (d, "\n\r", 0); */ send_to_desc ("What is your god? (help for more information) ", d); break; } ch->god = god; write_to_buffer (d, "\n\r", 2); send_to_desc ("You may be good, neutral, or evil.\n\r", d); send_to_desc ("Which alignment (G/N/E)? ", d); d->connected = CON_GET_ALIGNMENT; break; case CON_GET_ALIGNMENT: switch (argument[0]) { case 'g': case 'G': ch->alignment = 750; break; case 'n': case 'N': ch->alignment = 0; break; case 'e': case 'E': ch->alignment = -750; break; default: send_to_desc ("That's not a valid alignment.\n\r", d); send_to_desc ("Which alignment (G/N/E)? ", d); return; } write_to_buffer (d, "\n\r", 0); group_add (ch, "rom basics", FALSE); group_add (ch, class_table[ch->class].base_group, FALSE); ch->pcdata->learned[gsn_recall] = 50; send_to_desc ("Do you wish to customize this character?\n\r", d); send_to_desc ("Customization takes time, but allows a wider range of skills and abilities.\n\r", d); send_to_desc ("Customize (Y/N)? ", d); d->connected = CON_DEFAULT_CHOICE; break; case CON_DEFAULT_CHOICE: write_to_buffer (d, "\n\r", 2); switch (argument[0]) { case 'y': case 'Y': ch->gen_data = new_gen_data (); ch->gen_data->points_chosen = ch->pcdata->points; do_function (ch, &do_help, "group header"); list_group_costs (ch); write_to_buffer (d, "You already have the following skills:\n\r", 0); do_function (ch, &do_skills, ""); do_function (ch, &do_help, "menu choice"); d->connected = CON_GEN_GROUPS; break; case 'n': case 'N': group_add (ch, class_table[ch->class].default_group, TRUE); write_to_buffer (d, "\n\r", 2); write_to_buffer (d, "Please pick a weapon from the following choices:\n\r", 0); buf[0] = '\0'; for (i = 0; weapon_table[i].name != NULL; i++) if (ch->pcdata->learned[*weapon_table[i].gsn] > 0) { strcat (buf, weapon_table[i].name); strcat (buf, " "); } strcat (buf, "\n\rYour choice? "); write_to_buffer (d, buf, 0); d->connected = CON_PICK_WEAPON; break; default: write_to_buffer (d, "Please answer (Y/N)? ", 0); return; } break; case CON_PICK_WEAPON: write_to_buffer (d, "\n\r", 2); weapon = weapon_lookup (argument); if (weapon == -1 || ch->pcdata->learned[*weapon_table[weapon].gsn] <= 0) { write_to_buffer (d, "That's not a valid selection. Choices are:\n\r", 0); buf[0] = '\0'; for (i = 0; weapon_table[i].name != NULL; i++) if (ch->pcdata->learned[*weapon_table[i].gsn] > 0) { strcat (buf, weapon_table[i].name); strcat (buf, " "); } strcat (buf, "\n\rYour choice? "); write_to_buffer (d, buf, 0); return; } ch->pcdata->learned[*weapon_table[weapon].gsn] = 40; write_to_buffer (d, "\n\r", 2); do_function (ch, &do_help, "motd"); d->connected = CON_READ_MOTD; break; case CON_GEN_GROUPS: send_to_char ("\n\r", ch); if (!str_cmp (argument, "done")) { if (ch->pcdata->points == pc_race_table[ch->race].points) { send_to_char ("You didn't pick anything.\n\r", ch); break; } if (ch->pcdata->points < 40 + pc_race_table[ch->race].points) { sprintf (buf, "You must take at least %d points of skills and groups", 40 + pc_race_table[ch->race].points); send_to_char (buf, ch); break; } sprintf (buf, "Creation points: %d\n\r", ch->pcdata->points); send_to_char (buf, ch); sprintf (buf, "Experience per level: %d\n\r", exp_per_level (ch, ch->gen_data->points_chosen)); if (ch->pcdata->points < 40) ch->train = (40 - ch->pcdata->points + 1) / 2; free_gen_data (ch->gen_data); ch->gen_data = NULL; send_to_char (buf, ch); write_to_buffer (d, "\n\r", 2); write_to_buffer (d, "Please pick a weapon from the following choices:\n\r", 0); buf[0] = '\0'; for (i = 0; weapon_table[i].name != NULL; i++) if (ch->pcdata->learned[*weapon_table[i].gsn] > 0) { strcat (buf, weapon_table[i].name); strcat (buf, " "); } strcat (buf, "\n\rYour choice? "); write_to_buffer (d, buf, 0); d->connected = CON_PICK_WEAPON; break; } if (!parse_gen_groups (ch, argument)) send_to_char ("Choices are: list,learned,premise,add,drop,info,help, and done.\n\r", ch); do_function (ch, &do_help, "menu choice"); break; case CON_READ_IMOTD: write_to_buffer (d, "\n\r", 2); do_function (ch, &do_help, "motd"); d->connected = CON_READ_MOTD; break; /* states for new note system, (c)1995-96 erwin@pip.dknet.dk */ /* ch MUST be PC here; have nwrite check for PC status! */ case CON_NOTE_TO: handle_con_note_to (d, argument); break; case CON_NOTE_SUBJECT: handle_con_note_subject (d, argument); break; case CON_NOTE_EXPIRE: handle_con_note_expire (d, argument); break; case CON_NOTE_TEXT: handle_con_note_text (d, argument); break; case CON_NOTE_FINISH: handle_con_note_finish (d, argument); break; case CON_READ_MOTD: if (ch->pcdata == NULL || ch->pcdata->pwd[0] == '\0') { write_to_buffer (d, "Warning! Null password!\n\r", 0); write_to_buffer (d, "Please report old password with bug.\n\r", 0); write_to_buffer (d, "Type 'password null <new password>' to fix.\n\r", 0); } write_to_buffer (d, "\n\rWelcome to ROM 2.4. Please don't feed the mobiles!\n\r", 0); ch->next = char_list; char_list = ch; d->connected = CON_PLAYING; reset_char (ch); if (ch->level == 0) { if(mud_ansicolor) SET_BIT (ch->act, PLR_COLOUR); if(mud_telnetga) SET_BIT (ch->comm, COMM_TELNET_GA); ch->perm_stat[class_table[ch->class].attr_prime] += 3; ch->level = 1; // ch->exp = exp_per_level (ch, ch->pcdata->points); ch->exp = 0; ch->hit = ch->max_hit; ch->mana = ch->max_mana; ch->move = ch->max_move; ch->train = 3; ch->practice = 5; // sprintf (buf, "the %s", title_table[ch->class][ch->level] // [ch->sex == SEX_FEMALE ? 1 : 0]); set_title (ch, "The Newbie"); do_prompt ( ch, "all" ); creations_today++; do_function (ch, &do_outfit, ""); obj_to_char (create_object (get_obj_index (OBJ_VNUM_MAP), 0), ch); char_to_room (ch, get_room_index (ROOM_VNUM_SCHOOL)); send_to_char ("\n\r", ch); do_function (ch, &do_help, "newbie info"); send_to_char ("\n\r", ch); } else if (ch->in_room != NULL) { char_to_room (ch, ch->in_room); } else if (IS_IMMORTAL (ch)) { char_to_room (ch, get_room_index (ROOM_VNUM_CHAT)); } else { char_to_room (ch, get_room_index (ROOM_VNUM_TEMPLE)); } sprintf(buf, "{r%s {whas entered {YEye of the Cyclops.{x", ch->name); enter_info(buf); act ("$n has entered the game.", ch, NULL, NULL, TO_ROOM); do_function (ch, &do_look, "auto"); ++logins_today; wiznet ("$N has left real life behind.", ch, NULL, WIZ_LOGINS, WIZ_SITES, get_trust (ch)); if (ch->pet != NULL) { char_to_room (ch->pet, ch->in_room); act ("$n has entered the game.", ch->pet, NULL, NULL, TO_ROOM); } send_to_char("\n", ch); do_function (ch, &do_board, ""); break; } return; }