Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

nanny.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
00003  *  Michael Seifert, Hans Henrik Strfeldt, Tom Madsen, and Katja Nyboe.    *
00004  *                                                                         *
00005  *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
00006  *  Chastain, Michael Quan, and Mitchell Tse.                              *
00007  *                                                                         *
00008  *  In order to use any part of this Merc Diku Mud, you must comply with   *
00009  *  both the original Diku license in 'license.doc' as well the Merc       *
00010  *  license in 'license.txt'.  In particular, you may not remove either of *
00011  *  these copyright notices.                                               *
00012  *                                                                         *
00013  *  Thanks to abaddon for proof-reading our comm.c and pointing out bugs.  *
00014  *  Any remaining bugs are, of course, our work, not his.  :)              *
00015  *                                                                         *
00016  *  Much time and thought has gone into this software and you are          *
00017  *  benefitting.  We hope that you share your changes too.  What goes      *
00018  *  around, comes around.                                                  *
00019  ***************************************************************************/
00020 
00021 /***************************************************************************
00022 *    ROM 2.4 is copyright 1993-1998 Russ Taylor                             *
00023 *    ROM has been brought to you by the ROM consortium                      *
00024 *        Russ Taylor (rtaylor@hypercube.org)                                *
00025 *        Gabrielle Taylor (gtaylor@hypercube.org)                           *
00026 *        Brian Moore (zump@rom.org)                                         *
00027 *    By using this code, you have agreed to follow the terms of the         *
00028 *    ROM license, in the file Rom24/doc/rom.license                         *
00029 ****************************************************************************/
00030 
00031 /****************************************************************************
00032  *   This file is just the stock nanny() function ripped from comm.c. It    *
00033  *   seems to be a popular task for new mud coders, so what the heck?       *
00034  ***************************************************************************/
00035 
00036 #if defined(macintosh)
00037 #include <types.h>
00038 #else
00039 #include <sys/types.h>
00040 #include <sys/time.h>
00041 #endif
00042 
00043 #include <ctype.h>
00044 #include <errno.h>
00045 #include <stdio.h>
00046 #include <string.h>
00047 #include <stdlib.h>
00048 #include <time.h>
00049 #include <unistd.h>                /* OLC -- for close read write etc */
00050 #include <stdarg.h>                /* printf_to_char */
00051 
00052 #include "merc.h"
00053 #include "interp.h"
00054 #include "recycle.h"
00055 #include "tables.h"
00056 
00057 #if    defined(macintosh) || defined(MSDOS)
00058 extern const char echo_off_str[];
00059 extern const char echo_on_str[];
00060 extern const char go_ahead_str[];
00061 #endif
00062 
00063 #if    defined(unix)
00064 #include <fcntl.h>
00065 #include <netdb.h>
00066 #include <netinet/in.h>
00067 #include <sys/socket.h>
00068 #include "telnet.h"
00069 extern const char echo_off_str[];
00070 extern const char echo_on_str[];
00071 extern const char go_ahead_str[];
00072 #endif
00073 
00074 /*
00075  * OS-dependent local functions.
00076  */
00077 #if defined(macintosh) || defined(MSDOS)
00078 void game_loop_mac_msdos args ((void));
00079 bool read_from_descriptor args ((DESCRIPTOR_DATA * d));
00080 bool write_to_descriptor args ((int desc, char *txt, int length));
00081 #endif
00082 
00083 #if defined(unix)
00084 void game_loop_unix args ((int control));
00085 int init_socket args ((int port));
00086 void init_descriptor args ((int control));
00087 bool read_from_descriptor args ((DESCRIPTOR_DATA * d));
00088 bool write_to_descriptor args ((int desc, char *txt, int length));
00089 #endif
00090 
00091 /*
00092  *  * Other local functions (OS-independent).
00093  *   */
00094 bool check_parse_name args ((char *name));
00095 bool check_reconnect args ((DESCRIPTOR_DATA * d, char *name, bool fConn));
00096 bool check_playing args ((DESCRIPTOR_DATA * d, char *name));
00097 
00098 /*
00099  * Global variables.
00100  */
00101 extern DESCRIPTOR_DATA *descriptor_list;    /* All open descriptors     */
00102 extern DESCRIPTOR_DATA *d_next;        /* Next descriptor in loop  */
00103 extern FILE *fpReserve;                /* Reserved file handle     */
00104 extern bool god;                        /* All new chars are gods!  */
00105 extern bool merc_down;                    /* Shutdown         */
00106 extern bool wizlock;                    /* Game is wizlocked        */
00107 extern bool newlock;                    /* Game is newlocked        */
00108 extern char str_boot_time[MAX_INPUT_LENGTH];
00109 extern time_t current_time;            /* time of this pulse */
00110 
00111 
00112 /*
00113  * Deal with sockets that haven't logged in yet.
00114  */
00115 void nanny (DESCRIPTOR_DATA * d, char *argument)
00116 {
00117 
00118         DESCRIPTOR_DATA *d_old, *d_next;
00119     char buf[MAX_STRING_LENGTH];
00120     char arg[MAX_INPUT_LENGTH];
00121     CHAR_DATA *ch;
00122     char *pwdnew;
00123     char *p;
00124     int iClass, race, i, weapon;
00125     bool fOld;
00126     extern int mud_telnetga, mud_ansicolor;
00127 
00128     /* Delete leading spaces UNLESS character is writing a note */
00129 //if (d->connected != CON_NOTE_TEXT)
00130 //  {
00131 //      while ( isspace(*argument) )
00132 //          argument++;
00133 //  }
00134     ch = d->character;
00135 
00136     switch (d->connected)
00137     {
00138 
00139         default:
00140             bug ("Nanny: bad d->connected %d.", d->connected);
00141             close_socket (d);
00142             return;
00143 
00144         case CON_ANSI:
00145             if (argument[0] == '\0' || UPPER (argument[0]) == 'Y')
00146             {
00147                 d->ansi = TRUE;
00148                 send_to_desc ("{RAnsi enabled!{x\n\r", d);
00149                //d->connected = CON_GET_NAME;
00150         d->connected = CON_SHOW_LOGIN;
00151                 {
00152                     extern char *help_greeting;
00153                     if (help_greeting[0] == '.')
00154                         send_to_desc (help_greeting + 1, d);
00155                     else
00156                         send_to_desc (help_greeting, d);
00157                 }
00158                 break;
00159             }
00160 
00161             if (UPPER (argument[0]) == 'N')
00162             {
00163                 d->ansi = FALSE;
00164                 send_to_desc ("Ansi disabled!\n\r", d);
00165                //d->connected = CON_GET_NAME;
00166         d->connected = CON_SHOW_LOGIN;
00167                 {
00168                     extern char *help_greeting;
00169                     if (help_greeting[0] == '.')
00170                         send_to_desc (help_greeting + 1, d);
00171                     else
00172                         send_to_desc (help_greeting, d);
00173                 }
00174                 break;
00175             }
00176             else
00177             {
00178                 send_to_desc ("Do you want Colour? (Y/n) ", d);
00179                 return;
00180             }
00181 
00182           case CON_SHOW_LOGIN:
00183                         
00184                         if (argument[0] == '\0')
00185                                 d->connected = CON_SHOW_LOGIN;
00186                         if (UPPER (argument[0]) == 'P')
00187                         {
00188                                 send_to_desc ("Please enter your name: ",d);
00189                                 d->connected = CON_GET_NAME;
00190                                 return;
00191                         }
00192                         if (UPPER (argument[0]) == 'C')
00193                         {
00194                                 send_to_desc ("Please enter the name you wish to use: ",d);
00195                                 d->connected = CON_GET_NAME;
00196                                 return;
00197                         }
00198                         if (UPPER (argument[0]) == 'W')
00199                         {
00200                             send_to_desc ("If only the world knew...\n\r[{DHit enter to continue{x]",d);
00201                     /*DESCRIPTOR_DATA *dlist;
00202                     int dCol=0;
00203                     char dbuf[MAX_STRING_LENGTH];
00204                     BUFFER *dBuf;
00205                     dBuf = new_buf();
00206                     for (dlist = descriptor_list; dlist != NULL; dlist = dlist->next)
00207                     {
00208                         if (dlist->connected != CON_PLAYING || !can_see (d->character, dlist->character))
00209                                           continue;
00210                         sprintf(dbuf, "{W%-12s{x ", dlist->character->name);
00211                         add_buf(dBuf, dbuf);
00212                         if (dCol % 5 == 0)
00213                             add_buf(dBuf, "\n\r");
00214                     }
00215                     send_to_desc(buf_string(dBuf), d);
00216                     free_buf(dBuf);
00217 
00218 
00219                         
00220                         
00221 
00222                           
00223                 */      
00224                             d->connected = CON_SHOW_LOGIN;
00225                             return;
00226                     }
00227                         if (UPPER (argument[0]) == 'Q')
00228                 {
00229                     send_to_desc ("Thank you for stoping by, please come back soon!!\n\r",d);
00230                     //send_to_desc ("{Rone.xwin.net {Dport{g: {W4000{x\n\r",d);
00231                     close_socket(d);
00232                     return;
00233                 }
00234                 char sbuf[MAX_STRING_LENGTH];
00235                 send_to_desc ("\n\r",d);
00236                 send_to_desc ("\t{D*-------|{wBeyond the shadows{D|--------*\n\r",d);
00237                         send_to_desc ("\t{D|    ({RP{D)lay an existing character   |",d);
00238                 sprintf (sbuf, "\t  {D*-------|{wGame status{D|-------*{x\n\r");
00239                 send_to_desc (sbuf, d);
00240                 send_to_desc ("\t{D|    ({RC{D)reate a new character.      |",d);
00241                 sprintf (sbuf, "\t  {D| {wWizlock{g: {R%-4s         {D    |\n\r", wizlock ? "Yes" : "No");
00242                 send_to_desc(sbuf, d);
00243                 send_to_desc ("\t{D|    ({RQ{D)uit                         |",d);
00244                 sprintf (sbuf, "\t  {D| {wNewlock{g: {R%-4s         {D    |\n\r", newlock ? "Yes" : "No");
00245                     send_to_desc(sbuf,d);
00246                 send_to_desc ("\t{D|    ({RW{D)ho is playing?              |",d);
00247                 sprintf (sbuf, "\t  {D*-------|{wGame status{D|-------*{x\n\r");
00248                 send_to_desc (sbuf, d);
00249                 send_to_desc ("\t{D*-------|{wBeyond the shadows{D|--------*{x\n\r",d);
00250                         send_to_desc ("\n\r\n\rYour selection-> ",d);
00251                         return;
00252                                                                                 
00253 
00254         case CON_GET_NAME:
00255             if (argument[0] == '\0')
00256             {
00257                 close_socket (d);
00258                 return;
00259             }
00260 
00261             argument[0] = UPPER (argument[0]);
00262             if (!check_parse_name (argument))
00263             {
00264                 send_to_desc ("Illegal name, try another.\n\rName: ", d);
00265                 return;
00266             }
00267 
00268             fOld = load_char_obj (d, argument);
00269             ch = d->character;
00270 
00271             if (IS_SET (ch->act, PLR_DENY))
00272             {
00273                 sprintf (log_buf, "Denying access to %s@%s.", argument,
00274                          d->host);
00275                 log_string (log_buf);
00276                 send_to_desc ("You are denied access.\n\r", d);
00277                 close_socket (d);
00278                 return;
00279             }
00280 
00281             if (check_ban (d->host, BAN_PERMIT)
00282                 && !IS_SET (ch->act, PLR_PERMIT))
00283             {
00284                 send_to_desc ("Your site has been banned from this mud.\n\r",
00285                               d);
00286                 close_socket (d);
00287                 return;
00288             }
00289 
00290             if (check_reconnect (d, argument, FALSE))
00291             {
00292                 fOld = TRUE;
00293             }
00294             else
00295             {
00296                 if (wizlock && !IS_IMMORTAL (ch))
00297                 {
00298                     send_to_desc ("The game is wizlocked.\n\r", d);
00299                     close_socket (d);
00300                     return;
00301                 }
00302             }
00303 
00304             if (fOld)
00305             {
00306                 /* Old player */
00307                 send_to_desc ("Password: ", d);
00308                 write_to_buffer (d, echo_off_str, 0);
00309                 d->connected = CON_GET_OLD_PASSWORD;
00310                 return;
00311             }
00312             else
00313             {
00314                 /* New player */
00315                 if (newlock)
00316                 {
00317                     send_to_desc ("The game is newlocked.\n\r", d);
00318                     close_socket (d);
00319                     return;
00320                 }
00321 
00322                 if (check_ban (d->host, BAN_NEWBIES))
00323                 {
00324                     send_to_desc
00325                         ("New players are not allowed from your site.\n\r",
00326                          0);
00327                     close_socket (d);
00328                     return;
00329                 }
00330 
00331                 sprintf (buf, "Did I get that right, %s (Y/N)? ", argument);
00332                 send_to_desc (buf, d);
00333                 d->connected = CON_CONFIRM_NEW_NAME;
00334                 return;
00335             }
00336             break;
00337 
00338         case CON_GET_OLD_PASSWORD:
00339 #if defined(unix)
00340             write_to_buffer (d, "\n\r", 2);
00341 #endif
00342 
00343             if (strcmp (crypt (argument, ch->pcdata->pwd), ch->pcdata->pwd))
00344             {
00345                 send_to_desc ("{*{!{RWrong password{x.\n\r", d);
00346                // close_socket (d);
00347                 WAIT_STATE (d->character, PULSE_TICK);
00348         send_to_desc ("Enter the correct password:",d);
00349         return;
00350             }
00351 
00352             write_to_buffer (d, echo_on_str, 0);
00353 
00354             if (check_playing (d, ch->name))
00355                 return;
00356 
00357             if (check_reconnect (d, ch->name, TRUE))
00358                 return;
00359         sprintf (log_buf, "%s@%s has connected.", ch->name, d->host);
00360         log_string (log_buf);
00361 
00362             sprintf (log_buf, "{R%s@{c%s{x has connected.{x", ch->name, d->host);  
00363             
00364             wiznet (log_buf, NULL, NULL, WIZ_SITES, 0, get_trust (ch));
00365 
00366             if (ch->desc->ansi)
00367                 SET_BIT (ch->act, PLR_COLOUR);
00368             else
00369                 REMOVE_BIT (ch->act, PLR_COLOUR);
00370 
00371             if (IS_IMMORTAL (ch))
00372             {
00373                 do_function (ch, &do_help, "imotd");
00374         d->connected = CON_READ_IMOTD;
00375             }
00376             else
00377             {
00378                 do_function (ch, &do_help, "motd");
00379                 d->connected = CON_READ_MOTD;
00380             }
00381             break;
00382 
00383 /* RT code for breaking link */
00384 
00385         case CON_BREAK_CONNECT:
00386             switch (*argument)
00387             {
00388                 case 'y':
00389                 case 'Y':
00390                     for (d_old = descriptor_list; d_old != NULL;
00391                          d_old = d_next)
00392                     {
00393                         d_next = d_old->next;
00394                         if (d_old == d || d_old->character == NULL)
00395                             continue;
00396 
00397                         if (str_cmp (ch->name, d_old->original ?
00398                                      d_old->original->name : d_old->
00399                                      character->name))
00400                             continue;
00401 
00402                         close_socket (d_old);
00403                     }
00404                     if (check_reconnect (d, ch->name, TRUE))
00405                         return;
00406                     send_to_desc ("Reconnect attempt failed.\n\rName: ", d);
00407                     if (d->character != NULL)
00408                     {
00409                         free_char (d->character);
00410                         d->character = NULL;
00411                     }
00412                     d->connected = CON_GET_NAME;
00413                     break;
00414 
00415                 case 'n':
00416                 case 'N':
00417                     send_to_desc ("Name: ", d);
00418                     if (d->character != NULL)
00419                     {
00420                         free_char (d->character);
00421                         d->character = NULL;
00422                     }
00423                     d->connected = CON_GET_NAME;
00424                     break;
00425 
00426                 default:
00427                     send_to_desc ("Please type Y or N? ", d);
00428                     break;
00429             }
00430             break;
00431 
00432         case CON_CONFIRM_NEW_NAME:
00433             switch (*argument)
00434             {
00435                 case 'y':
00436                 case 'Y':
00437                     sprintf (buf,
00438                              "New character.\n\rGive me a password for %s: %s",
00439                              ch->name, echo_off_str);
00440                     send_to_desc (buf, d);
00441                     d->connected = CON_GET_NEW_PASSWORD;
00442                     if (ch->desc->ansi)
00443                         SET_BIT (ch->act, PLR_COLOUR);
00444                     break;
00445 
00446                 case 'n':
00447                 case 'N':
00448                     send_to_desc ("Ok, what IS it, then? ", d);
00449                     free_char (d->character);
00450                     d->character = NULL;
00451                     d->connected = CON_GET_NAME;
00452                     break;
00453 
00454                 default:
00455                     send_to_desc ("Please type Yes or No? ", d);
00456                     break;
00457             }
00458             break;
00459 
00460         case CON_GET_NEW_PASSWORD:
00461 #if defined(unix)
00462             write_to_buffer (d, "\n\r", 2);
00463 #endif
00464 
00465             if (strlen (argument) < 5)
00466             {
00467                 send_to_desc
00468                     ("Password must be at least five characters long.\n\rPassword: ",
00469                      d);
00470                 return;
00471             }
00472 
00473             pwdnew = crypt (argument, ch->name);
00474             for (p = pwdnew; *p != '\0'; p++)
00475             {
00476                 if (*p == '~')
00477                 {
00478                     send_to_desc
00479                         ("New password not acceptable, try again.\n\rPassword: ",
00480                          d);
00481                     return;
00482                 }
00483             }
00484 
00485             free_string (ch->pcdata->pwd);
00486             ch->pcdata->pwd = str_dup (pwdnew);
00487             send_to_desc ("Please retype password: ", d);
00488             d->connected = CON_CONFIRM_NEW_PASSWORD;
00489             break;
00490 
00491         case CON_CONFIRM_NEW_PASSWORD:
00492 #if defined(unix)
00493             write_to_buffer (d, "\n\r", 2);
00494 #endif
00495 
00496             
00497         if (strcmp (crypt (argument, ch->pcdata->pwd), ch->pcdata->pwd))
00498             {
00499                 send_to_desc ("Passwords don't match.\n\rRetype password: ",
00500                               d);
00501                 d->connected = CON_GET_NEW_PASSWORD;
00502                 return;
00503             }
00504 
00505             write_to_buffer (d, echo_on_str, 0);
00506             send_to_desc ("You may select one of the following races:\n\r", d);
00507             for (race = 1; race_table[race].name != NULL; race++)
00508             {
00509                 if (!race_table[race].pc_race)
00510                     break;
00511         if (!str_cmp (race_table[race].name, "dragon"))
00512             break;
00513                 //write_to_buffer (d, race_table[race].name, 0);
00514                 //write_to_buffer (d, " ", 1);
00515         sprintf(buf, "{W* {x%s\n\r", race_table[race].name);
00516         send_to_desc(buf, d);
00517             }
00518             write_to_buffer (d, "\n\r", 0);
00519             send_to_desc ("What race would you like to be(help for more information)? ",
00520                           d);
00521             d->connected = CON_GET_NEW_RACE;
00522             break;
00523 
00524         case CON_GET_NEW_RACE:
00525             one_argument (argument, arg);
00526 
00527             if (!strcmp (arg, "help"))
00528             {
00529                 argument = one_argument (argument, arg);
00530                 if (argument[0] == '\0')
00531                     do_function (ch, &do_help, "race help");
00532                 else
00533                     do_function (ch, &do_help, argument);
00534                 send_to_desc
00535                     ("What race would you like to be(help for more information)? ", d);
00536                 break;
00537             }
00538 
00539             race = race_lookup (argument);
00540 
00541             if (race == 0 || !race_table[race].pc_race || !str_cmp(race_table[race].name, "dragon"))
00542             {
00543                 send_to_desc ("That is not a valid race.\n\r", d);
00544                 send_to_desc ("The following races are available:\n\r", d);
00545                 for (race = 1; race_table[race].name != NULL; race++)
00546                 {
00547                     if (!race_table[race].pc_race)
00548                         break;
00549             if (!str_cmp(race_table[race].name, "dragon"))
00550                 break;
00551 
00552                     //write_to_buffer (d, race_table[race].name, 0);
00553                     //write_to_buffer (d, " ", 1);
00554             sprintf(buf, "{W* {x%s\n\r", race_table[race].name);
00555             send_to_desc(buf,d);
00556                 }
00557                 write_to_buffer (d, "\n\r", 0);
00558                 send_to_desc
00559                     ("What is your race? (help for more information) ", d);
00560                 break;
00561             }
00562 
00563             ch->race = race;
00564             /* initialize stats */
00565             for (i = 0; i < MAX_STATS; i++)
00566                 ch->perm_stat[i] = pc_race_table[race].stats[i];
00567             ch->affected_by = ch->affected_by | race_table[race].aff;
00568             ch->imm_flags = ch->imm_flags | race_table[race].imm;
00569             ch->res_flags = ch->res_flags | race_table[race].res;
00570             ch->vuln_flags = ch->vuln_flags | race_table[race].vuln;
00571             ch->form = race_table[race].form;
00572             ch->parts = race_table[race].parts;
00573 
00574             /* add skills */
00575             for (i = 0; i < 5; i++)
00576             {
00577                 if (pc_race_table[race].skills[i] == NULL)
00578                     break;
00579                 group_add (ch, pc_race_table[race].skills[i], FALSE);
00580             }
00581             /* add cost */
00582             ch->pcdata->points = pc_race_table[race].points;
00583             ch->size = pc_race_table[race].size;
00584 
00585             send_to_desc ("What is your sex (Male/Female)? ", d);
00586             d->connected = CON_GET_NEW_SEX;
00587             break;
00588 
00589 
00590         case CON_GET_NEW_SEX:
00591             switch (argument[0])
00592             {
00593                 case 'm':
00594                 case 'M':
00595                     ch->sex = SEX_MALE;
00596                     ch->pcdata->true_sex = SEX_MALE;
00597                     break;
00598                 case 'f':
00599                 case 'F':
00600                     ch->sex = SEX_FEMALE;
00601                     ch->pcdata->true_sex = SEX_FEMALE;
00602                     break;
00603                 default:
00604                     send_to_desc ("That is not a valid sex, What is your sex? ",
00605                                   d);
00606                     return;
00607             }
00608 
00609             strcpy (buf, "Select a class:\n\r");
00610             for (iClass = 0; iClass < MAX_CLASS; iClass++)
00611             {
00612                 if (iClass > 0)
00613                     strcat (buf, " ");
00614         if (class_table[iClass].pick == FALSE)
00615             continue;
00616                 //strcat (buf, class_table[iClass].name);
00617         sprintf(buf, "{W*{x %s\n\r", class_table[iClass].name);
00618         send_to_desc(buf,d);
00619             }
00620             //strcat (buf, "]: ");
00621             //write_to_buffer (d, buf, 0);
00622             d->connected = CON_GET_NEW_CLASS;
00623             break;
00624 
00625         case CON_GET_NEW_CLASS:
00626            iClass = class_lookup (argument);
00627            //  iClass = class_lookup ("citizen");
00628             if (iClass == -1 || (class_table[iClass].pick == FALSE))
00629             {
00630                 send_to_desc ("That is not a valid class, What is your class? ",
00631                               d);
00632                 return;
00633             }
00634 
00635             ch->class = iClass;
00636 
00637             sprintf (log_buf, "%s@%s new player.", ch->name, d->host);
00638             log_string (log_buf);
00639             wiznet ("Newbie alert!  $N sighted.", ch, NULL, WIZ_NEWBIE, 0, 0);
00640             wiznet (log_buf, NULL, NULL, WIZ_SITES, 0, get_trust (ch));
00641         
00642         
00643             write_to_buffer (d, "\n\r", 2);
00644             send_to_desc ("You may be good, neutral, or evil.\n\r", d);
00645             send_to_desc ("Which alignment (Good/Neutral/Evil)? ", d);
00646             
00647         d->connected = CON_GET_ALIGNMENT;
00648             break;
00649     
00650 
00651     case CON_GET_ALIGNMENT:
00652             switch (argument[0])
00653             {
00654                 case 'g':
00655                 case 'G':
00656                     ch->alignment = 750;
00657                     break;
00658                 case 'n':
00659                 case 'N':
00660                     ch->alignment = 0;
00661                     break;
00662                 case 'e':
00663                 case 'E':
00664                     ch->alignment = -750;
00665                     break;
00666                 default:
00667                     send_to_desc ("That's not a valid alignment.\n\r", d);
00668                     send_to_desc ("Which alignment (G/N/E)? ", d);
00669                     return;
00670             }
00671 
00672         
00673 
00674             write_to_buffer (d, "\n\r", 0);
00675 
00676         send_to_desc ("\n\r\n\r{wWelcome to character creation. This process will help you customize\n\r"
00677                 "{wyour character the way you see fit. Any abuse of these creation processes\n\r"
00678                 "{wwill be {Rnot{x tolerated.{x{w If they do not stand up to the Beyond the Shadows\n\r"
00679                 "{wThen they will either be changed, or you will seek a chance of denial. And please\n\r"
00680                 "{wfor the sake of all who play, use common sense.{x",d);
00681 
00682         sprintf(buf, "\n\r{wYour current race is: %s\n\r", race_table[d->character->race].name);
00683         send_to_desc(buf,d);
00684         send_to_desc("{xPlease enter your eye color (Color codes may be used): ",d);
00685         d->connected = CON_GET_EYE_COLOR;
00686         break;
00687 
00688     case CON_GET_EYE_COLOR:
00689         if (argument[0] != ' ')
00690         {
00691             sprintf(buf, "Are you sure %s is what you want?(Y/n)", argument);
00692             d->character->pcdata->eyecolor = str_dup(argument);
00693             send_to_desc(buf,d);
00694             d->connected = CON_CONFIRM_EYES;
00695             break;
00696         }
00697         if (argument[0] == ' ')
00698         {
00699             send_to_desc("Please enter your eye color (Color codes may be used): ",d);
00700             d->connected = CON_GET_EYE_COLOR;
00701             return;
00702         }
00703         
00704         break;
00705 
00706     case CON_CONFIRM_EYES:
00707         switch (argument[0])
00708         {
00709             case 'y':
00710             case 'Y':
00711                 send_to_desc("Eye color set.\n\r",d);
00712                 sprintf(buf, "Current race: %s:\n\rCurrent eye color: %s\n\r",
00713                         race_table[d->character->race].name, d->character->pcdata->eyecolor);
00714                 send_to_desc(buf,d);
00715                 send_to_desc("\n\rPlease enter your hair texture. If no hair, enter bald: ",d);
00716                 
00717                 d->connected = CON_GET_HAIR_TYPE;
00718                 break;
00719             case 'n':
00720             case 'N':
00721                 d->character->pcdata->eyecolor = NULL;
00722                 send_to_desc("Please enter your eye color (Color codes may be used): ", d);
00723                 d->connected = CON_GET_EYE_COLOR;
00724                 break;
00725 
00726             default: 
00727                 d->character->pcdata->eyecolor = NULL;
00728                 send_to_desc("Please enter your eye color (Color codes may be used): ", d);
00729                 d->connected = CON_GET_EYE_COLOR;
00730                 break;
00731         }
00732             
00733             
00734         break;
00735     case CON_GET_HAIR_LENGTH:
00736         if (argument[0] != ' ')
00737         {
00738             sprintf(buf, "Are you sure %s is what you want? (y/n)", argument);
00739             d->character->pcdata->hairlength = str_dup(argument);
00740             send_to_desc(buf,d);
00741             d->connected = CON_CONFIRM_HAIR_LENGTH;
00742             break;
00743         }
00744         if (argument[0] == ' ')
00745         {
00746             send_to_desc("Please enter your hair length ",d);
00747             d->connected = CON_GET_HAIR_LENGTH;
00748             break;
00749         }
00750         break;
00751     case CON_CONFIRM_HAIR_LENGTH:
00752         switch(argument[0])
00753         {
00754             case 'y':
00755             case 'Y':
00756                 send_to_desc("Hair length set.\n\r",d);
00757                 sprintf(buf, "Current race %s\n\rCurrent eye color %s\n\rCurrent hair type %s\n\r"
00758                         "Current hair color %s\n\rCurrent hair length %s\n\r",
00759                         race_table[ch->race].name, ch->pcdata->eyecolor,
00760                         ch->pcdata->hairtype, ch->pcdata->haircolor, ch->pcdata->hairlength);
00761                 send_to_desc(buf,d);
00762                 send_to_desc("Please enter your body type: ",d);
00763                 d->connected = CON_GET_BODY_TYPE;
00764                 break;
00765             case 'n':
00766             case 'N':
00767                 ch->pcdata->hairlength = NULL;
00768                 send_to_desc("Please enter your hair length ",d);
00769                 d->connected = CON_GET_HAIR_LENGTH;
00770                 break;
00771             default:
00772                 ch->pcdata->hairlength = NULL;
00773                 send_to_desc("Please enter your hair length ",d);
00774                 d->connected = CON_GET_HAIR_LENGTH;
00775                 break;
00776         }
00777         break;
00778                 
00779         
00780     case CON_GET_HAIR_TYPE:
00781         if (argument[0] != ' ')
00782         {
00783             sprintf(buf, "Are you sure %s is what you want? (Y/n)", argument);
00784             d->character->pcdata->hairtype = str_dup(argument);
00785             send_to_desc(buf,d);
00786             d->connected = CON_CONFIRM_HAIR_TYPE;
00787             break;
00788         }
00789         if (argument[0] == ' ')
00790         {
00791             send_to_desc("Please enter your hair texture. If no hair, enter bald: ", d);
00792             d->connected = CON_GET_HAIR_TYPE;
00793             return;
00794         }
00795         break;
00796         
00797     case CON_CONFIRM_HAIR_TYPE:
00798         switch(argument[0])
00799         {
00800             case 'y':
00801             case 'Y':
00802                 send_to_desc("Hair texture set.\n\r",d);
00803                 sprintf(buf, "Current race: %s\n\rCurrent eye color: %s\n\rCurrent hair texture %s\n\r\n\r",
00804                         race_table[d->character->race].name, d->character->pcdata->eyecolor,
00805                         d->character->pcdata->hairtype);
00806                 send_to_desc(buf,d);
00807                 if (!str_cmp(d->character->pcdata->hairtype, "bald"))
00808                 {
00809 /*                  group_add (ch, "rom basics", FALSE);
00810                     group_add (ch, class_table[ch->class].base_group, FALSE);
00811                     ch->pcdata->learned[gsn_recall] = 50;
00812                     send_to_desc ("Do you wish to customize this character?\n\r", d);
00813                     send_to_desc
00814                         ("Customization takes time, but allows a wider range of skills and abilities.\n\r",
00815                      d);
00816                     send_to_desc ("Customize (Y/N)? ", d);
00817                     d->connected = CON_DEFAULT_CHOICE;*/
00818                     ch->pcdata->haircolor = "None";
00819                     ch->pcdata->hairlength = "None";
00820                     send_to_desc("Please enter your body type: ",d);
00821                     d->connected = CON_GET_BODY_TYPE;
00822                     break;
00823                 }
00824                 send_to_desc("Please enter your hair color (color codes may be used): ", d);
00825                 d->connected = CON_GET_HAIR_COLOR;
00826                 break;
00827             case 'n':
00828             case 'N':
00829                 d->character->pcdata->hairtype = NULL;
00830                 send_to_desc("Please enter your hair texture. If no hair, enter bald: ", d);
00831                 d->connected = CON_GET_HAIR_TYPE;
00832                 break;
00833             default:
00834                 d->character->pcdata->hairtype = NULL;
00835                 send_to_desc("Please enter your hair texture. If no hair, enter bald: ",d);
00836                 d->connected = CON_GET_HAIR_TYPE;
00837                 break;
00838         }
00839         break;
00840 
00841     case CON_GET_BODY_TYPE:
00842         if (argument[0] != ' ')
00843         {
00844             sprintf(buf, "Are you sure %s is what you want?(Y/n)", argument);
00845             send_to_desc(buf,d);
00846             d->character->pcdata->bodytype = str_dup(argument);
00847             d->connected = CON_CONFIRM_BODY_TYPE;
00848             break;
00849         }
00850         if (argument[0] == ' ')
00851         {
00852             send_to_desc("Please enter your body type: ", d);
00853             d->connected = CON_GET_BODY_TYPE;
00854             return;
00855         }
00856         break;
00857     case CON_CONFIRM_BODY_TYPE:
00858         switch (argument[0])
00859         {
00860             case 'y':
00861             case 'Y':
00862                 send_to_desc("Body type set.\n\r",d);
00863                 sprintf(buf,"Current race %s\n\rCurrent eye color %s\n\r Current hair texture %s\n\r"
00864                         "Current hair color %s\n\rCurrent hair length %s\n\rCurrent body type %s\n\r",
00865                         race_table[d->character->race].name, d->character->pcdata->eyecolor,
00866                         d->character->pcdata->hairtype, d->character->pcdata->haircolor,
00867                         ch->pcdata->hairlength,d->character->pcdata->bodytype);
00868                 send_to_desc(buf,d);
00869                 if (d->character->sex == 2)
00870                 {
00871                     send_to_desc("Continuing with creation...\n\r",d);
00872                     group_add(ch, "rom basics", FALSE);
00873                     group_add(ch, class_table[ch->class].base_group, FALSE);
00874                     ch->pcdata->learned[gsn_recall] = 50;
00875                     send_to_desc("Do you wish to customize this character?\n\r",d);
00876                     send_to_desc("Customization takes time, but allows a wider range of skills and"
00877                             "abilities.\n\r",d);
00878                     send_to_desc("Continue with customization? (Y/n) ", d);
00879                     d->connected = CON_DEFAULT_CHOICE;
00880                     break;
00881                 }
00882                 send_to_desc("Enter your facial hair type(none for none): ",d);
00883                 d->connected = CON_GET_FACIAL_HAIR;
00884                 break;
00885             case 'n':
00886             case 'N':
00887                 d->character->pcdata->bodytype = NULL;
00888                 send_to_desc("Please enter your body type: ",d);
00889                 d->connected = CON_GET_BODY_TYPE;
00890                 break;
00891             default:
00892                 d->character->pcdata->bodytype = NULL;
00893                 send_to_desc("Please enter your body type: ", d);
00894                 d->connected = CON_GET_BODY_TYPE;
00895                 break;
00896                 
00897         }
00898         break;
00899     case CON_GET_FACIAL_HAIR:
00900         if (argument[0] != ' ')
00901         {
00902             sprintf(buf, "Are you sure %s is what you want?(Y/n)", argument);
00903             send_to_desc(buf,d);
00904             d->character->pcdata->facialhair = str_dup(argument);
00905             d->connected = CON_CONFIRM_FACIAL_HAIR;
00906             break;
00907         }
00908         if (argument[0] == ' ')
00909         {
00910             send_to_desc("Enter your facial hair type(none for none): ",d);
00911             d->connected = CON_GET_FACIAL_HAIR;
00912             break;
00913         }
00914         break;
00915     case CON_CONFIRM_FACIAL_HAIR:
00916         switch(argument[0])
00917         {
00918             case 'y':
00919             case 'Y':
00920                 send_to_desc ("Facial hair set.\n\r",d);
00921                 sprintf(buf, "Current race %s\n\rCurrent eye color %s\n\rCurrent hair texture %s\n\r"
00922                         "Current hair color %s\n\rCurrent hair length %s\n\rCurrent body type %s\n\r"
00923                         "Current facial hair type %s\n\r",
00924                         race_table[ch->race].name, ch->pcdata->eyecolor, ch->pcdata->hairtype,
00925                         ch->pcdata->haircolor,ch->pcdata->hairlength,
00926                         ch->pcdata->bodytype, ch->pcdata->facialhair);
00927                 send_to_desc(buf,d);
00928                 send_to_desc("\n\rContinuing with creation...\n\r",d);
00929                 group_add(ch, "rom basics", FALSE);
00930                 group_add(ch, class_table[ch->class].base_group, FALSE);
00931                     ch->pcdata->learned[gsn_recall] = 50;
00932                         send_to_desc("Do you wish to customize this character?\n\r",d);
00933                 send_to_desc("Customization takes time, but it allows a wider range of skills and "
00934                     "abilities\n\r",d);
00935                 send_to_desc("Customize?(Y/n) ", d);
00936                         d->connected = CON_DEFAULT_CHOICE;
00937                         break;
00938             case 'n':
00939             case 'N':
00940               ch->pcdata->facialhair = NULL;
00941                       send_to_desc("Enter your facial hair type(none for none): ",d);
00942                       d->connected = CON_GET_FACIAL_HAIR;
00943                       break;
00944             default:
00945               ch->pcdata->facialhair = NULL;
00946               send_to_desc("Enter your facial hair type(none for none): ",d);
00947               d->connected = CON_GET_FACIAL_HAIR;
00948               break;
00949         }
00950             break;
00951 
00952     case CON_GET_HAIR_COLOR:
00953         if (argument[0] != ' ')
00954         {
00955             sprintf(buf, "Are you sure %s is what you want?(Y/n)", argument);
00956             send_to_desc(buf,d);
00957             d->character->pcdata->haircolor = str_dup(argument);
00958             d->connected = CON_CONFIRM_HAIR_COLOR;
00959             break;
00960         }
00961         if (argument[0] == ' ')
00962         {
00963             send_to_desc("Please enter your hair color (color codes may be used): ", d);
00964             d->connected = CON_GET_HAIR_COLOR;
00965             return;
00966         }
00967         break;
00968 
00969     case CON_CONFIRM_HAIR_COLOR:
00970         switch (argument[0])
00971         {
00972             case 'y':
00973             case 'Y':
00974                 send_to_desc ("Hair color set.\n\r",d);
00975                 sprintf(buf, "Current race %s\n\rCurrent eye color %s\n\rCurrent hair texture %s\n\r"
00976                         "Current hair color %s\n\r",
00977                         race_table[d->character->race].name, d->character->pcdata->eyecolor,
00978                         d->character->pcdata->hairtype,
00979                         d->character->pcdata->haircolor);
00980                 send_to_desc(buf,d);
00981 /*              send_to_desc("\n\rContinuing with creation.\n\r",d);
00982                 group_add(ch, "rom basics", FALSE);
00983                 group_add(ch, class_table[ch->class].base_group, FALSE);
00984                 ch->pcdata->learned[gsn_recall] = 50;
00985                 send_to_desc("Do you wish to customize this character?\n\r",d);
00986                 send_to_desc("Customization takes time, but allows a wider range of skills and abilities.\n\r",
00987                         d);
00988                 send_to_desc("Customize?(Y/n) ",d);
00989                 d->connected = CON_DEFAULT_CHOICE;*/
00990                 send_to_desc("Please enter your hair length  ",d);
00991                 d->connected = CON_GET_HAIR_LENGTH;
00992                 break;
00993             case 'n':
00994             case 'N':
00995                 d->character->pcdata->haircolor = NULL;
00996                 send_to_desc ("Please enter your hair color (color codes may be used): ",d);
00997                 d->connected = CON_GET_HAIR_COLOR;
00998                 break;
00999             default:
01000                 d->character->pcdata->haircolor = NULL;
01001                 send_to_desc ("Please enter your hair color (color codes may be used): ", d);
01002                 d->connected = CON_GET_HAIR_COLOR;
01003                 break;
01004                 
01005         }
01006         break;
01007                 
01008                 
01009         
01010 
01011         
01012                 
01013                 
01014 
01015         case CON_DEFAULT_CHOICE:
01016             write_to_buffer (d, "\n\r", 2);
01017             switch (argument[0])
01018             {
01019                 case 'y':
01020                 case 'Y':
01021                     ch->gen_data = new_gen_data ();
01022                     ch->gen_data->points_chosen = ch->pcdata->points;
01023                     do_function (ch, &do_help, "group header");
01024                     list_group_costs (ch);
01025                     write_to_buffer (d,
01026                                      "You already have the following skills:\n\r",
01027                                      0);
01028                     do_function (ch, &do_skills, "");
01029                     do_function (ch, &do_help, "menu choice");
01030                     d->connected = CON_GEN_GROUPS;
01031                     break;
01032                 case 'n':
01033                 case 'N':
01034                     group_add (ch, class_table[ch->class].default_group,
01035                                TRUE);
01036                     write_to_buffer (d, "\n\r", 2);
01037                     write_to_buffer (d,
01038                                      "Please pick a weapon from the following choices:\n\r",
01039                                      0);
01040                     buf[0] = '\0';
01041                     for (i = 0; weapon_table[i].name != NULL; i++)
01042                         if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
01043                         {
01044                             strcat (buf, weapon_table[i].name);
01045                             strcat (buf, " ");
01046                         }
01047                     strcat (buf, "\n\rYour choice? ");
01048                     write_to_buffer (d, buf, 0);
01049                     d->connected = CON_PICK_WEAPON;
01050                     break;
01051                 default:
01052                     write_to_buffer (d, "Please answer (Y/N)? ", 0);
01053                     return;
01054             }
01055             break;
01056 
01057         case CON_PICK_WEAPON:
01058             write_to_buffer (d, "\n\r", 2);
01059             weapon = weapon_lookup (argument);
01060             if (weapon == -1
01061                 || ch->pcdata->learned[*weapon_table[weapon].gsn] <= 0)
01062             {
01063                 write_to_buffer (d,
01064                                  "That's not a valid selection. Choices are:\n\r",
01065                                  0);
01066                 buf[0] = '\0';
01067                 for (i = 0; weapon_table[i].name != NULL; i++)
01068                     if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
01069                     {
01070                         strcat (buf, weapon_table[i].name);
01071                         strcat (buf, " ");
01072                     }
01073                 strcat (buf, "\n\rYour choice? ");
01074                 write_to_buffer (d, buf, 0);
01075                 return;
01076             }
01077 
01078             ch->pcdata->learned[*weapon_table[weapon].gsn] = 40;
01079             write_to_buffer (d, "\n\r", 2);
01080             if (ch->reclass == 1)
01081         {
01082             send_to_char("Your class was set successfully, please reconnect.\n\r",ch);
01083             save_char_obj (ch);
01084             //f (ch->desc != NULL)
01085             //     close_socket (ch->desc);
01086             ch->valid = TRUE;
01087             //free_char(ch);
01088             save_char_obj(ch);
01089             close_socket (ch->desc);
01090             return;
01091         }
01092             
01093 
01094                
01095              
01096 
01097         do_function (ch, &do_help, "motd");
01098             
01099         d->connected = CON_READ_MOTD;
01100             break;
01101 
01102         case CON_GEN_GROUPS:
01103             send_to_char ("\n\r", ch);
01104 
01105             if (!str_cmp (argument, "done"))
01106             {
01107                 if (ch->pcdata->points == pc_race_table[ch->race].points)
01108                 {
01109                     send_to_char ("You didn't pick anything.\n\r", ch);
01110                     break;
01111                 }
01112 
01113                 if (ch->pcdata->points < 40 + pc_race_table[ch->race].points)
01114                 {
01115                     sprintf (buf,
01116                              "You must take at least %d points of skills and groups",
01117                              40 + pc_race_table[ch->race].points);
01118                     send_to_char (buf, ch);
01119                     break;
01120                 }
01121 
01122                 sprintf (buf, "Creation points: %d\n\r", ch->pcdata->points);
01123                 send_to_char (buf, ch);
01124                 sprintf (buf, "Experience per level: %d\n\r",
01125                          exp_per_level (ch, ch->gen_data->points_chosen));
01126                 if (ch->pcdata->points < 40)
01127                     ch->train = (40 - ch->pcdata->points + 1) / 2;
01128                 free_gen_data (ch->gen_data);
01129                 ch->gen_data = NULL;
01130                 send_to_char (buf, ch);
01131                 write_to_buffer (d, "\n\r", 2);
01132                 write_to_buffer (d,
01133                                  "Please pick a weapon from the following choices:\n\r",
01134                                  0);
01135                 buf[0] = '\0';
01136                 for (i = 0; weapon_table[i].name != NULL; i++)
01137                     if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
01138                     {
01139                         strcat (buf, weapon_table[i].name);
01140                         strcat (buf, " ");
01141                     }
01142                 strcat (buf, "\n\rYour choice? ");
01143                 write_to_buffer (d, buf, 0);
01144                 d->connected = CON_PICK_WEAPON;
01145                 break;
01146             }
01147 
01148             if (!parse_gen_groups (ch, argument))
01149                 send_to_char
01150                     ("Choices are: list,learned,premise,add,drop,info,help, and done.\n\r",
01151                      ch);
01152 
01153             do_function (ch, &do_help, "menu choice");
01154             break;
01155 
01156         case CON_READ_IMOTD:
01157             write_to_buffer (d, "\n\r", 2);
01158             do_function (ch, &do_help, "motd");
01159             d->connected = CON_READ_MOTD;
01160             break;
01161 
01162         /* states for new note system, (c)1995-96 erwin@pip.dknet.dk */
01163         /* ch MUST be PC here; have nwrite check for PC status! */
01164 
01165     /*  case CON_NOTE_TO:
01166             handle_con_note_to (d, argument);
01167             break;
01168 
01169         case CON_NOTE_SUBJECT:
01170             handle_con_note_subject (d, argument);
01171             break;
01172 
01173         case CON_NOTE_EXPIRE:
01174             handle_con_note_expire (d, argument);
01175             break;
01176 
01177         case CON_NOTE_TEXT:
01178             handle_con_note_text (d, argument);
01179             break;
01180 
01181         case CON_NOTE_FINISH:
01182             handle_con_note_finish (d, argument);
01183             break;*/
01184 
01185         case CON_READ_MOTD:
01186             if (ch->pcdata == NULL || ch->pcdata->pwd[0] == '\0')
01187         {
01188                 write_to_buffer (d, "Warning! Null password!\n\r", 0);
01189                 write_to_buffer (d,
01190                                  "Please report old password with bug.\n\r",
01191                                  0);
01192                 write_to_buffer (d,
01193                                  "Type 'password null <new password>' to fix.\n\r",
01194                                  0);
01195             }
01196 
01197             write_to_buffer (d,
01198                              "\n\rWelcome to Beyond the Shadows.  Please don't feed the mobiles!\n\r",
01199                              0);
01200             ch->next = char_list;
01201             char_list = ch;
01202             d->connected = CON_PLAYING;
01203             reset_char (ch);
01204 
01205             if (ch->level == 0)
01206             {
01207         if(mud_ansicolor)
01208                     SET_BIT (ch->act, PLR_COLOUR);
01209         if(mud_telnetga)
01210             SET_BIT (ch->comm, COMM_TELNET_GA);
01211 
01212                 ch->perm_stat[class_table[ch->class].attr_prime] += 3;
01213 
01214                 ch->level = 1;
01215                 ch->exp = exp_per_level (ch, ch->pcdata->points);
01216                 ch->hit = ch->max_hit;
01217                 ch->mana = ch->max_mana;
01218                 ch->move = ch->max_move;
01219                 ch->train = 3;
01220                 ch->practice = 5;
01221               // sprintf (buf, "the %s", title_table[ch->class][ch->level]
01222                 //         [ch->sex == SEX_FEMALE ? 1 : 0]);
01223                // set_title (ch, buf);
01224 
01225                 do_function (ch, &do_outfit, "");
01226                 //obj_to_char (create_object (get_obj_index (OBJ_VNUM_MAP), 0),
01227                   //           ch);
01228 
01229                 char_to_room (ch, get_room_index (ROOM_VNUM_SCHOOL));
01230                 send_to_char ("\n\r", ch);
01231                 do_function (ch, &do_help, "newbie info");
01232                 send_to_char ("\n\r", ch);
01233             }
01234             else if (ch->in_room != NULL)
01235             {
01236                 char_to_room (ch, ch->in_room);
01237             }
01238             else if (IS_IMMORTAL (ch))
01239             {
01240                 char_to_room (ch, get_room_index (ROOM_VNUM_CHAT));
01241             }
01242             else
01243             {
01244                 char_to_room (ch, get_room_index (ROOM_VNUM_TEMPLE));
01245             }
01246 
01247             act ("$n has entered the game.", ch, NULL, NULL, TO_ROOM);
01248             do_function (ch, &do_look, "auto");
01249 
01250             wiznet ("{R$N has left real life behind.{x", ch, NULL,
01251                     WIZ_LOGINS, WIZ_SITES, get_trust (ch));
01252 
01253             if (ch->pet != NULL)
01254             {
01255                 char_to_room (ch->pet, ch->in_room);
01256                 act ("$n has entered the game.", ch->pet, NULL, NULL,
01257                      TO_ROOM);
01258             }
01259 
01260             send_to_char("\n", ch);
01261            do_function (ch, do_unread, "");
01262             break;
01263     }
01264 
01265     return;
01266 }
01267 

Generated on Thu Jan 13 21:48:13 2005 for Beyond the Shadows by  doxygen 1.4.0