/***************************************************************************
* 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;
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *ch;
char *pwdnew, *option;
char *p;
bool fOld;
int iClass, race, i, weapon, god;
extern int mud_telnetga, mud_ansicolor;
char reRoll[MSL];
int nStr[3], nInt[3], nWis[3], nCon[3], nDex[3];
int nVit[3], nDis[3], nAgi[3], nCha[3], nLuc[3];
int j;
char pickRace[MSL];
char pickClass[MSL];
char rollStats[MSL];
char sAlign[MSL], sHome[MSL], sCustom[MSL], sWeapon[MSL];
/* 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;
{
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;
{
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:
if (argument[0] == '\0')
{
close_socket (d);
return;
}
argument[0] = UPPER (argument[0]);
if (!check_parse_name (argument))
{
send_to_desc ("Illegal name, try another.\n\rName: ", d);
return;
}
fOld = load_char_obj (d, argument);
ch = d->character;
if (IS_SET (ch->act, PLR_DENY))
{
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);
return;
}
if (check_ban (d->host, BAN_PERMIT)
&& !IS_SET (ch->act, PLR_PERMIT))
{
send_to_desc ("Your site has been banned from this mud.\n\r",
d);
close_socket (d);
return;
}
if (check_reconnect (d, argument, FALSE))
{
fOld = TRUE;
}
else
{
if (wizlock && !IS_IMMORTAL (ch))
{
send_to_desc ("The game is wizlocked.\n\r", d);
close_socket (d);
return;
}
}
if (fOld)
{
/* Old player */
send_to_desc ("Password: ", d);
write_to_buffer (d, echo_off_str, 0);
d->connected = CON_GET_OLD_PASSWORD;
return;
}
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, "{BDid I get that right, {W%s {B[{WYes{c/{WNo{B]{x? ", argument);
send_to_desc (buf, d);
d->connected = CON_CONFIRM_NEW_NAME;
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))
{
send_to_desc ("{RWrong password.{x\n\r", d);
close_socket (d);
return;
}
write_to_buffer (d, echo_on_str, 0);
if (check_playing (d, ch->name))
return;
if (check_reconnect (d, ch->name, TRUE))
return;
sprintf (log_buf, "{B%s{W@{B%s has connected.{x", ch->name, d->host);
log_string (log_buf);
ch->lasthost = str_dup(d->host);
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
{
do_function (ch, &do_help, "motd");
d->connected = CON_READ_MOTD;
}
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;
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;
break;
default:
send_to_desc ("Please type Y or N? ", d);
break;
}
break;
case CON_CONFIRM_NEW_NAME:
switch (*argument)
{
case 'y':
case 'Y':
sprintf (buf,
"{BNew character.{x\n\r{BGive me a password for {W%s{B:{x %s",
ch->name, echo_off_str);
send_to_desc (buf, d);
d->connected = CON_GET_NEW_PASSWORD;
if (ch->desc->ansi)
SET_BIT (ch->act, PLR_COLOUR);
break;
case 'n':
case 'N':
send_to_desc ("{BOk, what {WIS {Bit, then?{x ", d);
free_char (d->character);
d->character = NULL;
d->connected = CON_GET_NAME;
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
("{RPassword must be at least five characters long.{X\n\r{BPassword:{x ",
d);
return;
}
pwdnew = crypt (argument, ch->name);
for (p = pwdnew; *p != '\0'; p++)
{
if (*p == '~')
{
send_to_desc
("{RNew password not acceptable, try again.\n\r{BPassword:{x ",
d);
return;
}
}
free_string (ch->pcdata->pwd);
ch->pcdata->pwd = str_dup (pwdnew);
send_to_desc ("{BPlease retype password:{x ", d);
d->connected = CON_CONFIRM_NEW_PASSWORD;
break;
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))
{
send_to_desc ("{RPasswords don't match.\n\r{BRetype password:{x ",
d);
d->connected = CON_GET_NEW_PASSWORD;
return;
}
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
sprintf(pickRace, "Pick a Race");
sprintf(pickClass, "Pick a Class");
sprintf(sAlign, "None");
sprintf(sHome, "None");
sprintf(sCustom, "None");
sprintf(sWeapon, "None");
sprintf(rollStats, "Stat Roll [{DN/A{x]");
d->connected = CON_SHOW_MENU;
break;
case CON_SHOW_MENU:
if(str_cmp(pickRace, "Pick a Race") && str_cmp(pickClass, "Pick a Class") && str_cmp(reRoll, "No"))
sprintf(rollStats, "Stat Roll [ {RNEED{x]");
send_to_desc("+---------------------------------------------+\n", d);
sprintf(buf, "| Creation Sheet for %-12s |\n", ch->name);
send_to_desc(buf, d);
send_to_desc("+---------------------------------------------+\n", d);
sprintf(buf, "| R) %-17s | C) %-17s |\n",
pickRace, pickClass);
send_to_desc(buf, d);
sprintf(buf, "| G) %-17s | S) %-17s |\n",
ch->sex == 0 ? "Pick a Gender" : ch->sex == 1 ? "Male" : "Female",
string_pad(rollStats,16,FALSE));
send_to_desc(buf, d);
sprintf(buf, "| A) %-17s | H) %-17s |\n",
!str_cmp(sAlign, "None") ? "Choose Alignment" : string_pad(sAlign,16,FALSE),
!str_cmp(sHome, "None") ? "Pick a Hometown" : string_pad(sHome,16,FALSE) );
send_to_desc(buf, d);
sprintf(buf, "| U) %-17s | W) %-17s |\n",
!str_cmp(sCustom, "None") ? "Customized? [ {RNO{x]" : "Customized? [{GYES{x]",
!str_cmp(sWeapon, "None") ? "Pick a Weapon" : string_pad(sWeapon,16,FALSE));
send_to_desc(buf, d);
send_to_desc("+---------------------------------------------+\n", d);
send_to_desc("+ D) Complete the Creation Process |\n", d);
send_to_desc("+---------------------------------------------+\n", d);
send_to_desc("Your ALPHABETICAL choice?: ", d);
d->connected = CON_GET_MENU;
break;
case CON_GET_MENU:
switch(argument[0])
{
case 'a': case 'A':
send_to_desc("\n{BYou may be {Wgood{B, {Wneutral{B, or {Wevil{B.{x\n\r",d);
send_to_desc("{BWhich alignment \n\r[{WGood{B]\n\r{B[{WNeutral{B]\n\r{B[{WEvil{B]{x\n\rYour Choice: ",d);
d->connected = CON_GET_ALIGNMENT;
break;
case 'r': case 'R':
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++)
{
if (!race_table[race].pc_race)
break;
write_to_buffer (d, race_table[race].name, 0);
write_to_buffer (d, "\n\r", 1);
}
*/
send_to_desc ("{B[ {WHuman Elf Dwarf Giant ]\n\r ", d);
send_to_desc ("{B[ {WDraconian Gnome Hobbit Kender ] \n\r ", d);
send_to_desc ("{B[ {WTroll Pixie Half-Elf Half-Giant ]\n\r ", d);
send_to_desc ("{B[ {WHalf-Orc Duergar Minotaur Centaur ]\n\r ", d);
send_to_desc ("{B[ {WDrow StormGiant CloudGiant FireGiant ]\n\r ", d);
send_to_desc ("{B[ {WFrostGiant Cyclops Hydra Rockseer ]\n\r ", d);
send_to_desc ("{B[ {WSvirfnebli Arial Felar Githyanki ]\n\r ", d);
send_to_desc ("{B[ {WSatyr ]\n\r ", d);
write_to_buffer (d, "\n\r", 0);
send_to_desc ("{BWhat is your race [{Whelp for more information{B]{x? ",
d);
d->connected = CON_GET_NEW_RACE;
break;
case 'c': case 'C':
send_to_desc("Select a class: {B[{W",d);
for (iClass = 0; iClass < MAX_CLASS; iClass++)
{
if (iClass > 0)
send_to_desc (" ",d);
send_to_desc (class_table[iClass].name,d);
}
send_to_desc ("{B]{x:{x ",d);
d->connected = CON_GET_NEW_CLASS;
break;
case 's': case 'S':
if(!str_cmp(pickRace, "Pick a Race") || !str_cmp(pickClass, "Pick a Class"))
{
send_to_desc("You must first choose a RACE and CLASS.\n\n", d);
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
}
ch->perm_stat[STAT_STR] = number_range(8,16);
ch->perm_stat[STAT_INT] = number_range(8,16);
ch->perm_stat[STAT_WIS] = number_range(8,16);
ch->perm_stat[STAT_DEX] = number_range(8,16);
ch->perm_stat[STAT_CON] = number_range(8,16);
ch->perm_stat[STAT_VIT] = number_range(8,16);
ch->perm_stat[STAT_DIS] = number_range(8,16);
ch->perm_stat[STAT_AGI] = number_range(8,16);
ch->perm_stat[STAT_CHA] = number_range(8,16);
ch->perm_stat[STAT_LUC] = number_range(8,16);
sprintf(rollStats, "Stat Roll [ {GDONE{x]");
send_to_desc("{BYou will now begin to roll your initial stats from the table below.{x\n\n", d);
for(j = 0; j < 4; j++)
{
nStr[j] = number_range(8, get_curr_stat(ch, STAT_STR));
nInt[j] = number_range(8, get_curr_stat(ch, STAT_INT));
nWis[j] = number_range(8, get_curr_stat(ch, STAT_WIS));
nDex[j] = number_range(8, get_curr_stat(ch, STAT_DEX));
nCon[j] = number_range(8, get_curr_stat(ch, STAT_CON));
nVit[j] = number_range(8, get_curr_stat(ch, STAT_VIT));
nDis[j] = number_range(8, get_curr_stat(ch, STAT_DIS));
nAgi[j] = number_range(8, get_curr_stat(ch, STAT_AGI));
nCha[j] = number_range(8, get_curr_stat(ch, STAT_CHA));
nLuc[j] = number_range(8, get_curr_stat(ch, STAT_LUC));
}
sprintf(buf, "{BYour maximum stats are: {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c]{x\n\r",
get_curr_stat (ch, STAT_STR),
get_curr_stat (ch, STAT_INT),
get_curr_stat (ch, STAT_WIS),
get_curr_stat (ch, STAT_DEX),
get_curr_stat (ch, STAT_CON));
send_to_desc(buf, d);
sprintf(buf, "{BYour maximum stats are: {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c]{x\n\r",
get_curr_stat (ch, STAT_VIT),
get_curr_stat (ch, STAT_DIS),
get_curr_stat (ch, STAT_AGI),
get_curr_stat (ch, STAT_CHA),
get_curr_stat (ch, STAT_LUC));
send_to_desc(buf, d);
sprintf(buf, "\t%-16s %-3s %-3s %-3s %-3s\n\r", "", "0", "1", "2", "3");
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Strength", nStr[0], nStr[1], nStr[2], nStr[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Intelligence", nInt[0], nInt[1], nInt[2], nInt[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Wisdom", nWis[0], nWis[1], nWis[2], nWis[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Dexterity", nDex[0], nDex[1], nDex[2], nDex[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Constitution", nCon[0], nCon[1], nCon[2], nCon[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Vitality", nVit[0], nVit[1], nVit[2], nVit[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Discipline", nDis[0], nDis[1], nDis[2], nDis[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Agility", nAgi[0], nAgi[1], nAgi[2], nAgi[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Charisma", nCha[0], nCha[1], nCha[2], nCha[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Luck", nLuc[0], nLuc[1], nLuc[2], nLuc[3] );
send_to_desc(buf, d);
send_to_desc("\n\r\n\r\t{BPress enter to roll again,\n\r\telse enter number of column {W[{c0{W/{c1{W/{c2{W/{c3{W]{x\n\r",d);
send_to_desc("\n{BYour choice?{x: ",d);
d->connected = CON_SELECT_NEW_STATS;
break;
case 'g': case 'G':
send_to_desc("Please choose a Gender [{BMale{x/{MFemale{x]: ", d);
d->connected = CON_GET_NEW_SEX;
break;
break;
case 'h': case 'H':
send_to_desc("{BSelect a Hometown{c:{x\n\r", d);
for (i=0;hometown_table[i].name != NULL; ++i)
{
sprintf(buf,"{B[{W%-15s{B]{x\n\r", hometown_table[i].name );
send_to_desc(buf, d);
}
send_to_desc("\n\r{BWhat's your hometown? {x", d);
d->connected = CON_GET_HOMETOWN;
break;
case 'u': case 'U':
if(!str_cmp(pickClass, "Pick a Class") || !str_cmp(pickRace, "Pick a Race"))
{
send_to_desc("Make sure you've chosen a RACE and CLASS.\n", d);
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
}
send_to_desc ("{BYou will now customize this character.\n\r", d);
send_to_desc
("\t{BCustomization takes time, but allows a wider range of skills and abilities.\n\r",
d);
d->connected = CON_DEFAULT_CHOICE;
break;
case 'w': case 'W':
if(!str_cmp(pickClass, "Pick a Class"))
{
send_to_desc("Make sure you've chosen a CLASS.\n", d);
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
}
strcat (buf, "\n\rYour choice? ");
write_to_buffer (d, buf, 0);
write_to_buffer (d, "\n\r", 2);
write_to_buffer (d,
"Please pick a weapon from the following choices:\n\r",
0);
send_to_desc("Make sure you've chosen a CLASS.\n", d);
buf[0] = '\0';
for (i = 0; weapon_table[i].name != NULL; i++)
if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
{
send_to_desc ("{B[{W",d);
sprintf (buf,weapon_table[i].name);
send_to_desc(buf, d);
send_to_desc ("{B]{x",d);
}
d->connected = CON_PICK_WEAPON;
break;
case 'd': case 'D':
if(!str_cmp(pickClass, "Pick a Class") ||
!str_cmp(!pickRace, "Pick a Race") ||
!str_cmp(!rollStats, "Stat Roll [{DN/A]{x") ||
!str_cmp(!sAlign, "None") ||
!str_cmp(!sHome, "None") ||
ch->sex == 0 ||
!str_cmp(!sWeapon, "None") ||
!str_cmp(!sWeapon, "None"))
{
send_to_desc("You aren't done creation yet!\n", d);
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
}
write_to_buffer (d, "\n\r", 2);
do_function (ch, &do_help, "motd");
d->connected = CON_READ_MOTD;
break;
default:
send_to_desc("That is not a valid choice!\n{x\n\n", d);
return;
}
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;
}
race = race_lookup (argument);
if (race == 0 || !race_table[race].pc_race)
{
send_to_desc ("{RThat is not a valid race.\n\r", d);
send_to_desc ("{BThe following races are available:{x\n\r ", d);
/*
for (race = 1; race_table[race].name != NULL; race++)
{
if (!race_table[race].pc_race)
break;
send_to_desc("{c", d);
write_to_buffer (d, race_table[race].name, 0);
write_to_buffer (d, "\n\r{x", 1);
}
*/
send_to_desc ("{B[ {WHuman Elf Dwarf Giant ]\n\r ", d);
send_to_desc ("{B[ {WDraconian Gnome Hobbit Kender ] \n\r ", d);
send_to_desc ("{B[ {WTroll Pixie Half-Elf Half-Giant ]\n\r ", d);
send_to_desc ("{B[ {WHalf-Orc Duergar Minotaur Centaur ]\n\r ", d);
send_to_desc ("{B[ {WDrow StormGiant CloudGiant FireGiant ]\n\r ", d);
send_to_desc ("{B[ {WFrostGiant Cyclops Hydra Rockseer ]\n\r ", d);
send_to_desc ("{B[ {WSvirfnebli Arial Felar Githyanki ]\n\r ", d);
send_to_desc ("{B[ {WSatyr ]\n\r ", d);
write_to_buffer (d, "\n\r", 0);
send_to_desc
("{BWhat is your race? [{Whelp for more information{B]{x ", d);
break;
}
ch->race = race;
sprintf(pickRace, "%s", capitalize(race_table[race].name));
/* initialize stats */
for (i = 0; i < MAX_STATS; i++)
ch->perm_stat[i] = pc_race_table[race].stats[i];
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;
/* 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("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
case CON_GET_NEW_CLASS:
iClass = class_lookup (argument);
if (iClass == -1)
{
send_to_desc ("{RThat's not a class.\n\r{BWhat IS your class?{x ",
d);
return;
}
ch->class = iClass;
sprintf(pickClass, "%s", capitalize(class_table[ch->class].name));
ch->pcdata->cname = ch->name;
sprintf (log_buf, "{B%s{W@{B%s new player.{x", ch->name, d->host);
log_string (log_buf);
ch->lasthost = str_dup(d->host);
wiznet ("{YNewbie alert! {C$N {Bsighted.{x", ch, NULL, WIZ_NEWBIE, 0, 0);
wiznet (log_buf, NULL, NULL, WIZ_SITES, 0, get_trust (ch));
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
// Initalize the current stats
case CON_SELECT_NEW_STATS:
if(!str_cmp(reRoll, "Yes"))
{
ch->perm_stat[STAT_STR] = number_range(8,16);
ch->perm_stat[STAT_INT] = number_range(8,16);
ch->perm_stat[STAT_WIS] = number_range(8,16);
ch->perm_stat[STAT_DEX] = number_range(8,16);
ch->perm_stat[STAT_CON] = number_range(8,16);
ch->perm_stat[STAT_VIT] = number_range(8,16);
ch->perm_stat[STAT_DIS] = number_range(8,16);
ch->perm_stat[STAT_AGI] = number_range(8,16);
ch->perm_stat[STAT_CHA] = number_range(8,16);
ch->perm_stat[STAT_LUC] = number_range(8,16);
for(j = 0; j < 4; j++)
{
nStr[j] = number_range(8, get_curr_stat(ch, STAT_STR));
nInt[j] = number_range(8, get_curr_stat(ch, STAT_INT));
nWis[j] = number_range(8, get_curr_stat(ch, STAT_WIS));
nDex[j] = number_range(8, get_curr_stat(ch, STAT_DEX));
nCon[j] = number_range(8, get_curr_stat(ch, STAT_CON));
nVit[j] = number_range(8, get_curr_stat(ch, STAT_VIT));
nDis[j] = number_range(8, get_curr_stat(ch, STAT_DIS));
nAgi[j] = number_range(8, get_curr_stat(ch, STAT_AGI));
nCha[j] = number_range(8, get_curr_stat(ch, STAT_CHA));
nLuc[j] = number_range(8, get_curr_stat(ch, STAT_LUC));
}
sprintf(buf, "{BYour maximum stats are: {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c]{x\n\r",
get_curr_stat (ch, STAT_STR),
get_curr_stat (ch, STAT_INT),
get_curr_stat (ch, STAT_WIS),
get_curr_stat (ch, STAT_DEX),
get_curr_stat (ch, STAT_CON));
send_to_desc(buf, d);
sprintf(buf, "{BYour maximum stats are: {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c] {c[{W%d{c]{x\n\r",
get_curr_stat (ch, STAT_VIT),
get_curr_stat (ch, STAT_DIS),
get_curr_stat (ch, STAT_AGI),
get_curr_stat (ch, STAT_CHA),
get_curr_stat (ch, STAT_LUC));
send_to_desc(buf, d);
sprintf(buf, "\t%-16s %-3s %-3s %-3s %-3s\n\r", "", "0", "1", "2", "3");
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Strength", nStr[0], nStr[1], nStr[2], nStr[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Intelligence", nInt[0], nInt[1], nInt[2], nInt[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Wisdom", nWis[0], nWis[1], nWis[2], nWis[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Dexterity", nDex[0], nDex[1], nDex[2], nDex[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Constitution", nCon[0], nCon[1], nCon[2], nCon[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Vitality", nVit[0], nVit[1], nVit[2], nVit[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Discipline", nDis[0], nDis[1], nDis[2], nDis[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Agility", nAgi[0], nAgi[1], nAgi[2], nAgi[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Charisma", nCha[0], nCha[1], nCha[2], nCha[3] );
send_to_desc(buf, d);
sprintf(buf, "\t{B%-15s{W: {c%-3d %-3d %-3d %-3d{x\n\r", "Luck", nLuc[0], nLuc[1], nLuc[2], nLuc[3] );
send_to_desc(buf, d);
send_to_desc("\n\r\n\r\t{BPress enter to roll again,\n\r\telse enter number of column {W[{c0{W/{c1{W/{c2{W/{c3{W]{x\n\r",d);
sprintf(rollStats, "No");
d->connected = CON_SELECT_NEW_STATS;
break;
}
switch(argument[0])
{
case '0':
ch->perm_stat[STAT_STR] = nStr[0];
ch->perm_stat[STAT_INT] = nInt[0];
ch->perm_stat[STAT_WIS] = nWis[0];
ch->perm_stat[STAT_DEX] = nDex[0];
ch->perm_stat[STAT_CON] = nCon[0];
ch->perm_stat[STAT_VIT] = nVit[0];
ch->perm_stat[STAT_DIS] = nDis[0];
ch->perm_stat[STAT_AGI] = nAgi[0];
ch->perm_stat[STAT_CHA] = nCha[0];
ch->perm_stat[STAT_LUC] = nLuc[0];
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
sprintf(reRoll, "No");
d->connected = CON_SHOW_MENU;
break;
case '1':
ch->perm_stat[STAT_STR] = nStr[1];
ch->perm_stat[STAT_INT] = nInt[1];
ch->perm_stat[STAT_WIS] = nWis[1];
ch->perm_stat[STAT_DEX] = nDex[1];
ch->perm_stat[STAT_CON] = nCon[1];
ch->perm_stat[STAT_VIT] = nVit[1];
ch->perm_stat[STAT_DIS] = nDis[1];
ch->perm_stat[STAT_AGI] = nAgi[1];
ch->perm_stat[STAT_CHA] = nCha[1];
ch->perm_stat[STAT_LUC] = nLuc[1];
sprintf(rollStats, "Stat Roll [ {GDONE{x]");
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
sprintf(reRoll, "No");
d->connected = CON_SHOW_MENU;
break;
case '2':
ch->perm_stat[STAT_STR] = nStr[2];
ch->perm_stat[STAT_INT] = nInt[2];
ch->perm_stat[STAT_WIS] = nWis[2];
ch->perm_stat[STAT_DEX] = nDex[2];
ch->perm_stat[STAT_CON] = nCon[2];
ch->perm_stat[STAT_VIT] = nVit[2];
ch->perm_stat[STAT_DIS] = nDis[2];
ch->perm_stat[STAT_AGI] = nAgi[2];
ch->perm_stat[STAT_CHA] = nCha[2];
ch->perm_stat[STAT_LUC] = nLuc[2];
sprintf(rollStats, "Stat Roll [ {GDONE{x]");
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
sprintf(reRoll, "No");
d->connected = CON_SHOW_MENU;
break;
case '3':
ch->perm_stat[STAT_STR] = nStr[3];
ch->perm_stat[STAT_INT] = nInt[3];
ch->perm_stat[STAT_WIS] = nWis[3];
ch->perm_stat[STAT_DEX] = nDex[3];
ch->perm_stat[STAT_CON] = nCon[3];
ch->perm_stat[STAT_VIT] = nVit[3];
ch->perm_stat[STAT_DIS] = nDis[3];
ch->perm_stat[STAT_AGI] = nAgi[3];
ch->perm_stat[STAT_CHA] = nCha[3];
ch->perm_stat[STAT_LUC] = nLuc[3];
sprintf(rollStats, "Stat Roll [ {GDONE{x]");
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
sprintf(reRoll, "No");
d->connected = CON_SHOW_MENU;
break;
default:
sprintf(reRoll, "Yes");
send_to_desc("\n{B[ {WHit Enter to Reroll Stats {B]{x \n\n", d);
d->connected = CON_SELECT_NEW_STATS;
break;
}
break;
case CON_GET_NEW_SEX:
switch (argument[0])
{
case 'm':
case 'M':
ch->sex = SEX_MALE;
ch->pcdata->true_sex = SEX_MALE;
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
case 'f':
case 'F':
ch->sex = SEX_FEMALE;
ch->pcdata->true_sex = SEX_FEMALE;
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
default:
send_to_desc ("{RThat's not a sex.{x\n\r{BWhat IS your sex?{x ",
d);
return;
}
break;
case CON_GET_HOMETOWN:
if (get_hometown(argument) == -1)
{
send_to_desc("\n\r{RThat's not a valid selection.{x\n\r",d);
send_to_desc("{BValid selections are:{x\n\r",d);
for (i=0;hometown_table[i].name != NULL; ++i)
{
sprintf(buf,"{B[{W%-15s{B]{x\n\r", hometown_table[i].name );
send_to_desc( buf, d);
}
send_to_desc("\n\r{BWhat's your hometown?{x ", d);
return;
}
ch->hometown = get_hometown(argument);
sprintf(sHome, "%s", capitalize(hometown_table[ch->hometown].name));
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
case CON_GET_ALIGNMENT:
switch (argument[0])
{
case 'g':
case 'G':
ch->alignment = 750;
sprintf(sAlign, "{CGOOD{x");
break;
case 'n':
case 'N':
ch->alignment = 0;
sprintf(sAlign, "{cNEUTRAL{x");
break;
case 'e':
case 'E':
sprintf(sAlign, "{REVIL{x");
ch->alignment = -750;
break;
default:
send_to_desc ("{RThat's not a valid alignment.\n\r", d);
send_to_desc("{BWhich alignment \n\r[{WGood{B]\n\r{B[{WNeutral{B]\n\r{B[{WEvil{B]{x\n\rYour Choice: ",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("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
break;
case CON_DEFAULT_CHOICE:
write_to_buffer (d, "\n\r", 2);
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 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)
{
send_to_desc (
"{RThat's not a valid selection. Choices are:{x\n\r",
d);
buf[0] = '\0';
for (i = 0; weapon_table[i].name != NULL; i++)
if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
{
send_to_desc ("{B[{W",d);
sprintf (buf,weapon_table[i].name);
send_to_desc(buf, d);
send_to_desc ("{B]{x",d);
}
strcat (buf, "\n\rYour choice? ");
write_to_buffer (d, buf, 0);
return;
}
ch->pcdata->learned[*weapon_table[weapon].gsn] = 40;
sprintf(sWeapon, "%-17s", capitalize(weapon_table[weapon].name));
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
d->connected = CON_SHOW_MENU;
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);
send_to_desc("\n{B[ {WHit Enter to Continue {B]{x\n\n", d);
sprintf(sCustom, "Done");
d->connected = CON_SHOW_MENU;
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->hit = ch->max_hit;
ch->mana = ch->max_mana;
ch->move = ch->max_move;
ch->train = 3;
ch->practice = 5;
ch->pcdata->spouse = "None";
sprintf (buf, "the %s", title_table[ch->class][ch->level]
[ch->sex == SEX_FEMALE ? 1 : 0]);
set_title (ch, buf);
do_function(ch, &do_autoexit, "");
// do_function (ch, &do_outfit, "");
// obj_to_char (create_object (get_obj_index (OBJ_VNUM_MAP), 0),
// ch);
/* Removed for Hometowns
char_to_room (ch, get_room_index (ROOM_VNUM_SCHOOL)); */
char_to_room( ch, get_room_index( hometown_table[ch->hometown].school ) );
send_to_char ("\n\r", ch);
do_function (ch, &do_help, "newbie info");
send_to_char ("\n\r", ch);
/*
* Small additions to make character creation way easier, by Rhaelar 08'2004
*/
creations_today++;
do_get ( ch, "all bag" );
do_wear ( ch, "sword" );
do_second ( ch, "sword" );
do_wear ( ch, "all" );
do_eat ( ch, "spellup" );
do_drink ( ch, "jug" );
do_eat ( ch, "mre" );
do_put ( ch, "all bag" );
do_stance(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));
}
act ("$n has entered the game.", ch, NULL, NULL, TO_ROOM);
do_function (ch, &do_look, "auto");
sprintf(buf, "%s {Dhas entered Eotc Advanced!{x", ch->name);
sprintf(buf, "{r%s {whas entered {DEye of the Cyclops Advanced.{x", ch->name);
enter_info(buf);
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;
}
}