/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements 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. * * * * Much time and thought has gone into this software and you are * * benefiting. 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 * *************************************************************************** * 1stMud ROM Derivative (c) 2001-2004 by Markanth * * http://www.firstmud.com/ <markanth@firstmud.com> * * By using this code you have agreed to follow the term of * * the 1stMud license in ../doc/1stMud/LICENSE * ***************************************************************************/ #include "merc.h" #include "interp.h" #include "telnet.h" #include "recycle.h" #include "tables.h" #include "vnums.h" #include "special.h" Proto(bool check_playing, (Descriptor *, const char *)); Proto(bool check_reconnect, (Descriptor *, const char *, bool)); Do_Fun(nanny_help) { HelpData *pHelp; Buffer *output; char argall[MAX_INPUT_LENGTH], argone[MAX_INPUT_LENGTH]; int level; output = new_buf(); if (NullStr(argument)) argument = "summary"; argall[0] = '\0'; while (!NullStr(argument)) { argument = one_argument(argument, argone); if (!NullStr(argall)) strcat(argall, " "); strcat(argall, argone); } for (pHelp = help_first; pHelp != NULL; pHelp = pHelp->next) { level = (pHelp->level < 0) ? -1 * pHelp->level - 1 : pHelp->level; if (level > get_trust(ch) || pHelp->category != HELP_CREATION) continue; if (is_name(argall, pHelp->keyword)) { bprint(output, help_text(pHelp->text)); break; } } if (!pHelp) chprintlnf(ch, "{cNo help on %s.{x", argall); else sendpage(ch, buf_string(output)); free_buf(output); } Nanny_Fun(HANDLE_CON_GET_TERM) { switch (argument[0]) { case 'y': case 'Y': SetBit(d->desc_flags, DESC_COLOR); d_println(d, "{?Color {cEnabled...{x"); break; case 'n': case 'N': RemBit(d->desc_flags, DESC_COLOR); d_println(d, "Color Disabled..."); break; case 't': case 'T': d_printlnf(d, NEWLINE "This text should be " ESC "[%d;%dmGREEN" CL_DEFAULT "." NEWLINE "This text should be " ESC "[%d;%dmRED" CL_DEFAULT ".", CL_BRIGHT, FG_GREEN, CL_BRIGHT, FG_RED); d_println(d, NEWLINE "Did you see color? (Y)es, (N)o, (T)est: "); return; default: d_println(d, "Please answer (Y)es, (N)o, (T)est: "); return; } show_greeting(d); d->connected = CON_GET_NAME; } Nanny_Fun(HANDLE_CON_GET_NAME) { CharData *ch; bool fOld; NameProfile *nl; Proto(NameProfile * profile_lookup, (int)); Proto(char *genname, (NameProfile *)); if (NullStr(argument)) { d_println(d, "You can't have a blank name, type 'list' to list name generator profiles," NEWLINE "<#> to generate a list of names based on profile number '#'" NEWLINE "'quit' to disconnect, or type your characters name - try again."); d_print(d, mud_info.login_prompt); return; } else if (!str_cmp(argument, "quit")) { close_socket(d); return; } else if (!str_cmp(argument, "list")) { int count = 0; d_println(d, "{RNAME GENERATOR PROFILES{x"); for (nl = name_profile_first; nl; nl = nl->next) { d_printlnf(d, "{W%2d{c> %s{x", ++count, nl->title); } d_println(d, "{cEnter a profile number to view generated names:{x"); return; } else if (is_number(argument)) { int count = 0, i; int profile_num = atoi(argument); Column Cd; if (profile_num < 1 || profile_num > top_name_profile || (nl = profile_lookup(profile_num)) == NULL) { d_printlnf(d, "{cInvalid profile number {W%d{c.{x", profile_num); d_println(d, "{RNAME GENERATOR PROFILES{x"); for (nl = name_profile_first; nl; nl = nl->next) { d_printlnf(d, "{W%2d{c> %s{x", ++count, nl->title); } d_println(d, "{cEnter a profile number to view generated names:{x"); return; } set_cols(&Cd, NULL, 4, COLS_DESC, d); d_printlnf(d, "{RNAME GENERATOR - %s{x", strupper(nl->title)); for (i = 0; i < 60; i++) { print_cols(&Cd, capitalize(genname(nl))); } cols_nl(&Cd); d_println(d, "{cPlease enter your name:{x"); d_println(d, "{c(to view a list of profiles, type 'list' or enter a profile number){x"); return; } else if (!check_parse_name(argument)) { d_println(d, "{cIllegal name, try another.{x" NEWLINE "Name: {x"); return; } fOld = load_char_obj(d, argument); ch = d->character; if (IsSet(ch->act, PLR_DENY)) { logf("Denying access to %s@%s.", argument, d->host); d_println(d, "{cYou are {Rdenied{c access.{x"); close_socket(d); return; } if (check_ban(d->host, BAN_PERMIT) && !IsSet(ch->act, PLR_PERMIT)) { d_println(d, "{cYour site has been {Rbanned{c from this mud.{x"); close_socket(d); return; } if (check_reconnect(d, argument, false)) { fOld = true; } else { if (IsSet(mud_info.mud_flags, MUD_WIZLOCK) && !IsImmortal(ch)) { d_println(d, "{cThe game is {Rwizlocked{c.{x"); close_socket(d); return; } } if (fOld) { d_write(d, echo_off_str, 0); d_println(d, "{cPassword: {x"); d->connected = CON_GET_OLD_PASSWORD; d->wrong_password_count = 0; return; } else { if (IsSet(mud_info.mud_flags, MUD_NEWLOCK)) { d_println(d, "{cThe game is {Rnewlocked{c.{x"); close_socket(d); return; } if (check_ban(d->host, BAN_NEWBIES)) { d_println(d, "{cNew players are not allowed from your site.{x"); close_socket(d); return; } d_printlnf(d, "{cDid I get that right, %s ({WY{c/{WN{c)? {x", capitalize(argument)); d->connected = CON_CONFIRM_NEW_NAME; return; } } Nanny_Fun(HANDLE_CON_GET_OLD_PASSWORD) { CharData *ch = CH(d); if (str_casecmp(crypt(argument, ch->pcdata->pwd), ch->pcdata->pwd)) { d_print(d, "{cWrong password"); if (++d->wrong_password_count < 3) { d_println(d, " - try again."); d_println(d, "{cPassword: {x"); d_println(d, echo_off_str); return; } else { d_println(d, "."); } close_socket(d); return; } d_write(d, echo_on_str, 0); if (check_playing(d, ch->name)) return; if (check_reconnect(d, ch->name, true)) return; new_wiznet(ch, d->host, WIZ_SITES, true, get_trust(ch), "$N@$t has connected."); set_desc_flags(d); if (IsImmortal(ch)) { d_print(d, "{cWould you like to login ({WW{c)izinvis, ({WI{c)ncognito, " "({WB{c)oth, or ({WN{c)ormal?{x" NEWLINE "{c(Include a level number to specify what level){x"); d->connected = CON_GET_WIZ; } else { do_function(ch, &nanny_help, "motd"); d->connected = CON_READ_MOTD; } } Nanny_Fun(HANDLE_CON_GET_WIZ) { CharData *ch = CH(d); char arg[MIL]; int wizlevel = Range(LEVEL_IMMORTAL, ch->level, MAX_LEVEL); argument = one_argument(argument, arg); if (!NullStr(argument) && is_number(argument)) wizlevel = Range(LEVEL_IMMORTAL, atoi(argument), MAX_LEVEL); switch (tolower(*arg)) { case 'w': ch->invis_level = wizlevel; ch->incog_level = 0; break; case 'i': ch->incog_level = wizlevel; ch->invis_level = 0; break; case 'b': ch->incog_level = wizlevel; ch->invis_level = wizlevel; break; default: case 'n': ch->incog_level = 0; ch->invis_level = 0; break; } do_function(ch, &nanny_help, "imotd"); d->connected = CON_READ_MOTD; } Nanny_Fun(HANDLE_CON_BREAK_CONNECT) { CharData *ch = CH(d); Descriptor *d_old, *pd_next; switch (*argument) { case 'y': case 'Y': for (d_old = descriptor_first; d_old != NULL; d_old = pd_next) { pd_next = d_old->next; if (d_old == d || d_old->character == NULL) continue; if (str_cmp(ch->name, CH(d_old)->name)) continue; close_socket(d_old); } if (check_reconnect(d, ch->name, true)) return; d_println(d, "{cReconnect attempt failed.{x" NEWLINE "{cName: "); if (d->character != NULL) { free_char(d->character); d->character = NULL; } d->connected = CON_GET_NAME; break; case 'n': case 'N': d_println(d, "{cName: {x"); if (d->character != NULL) { free_char(d->character); d->character = NULL; } d->connected = CON_GET_NAME; break; default: d_println(d, "{cPlease type ({WY{c)es or ({WN{c)o: {x"); break; } } Nanny_Fun(HANDLE_CON_CONFIRM_NEW_NAME) { CharData *ch = CH(d); switch (*argument) { case 'y': case 'Y': d_printlnf(d, "{cWelcome to {R%s{c!" NEWLINE "{cGive me a password for {W%s{c: {x", mud_info.name, ch->name); d_write(d, echo_off_str, 0); d->connected = CON_GET_NEW_PASSWORD; break; case 'n': case 'N': d_println(d, "{cOk, what IS it, then? {x"); free_char(d->character); d->character = NULL; d->connected = CON_GET_NAME; break; default: d_println(d, "{cPlease type ({WY{c)es or ({WN{c)o: {x"); break; } } Nanny_Fun(HANDLE_CON_GET_NEW_PASSWORD) { CharData *ch = CH(d); const char *pwdnew; const char *p; if (strlen(argument) < 5) { d_println(d, "{cPassword must be at least five characters long." NEWLINE "{cPassword: {x"); return; } pwdnew = crypt(argument, ch->name); for (p = pwdnew; *p != '\0'; p++) { if (*p == '~') { d_println(d, "{cNew password not acceptable, try again." NEWLINE "{cPassword: {x"); return; } } replace_str(&ch->pcdata->pwd, pwdnew); d_println(d, "{cPlease retype password: {x"); d->connected = CON_CONFIRM_NEW_PASSWORD; } void send_race_info(Descriptor * d) { RaceData *race; d_println(d, NEWLINE "{cThe following races are available:{x"); d_printlnf(d, "{W%s{x", draw_line(CH(d), "{w-{W-", 0)); for (race = race_first; race; race = race->next) { if (!race->pc_race) continue; d_printlnf(d, "{c\t%s{x", race->name); } d_printlnf(d, "{W%s", draw_line(CH(d), "{w-{W-", 0)); d_printlnf(d, "{cFor more information, use help. (i.e. 'help %s'){x", race_first->name); } Nanny_Fun(HANDLE_CON_CONFIRM_NEW_PASSWORD) { CharData *ch = CH(d); if (str_casecmp(crypt(argument, ch->pcdata->pwd), ch->pcdata->pwd)) { d_println(d, "{cPasswords don't match.{x" NEWLINE "{cRetype password: {x"); d->connected = CON_GET_NEW_PASSWORD; return; } d_write(d, echo_on_str, 0); send_race_info(d); d_println(d, "{cWhat is your race? {x"); d->connected = CON_GET_NEW_RACE; } Nanny_Fun(HANDLE_CON_GET_NEW_RACE) { CharData *ch = CH(d); char arg[MAX_INPUT_LENGTH]; RaceData *race; int i; one_argument(argument, arg); if (!str_cmp(arg, "help")) { argument = one_argument(argument, arg); if (NullStr(argument)) do_function(ch, &nanny_help, "race help"); else do_function(ch, &nanny_help, argument); d_println(d, NEWLINE "{cWhat is your race (help for more information)? {x"); return; } race = race_lookup(argument); if (race == NULL || !race->pc_race) { d_println(d, "{cThat is not a valid race.{x"); send_race_info(d); return; } if (IsRemort(ch) && ch->race != race) { d_printlnf(d, "{cYou are now a {R%s{c forever.{x", ch->race->name); ch->pcdata->stay_race = true; } ch->race = race; for (i = 0; i < STAT_MAX; i++) ch->perm_stat[i] = race->stats[i]; ch->affected_by = ch->affected_by | race->aff; ch->imm_flags = ch->imm_flags | race->imm; ch->res_flags = ch->res_flags | race->res; ch->vuln_flags = ch->vuln_flags | race->vuln; ch->form = race->form; ch->parts = race->parts; for (i = 0; i < MAX_RACE_SKILL; i++) { if (race->skills[i] == NULL) break; group_add(ch, race->skills[i], false); } ch->pcdata->points = race->points; ch->size = race->size; d_printlnf(d, "{cYou are now a {W%s{c.", race->name); d_println(d, NEWLINE "{cWhat is your sex ({WM{c)ale/({WF{c)emale/({WN{c)eutral? {x"); d->connected = CON_GET_NEW_SEX; } void send_class_info(Descriptor * d) { int iClass; d_println(d, NEWLINE "{cThe following classes are available:{x"); d_printlnf(d, "{W%s{x", draw_line(CH(d), "{w-{W-", 0)); for (iClass = 0; iClass < top_class; iClass++) { if (is_class(d->character, iClass)) continue; d_printlnf(d, "{c\t%s{x", ClassName(d->character, iClass)); } d_printlnf(d, "{W%s{x", draw_line(CH(d), "{w-{W-", 0)); d_printlnf(d, "{cFor more information, use help. (i.e. 'help %s'){x", class_table[0].name[0]); } Nanny_Fun(HANDLE_CON_GET_NEW_SEX) { CharData *ch = CH(d); switch (toupper(argument[0])) { case 'M': d_println(d, "{cYou are now {Wmale{c."); ch->sex = SEX_MALE; ch->pcdata->true_sex = SEX_MALE; break; case 'F': d_println(d, "{cYou are now {Wfemale{c."); ch->sex = SEX_FEMALE; ch->pcdata->true_sex = SEX_FEMALE; break; case 'N': d_println(d, "{cYou are now {Wneutral{c."); ch->sex = SEX_NEUTRAL; ch->pcdata->true_sex = SEX_NEUTRAL; break; default: d_println(d, "{cThat's not a sex.{x" NEWLINE "{cWhat IS your sex? {x"); return; } send_class_info(d); d_printlnf(d, "{cWhat is your %sclass? {x", IsRemort(ch) ? "next " : ""); d->connected = CON_GET_NEW_CLASS; } int roll_a_stat(CharData * ch, int pStat) { int percent, bonus, low, high; if (!ch || !ch->race->pc_race) return number_range(13, 22); percent = number_percent(); if (percent > 99) bonus = 2; else if (percent > 95) bonus = 1; else if (percent < 5) bonus = -1; else if (percent < 1) bonus = -2; else bonus = 0; high = ch->race->max_stats[pStat] - (3 - bonus); low = ch->race->stats[pStat] - (3 - bonus); return number_range(low, high); } void roll_stats(CharData * ch) { int i; for (i = 0; i < STAT_MAX; i++) ch->perm_stat[i] = roll_a_stat(ch, i); } void init_gen_data(Descriptor * d) { int i; CharData *ch = CH(d); ch->gen_data = new_gen_data(); ch->gen_data->points_chosen = ch->pcdata->points; d_println(d, NEWLINE "{cYou may now roll your stats.{x" NEWLINE); roll_stats(ch); for (i = 0; i < STAT_MAX; i++) d_printf(d, "{c%.3s {W%02d {x", capitalize(stat_types[i].name), ch->perm_stat[i]); d_println(d, "{c Keep? ({WY{c/{WN{c) {x"); } Nanny_Fun(HANDLE_CON_GET_NEW_CLASS) { CharData *ch = CH(d); char arg[MIL]; int iClass; one_argument(argument, arg); iClass = class_lookup(arg); if (iClass == -1) { if (!str_cmp(arg, "help")) { argument = one_argument(argument, arg); if (NullStr(argument)) do_function(ch, &nanny_help, "class help"); else do_function(ch, &nanny_help, argument); d_printlnf(d, NEWLINE "{cWhat IS your %sclass? {x", IsRemort(ch) ? "next " : ""); return; } d_println(d, "{cInvalid class.{x"); send_class_info(d); d_printlnf(d, "{cWhat IS your %sclass? {x", IsRemort(ch) ? "next " : ""); return; } if (is_class(ch, iClass)) { d_printlnf(d, "{cYou are already part {W%s{c. Try another!{x", ClassName(ch, iClass)); return; } ch->Class[ch->Class[CLASS_COUNT]] = iClass; ch->Class[CLASS_COUNT] += 1; ch->Class[ch->Class[CLASS_COUNT]] = -1; d_printlnf(d, "{cYou are now a {W%s{c.", class_long(ch)); if (!IsRemort(ch)) { wiznet("Newbie alert! $N sighted.", ch, NULL, WIZ_NEWBIE, false, 0); new_wiznet(ch, d->host, WIZ_SITES, true, get_trust(ch), "$N@$t new player."); mud_info.stats.newbies++; d_println(d, NEWLINE "{cYou may now choose a general alignment of your character.{x"); d_println(d, "{cWhich alignment ({WG{c)ood/({WN{c)eutral/({WE{c)vil? {x"); d->connected = CON_GET_ALIGNMENT; } else { init_gen_data(d); d->connected = CON_ROLL_STATS; } } void send_deity_info(Descriptor * d) { DeityData *i; int e; d_println(d, NEWLINE "{cDeities available for worship:{x"); d_printlnf(d, "{W%s", draw_line(CH(d), "{w-{W-", 0)); for (e = ETHOS_LAWFUL_GOOD; e != ETHOS_CHAOTIC_EVIL; e--) { for (i = deity_first; i; i = i->next) { if (i->ethos != (ethos_t) e) continue; d_printlnf(d, "{c\t%-12s (%s): %s{x", i->name, flag_string(ethos_types, i->ethos), i->desc); } } d_printlnf(d, "{W%s", draw_line(CH(d), "{w-{W-", 0)); d_printlnf(d, "{cFor more information, use help. (i.e. 'help %s'){x", deity_first->name); } Nanny_Fun(HANDLE_CON_GET_ALIGNMENT) { CharData *ch = CH(d); switch (toupper(argument[0])) { case 'G': d_println(d, "{cYou are now {Wgood{c.{x"); ch->alignment = 750; break; case 'N': d_println(d, "{cYou are now {Yneutral{c.{x"); ch->alignment = 0; break; case 'E': d_println(d, "{cYou are now {Revil{c.{x"); ch->alignment = -750; break; default: d_println(d, "{cThat's not a valid alignment.{x"); d_println(d, "{cWhich alignment ({WG{c)ood/({WN{c)eutral/({WE{c)vil? {x"); return; } send_deity_info(d); d_println(d, "{cWhat deity would you like to worship?{x"); d->connected = CON_GET_DEITY; return; } void send_timezone_info(Descriptor * d) { int i; d_println(d, NEWLINE "{cPlease choose a timezone closest to where you live:{x"); d_printlnf(d, "{W%s", draw_line(CH(d), "{w-{W-", 0)); for (i = 0; i < MAX_TZONE; i++) { d_printlnf(d, "{c\t{W%5s{c - %9s - %s{x", tzone_table[i].name, str_time(-1, i, "%I:%M:%S %p"), tzone_table[i].zone); } d_printlnf(d, "{W%s", draw_line(CH(d), "{w-{W-", 0)); d_printlnf(d, "{cFor more information, use help. (i.e. 'help %s'){x", tzone_table[0].name); } Nanny_Fun(HANDLE_CON_GET_DEITY) { char arg[MIL]; DeityData *i; CharData *ch = CH(d); one_argument(argument, arg); if (!str_cmp(arg, "help")) { argument = one_argument(argument, arg); if (NullStr(argument)) { send_deity_info(d); d_println(d, "{cWhat deity would you like to worship? {x"); } else do_function(ch, &do_help, argument); d_println(d, "{cWhat deity would you like to worship? {x"); return; } i = deity_lookup(argument); if (i == NULL) { send_deity_info(d); d_println(d, "{cWhat deity would you like to worship? {x"); return; } ch->deity = i; d_printlnf(d, "{cYou now worship {W%s{c.{x", ch->deity->name); send_timezone_info(d); d_println(d, "{cWhat time zone do you live in? {x"); d->connected = CON_GET_TIMEZONE; return; } Nanny_Fun(HANDLE_CON_GET_TIMEZONE) { int i; char arg[MIL]; CharData *ch = CH(d); one_argument(argument, arg); if (NullStr(arg)) { send_timezone_info(d); d_println(d, "{cWhat time zone do you live in? {x"); return; } if (!str_cmp(arg, "help")) { d_printlnf(d, "{cTime zones around the world are split up into %d areas,", MAX_TZONE); d_printlnf(d, "{ceach relating to Greenwich Mean Time (GMT) which is %s.{x", str_time(-1, tzone_lookup("GMT"), "%I:%M:%S %p")); d_println(d, "{cWhat time zone do you live in? {x"); return; } i = tzone_lookup(argument); if (i == -1) { d_println(d, "{cThat is not a valid time zone, please enter the full time zone name. (ex. GMT-5)"); d_println(d, "{cWhat time zone do you live in? {x"); return; } ch->pcdata->timezone = i; d_printlnf(d, "{cYour time zone is now %s %s (%s) {x", tzone_table[i].zone, tzone_table[i].name, str_time(-1, i, "%I:%M:%S %p")); d_println(d, NULL); d_println(d, "{cWhat is your e-mail address? (Hit return to leave blank){x"); d->connected = CON_GET_EMAIL; } Nanny_Fun(HANDLE_CON_GET_EMAIL) { if (NullStr(argument)) { d_println(d, "{cE-mail not set.{x"); } else { char *valid; CharData *ch = CH(d); if ((valid = is_invalid_email(argument)) != NULL) { d_printlnf(d, "{c%s{x", valid); d_println(d, "{cWhat is your e-mail address?{x"); return; } replace_str(&ch->pcdata->email, argument); d_printlnf(d, "{cE-mail address set to '{W%s{c'.{x", ch->pcdata->email); } d_println(d, NULL); if (IsSet(d->desc_flags, DESC_TELOPT_NAWS)) { init_gen_data(d); d->connected = CON_ROLL_STATS; } else { d_println(d, "{cThis mud makes use of formating text to your screen size, your client does not"); d_println(d, "support auto-negotation so you may now enter a screen size manually. The default"); d_printlnf(d, "screen is %d columns by %d lines.{x" NEWLINE, DEFAULT_SCR_WIDTH, DEFAULT_SCR_HEIGHT); d_println(d, "{cWhat is your screen size? Please answer in the form of 'AA BB' where AA is your screen{x"); d_println(d, "{cwidth and BB is your screen height.{x"); d->connected = CON_GET_SCR_SIZE; } } Nanny_Fun(HANDLE_CON_GET_SCR_SIZE) { int sz; unsigned int i, j; char w[MIL], h[MIL]; CharData *ch = CH(d); if (NullStr(argument)) { d_printlnf(d, "{cDefault screen size of %d by %d used.{x", DEFAULT_SCR_WIDTH, DEFAULT_SCR_HEIGHT); init_gen_data(d); d->connected = CON_ROLL_STATS; return; } argument = one_argument(argument, w); if (!is_number(w) || (sz = atoi(w)) < 10 || sz > 250) { d_println(d, "{cPlease keep your screen width between 10 and 250 columns.{x"); return; } else { d->scr_width = sz; ch->columns = sz; } argument = one_argument(argument, h); if (!NullStr(h)) { if (!is_number(h) || (sz = atoi(h)) < 10 || sz > 100) { d_println(d, "{cPlease keep your screen height between 10 and 100 lines.{x"); return; } else { d->scr_height = sz; ch->lines = sz; } } d_println(d, stringf(ch, 0, Center, "{?-{W=", "{c[ %d Columns by %d Lines ]", d->scr_width, d->scr_height)); for (i = 0; i < d->scr_height; i++) { d_print(d, "{?*"); for (j = 0; j < 6; j++) d_printf(d, "{?%*s", ScrWidth(d) / 6, "*"); d_println(d, NULL); } d_println(d, draw_line(ch, "{`-{W=", 0)); d_println(d, "{cBased on the above page, is your screen size set to your satisfaction? ({WY{c/{WN{c) "); d->connected = CON_CONFIRM_SCR_SIZE; } Nanny_Fun(HANDLE_CON_CONFIRM_SCR_SIZE) { switch (toupper(argument[0])) { case 'Y': d_printlnf(d, "{cScreen size set to {W%d{c columns by {W%d{c lines.{x", d->scr_width, d->scr_height); init_gen_data(d); d->connected = CON_ROLL_STATS; break; case 'N': d_println(d, "{cWhat is your screen size? Please answer in the form of 'AA BB' where AA is your screen{x"); d_println(d, "{cwidth and BB is your screen height.{x"); d->connected = CON_GET_SCR_SIZE; break; default: d_println(d, "{cYes or No?{x"); break; } } Nanny_Fun(HANDLE_CON_ROLL_STATS) { CharData *ch = CH(d); int i; switch (tolower(argument[0])) { case 'y': ch->gen_data->rerolls = 1; group_add(ch, "rom basics", false); add_base_groups(ch); ch->pcdata->learned[gsn_recall] = 50; d_println(d, "{cDo you wish to customize this character?{x"); d_println(d, "{cCustomization takes time, but allows a wider range of skills and abilities.{x"); d_println(d, "{cCustomize ({WY{c/{WN{c)? {x"); d->connected = CON_DEFAULT_CHOICE; break; case 'n': if (ch->gen_data->rerolls >= 10) { d_println(d, NEWLINE "You cannot reroll forever. Your stuck with what you have.{x"); d_println(d, NULL); group_add(ch, "rom basics", false); add_base_groups(ch); ch->pcdata->learned[gsn_recall] = 50; d_println(d, "{cDo you wish to customize this character?{x"); d_println(d, "Customization takes time, but allows a wider range of skills and abilities."); d_println(d, "{cCustomize ({WY{c/{WN{c)? {x"); d->connected = CON_DEFAULT_CHOICE; break; } ch->gen_data->rerolls++; roll_stats(ch); d_printlnf(d, "{cYou have {W%d{c re-rolls remaining.{x", (11 - ch->gen_data->rerolls)); for (i = 0; i < STAT_MAX; i++) d_printf(d, "{c%.3s {W%02d {x", capitalize(stat_types[i].name), ch->perm_stat[i]); d_println(d, "{c Keep? ({WY{c/{WN{c) {x"); break; default: d_println(d, "{cYes or No?{x"); break; } } void send_weapon_info(Descriptor * d) { CharData *ch = CH(d); int i; free_gen_data(ch->gen_data); d_println(d, "{cPlease pick a weapon from the following choices:{x"); for (i = 0; weapon_table[i].name != NULL; i++) if (ch->pcdata->learned[*weapon_table[i].gsn] > 0) d_printlnf(d, "{c\t%s{x", weapon_table[i].name); d_println(d, "{cYour choice? {x"); } Nanny_Fun(HANDLE_CON_DEFAULT_CHOICE) { CharData *ch = CH(d); d_println(d, NULL); switch (toupper(argument[0])) { case 'Y': d_println(d, "{cThe following skills and groups are available to your character:{x"); d_println(d, "{c(this list may be seen again by typing list){x"); list_group_costs(ch); if (!IsRemort(ch)) { d_println(d, "{cYou already have the following skills:{x"); do_function(ch, &do_skills, ""); } d_println(d, NEWLINE "{cChoice? (add, drop, list, learned, info, lookup, help, premise, done){x "); d->connected = CON_GEN_GROUPS; break; case 'N': d_printlnf(d, "{cDefault skill set for %s used.", ClassName(ch, prime_class(ch))); add_default_groups(ch); send_weapon_info(d); d->connected = CON_PICK_WEAPON; break; default: d_println(d, "{cPlease answer ({WY{c/{WN{c)? {x"); return; } } Nanny_Fun(HANDLE_CON_PICK_WEAPON) { CharData *ch = CH(d); int i, weapon; void finish_remort(CharData *); weapon = weapon_lookup(argument); if (weapon == -1 || ch->pcdata->learned[*weapon_table[weapon].gsn] <= 0) { d_println(d, "{cThat's not a valid selection. Choices are:{x"); for (i = 0; weapon_table[i].name != NULL; i++) if (ch->pcdata->learned[*weapon_table[i].gsn] > 0) d_printlnf(d, "{c\t%s{x", weapon_table[i].name); d_println(d, "{cYour choice? {x"); return; } ch->pcdata->learned[*weapon_table[weapon].gsn] = Max(40, ch->pcdata->learned[*weapon_table[weapon].gsn]); if (IsRemort(ch)) { finish_remort(ch); } else { do_function(ch, &nanny_help, "motd"); d->connected = CON_READ_MOTD; } } Nanny_Fun(HANDLE_CON_GEN_GROUPS) { CharData *ch = CH(d); if (!str_cmp(argument, "done")) { if (!IsRemort(ch)) { if (ch->pcdata->points == ch->race->points) { chprintln(ch, "{cYou didn't pick anything.{x"); return; } } ch->pcdata->points = Max(ch->pcdata->points, mud_info.max_points); chprintlnf(ch, "{cCreation points: %d{x", ch->pcdata->points); chprintlnf(ch, "{cExperience per level: %d{x", exp_per_level(ch, ch->gen_data->points_chosen)); send_weapon_info(d); d->connected = CON_PICK_WEAPON; return; } if (!parse_gen_groups(ch, argument)) d_println(d, "{cChoices are: (add, drop, list, learned, info, lookup, help, premise, done){x "); else d_println(d, "{cChoice? (add, drop, list, learned, info, lookup, help, premise, done){x "); } Nanny_Fun(HANDLE_CON_READ_IMOTD) { CharData *ch = CH(d); do_function(ch, &nanny_help, "motd"); d->connected = CON_READ_MOTD; } Nanny_Fun(HANDLE_CON_READ_MOTD) { CharData *ch = CH(d); char buf[MSL]; int i; Proto(int num_changes, (void)); if (ch->pcdata == NULL || NullStr(ch->pcdata->pwd)) { d_println(d, "{WWarning! Null password!{x"); d_println(d, "{WPlease report old password with bug.{x"); d_println(d, "{WType '{Wpassword null <new password>{c' to fix.{x"); } d_printlnf(d, "{cWelcome to {?%s{c, %s.{x", mud_info.name, ch->name); Link(ch, char, next, prev); Link(ch, player, next_player, prev_player); d->connected = CON_PLAYING; reset_char(ch); if (ch->level == 0) { if (ch->Class[0] == -1) ch->Class[0] = 0; ch->perm_stat[class_table[prime_class(ch)].attr_prime] += 3; if (pfiles.count == 0) { int sn; ch->level = MAX_LEVEL; ch->pcdata->perm_hit = ch->max_hit = 50000; ch->pcdata->perm_mana = ch->max_mana = 50000; ch->pcdata->perm_move = ch->max_move = 50000; ch->pcdata->security = 9; ch->trust = MAX_LEVEL; for (sn = 0; sn < top_skill; sn++) { if (get_skill(ch, sn) > 0) ch->pcdata->learned[sn] = 100; } #ifndef DISABLE_I3 ch->pcdata->i3chardata->i3perm = I3PERM_IMP; #endif SetBit(ch->act, PLR_HOLYLIGHT); replace_str(&ch->prompt, IMMORTAL_PROMPT); save_char_obj(ch); realloc_mem(pfiles.names, const char *, pfiles.count + 1); pfiles.names[pfiles.count++] = str_dup(ch->name); } else 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->gold = 10; sprintf(buf, "the %s %s", ch->race->name, ClassName(ch, prime_class(ch))); set_title(ch, buf); if (ch->level >= LEVEL_IMMORTAL) { char_to_room(ch, get_room_index(ROOM_VNUM_CHAT)); chprintlnf(ch, "{RSince you are the first player file on {?%s{R, " "you have been made an {rImplementor{R automatically.", mud_info.name); } else { 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)); chprintln(ch, NULL); do_function(ch, &nanny_help, "newbie info"); } } else if (ch->in_room != NULL) { char_to_room(ch, ch->in_room); } else if (IsImmortal(ch)) { char_to_room(ch, get_room_index(ROOM_VNUM_CHAT)); } else { char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE)); } announce(ch, INFO_LOGIN, "$n has entered the realms."); act("$n has entered the game.", ch, NULL, NULL, TO_ROOM); mud_info.stats.logins++; d_println(d, NULL); do_function(ch, &do_look, "auto"); wiznet("$N has left real life behind.", ch, NULL, WIZ_LOGINS, false, 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); } do_function(ch, &do_backup, "check"); do_function(ch, &do_ncheck, ""); do_function(ch, &do_count, ""); i = num_changes(); if (i > 0) { d_printlnf(d, "{R==> {WThere were {R%s {Wmade to the mud today type {G%s{W to view.{x", intstr(i, "change"), cmd_name(do_changes)); } unfinished_quest(ch); update_explored(ch); checkcorpse(ch); } #define NANNY_CASE(state, fun) \ case state : \ fun (d, argument); \ break void nanny(Descriptor * d, const char *argument) { if (d->connected != CON_NOTE_TEXT) { while (isspace(*argument)) argument++; } switch (d->connected) { default: bugf("Nanny: bad d->connected %d.", d->connected); close_socket(d); return; NANNY_CASE(CON_GET_TERM, HANDLE_CON_GET_TERM); NANNY_CASE(CON_GET_NAME, HANDLE_CON_GET_NAME); NANNY_CASE(CON_GET_OLD_PASSWORD, HANDLE_CON_GET_OLD_PASSWORD); NANNY_CASE(CON_GET_WIZ, HANDLE_CON_GET_WIZ); NANNY_CASE(CON_BREAK_CONNECT, HANDLE_CON_BREAK_CONNECT); NANNY_CASE(CON_CONFIRM_NEW_NAME, HANDLE_CON_CONFIRM_NEW_NAME); NANNY_CASE(CON_GET_NEW_PASSWORD, HANDLE_CON_GET_NEW_PASSWORD); NANNY_CASE(CON_CONFIRM_NEW_PASSWORD, HANDLE_CON_CONFIRM_NEW_PASSWORD); NANNY_CASE(CON_GET_NEW_RACE, HANDLE_CON_GET_NEW_RACE); NANNY_CASE(CON_GET_NEW_SEX, HANDLE_CON_GET_NEW_SEX); NANNY_CASE(CON_GET_NEW_CLASS, HANDLE_CON_GET_NEW_CLASS); NANNY_CASE(CON_GET_ALIGNMENT, HANDLE_CON_GET_ALIGNMENT); NANNY_CASE(CON_GET_DEITY, HANDLE_CON_GET_DEITY); NANNY_CASE(CON_GET_TIMEZONE, HANDLE_CON_GET_TIMEZONE); NANNY_CASE(CON_GET_EMAIL, HANDLE_CON_GET_EMAIL); NANNY_CASE(CON_GET_SCR_SIZE, HANDLE_CON_GET_SCR_SIZE); NANNY_CASE(CON_CONFIRM_SCR_SIZE, HANDLE_CON_CONFIRM_SCR_SIZE); NANNY_CASE(CON_ROLL_STATS, HANDLE_CON_ROLL_STATS); NANNY_CASE(CON_DEFAULT_CHOICE, HANDLE_CON_DEFAULT_CHOICE); NANNY_CASE(CON_PICK_WEAPON, HANDLE_CON_PICK_WEAPON); NANNY_CASE(CON_GEN_GROUPS, HANDLE_CON_GEN_GROUPS); NANNY_CASE(CON_READ_IMOTD, HANDLE_CON_READ_IMOTD); NANNY_CASE(CON_NOTE_TO, HANDLE_CON_NOTE_TO); NANNY_CASE(CON_NOTE_SUBJECT, HANDLE_CON_NOTE_SUBJECT); NANNY_CASE(CON_NOTE_EXPIRE, HANDLE_CON_NOTE_EXPIRE); NANNY_CASE(CON_NOTE_TEXT, HANDLE_CON_NOTE_TEXT); NANNY_CASE(CON_NOTE_FINISH, HANDLE_CON_NOTE_FINISH); NANNY_CASE(CON_READ_MOTD, HANDLE_CON_READ_MOTD); } return; }