/* SillyMUD Distribution V1.1b (c) 1993 SillyMUD Developement See license.doc for distribution terms. SillyMUD is based on DIKUMUD */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <time.h> #include "protos.h" #define REBOOT_AT 10 /* 0-23, time of optional reboot if -e lib/reboot */ #define TP_MOB 0 #define TP_OBJ 1 #define TP_ERROR 2 struct room_data *world; /* dyn alloc'ed array of rooms */ char *string_fields[] = { "name", "short", "long", "description", "title", "delete-description", "delnoise", "delfarnoise", "\n" }; char *room_fields[] = { "name", /* 1 */ "desc", "fs", "exit", "exdsc", /* 5 */ "extra", /* 6 */ "riv", /* 7 */ "tele", /* 8 */ "tunn", /* 9 */ "\n" }; /* maximum length for text field x+1 */ int length[] = { 15, 60, 256, 240, 60, }; int room_length[] = { 80, 1024, 50, 50, 512, 512, 50, 100, 50 }; char *skill_fields[] = { "learned", "affected", "duration", "recognize", "\n" }; int max_value[] = { 255, 255, 10000, 1 }; /* ************************************************************************ * modification of malloc'ed strings * ************************************************************************ */ /* Add user input to the 'current' string (as defined by d->str) */ void string_add(struct descriptor_data *d, char *str) { char *scan; int terminator = 0; /* determine if this is the terminal string, and truncate if so */ for (scan = str; *scan; scan++) if (terminator = (*scan == '@')) { *scan = '\0'; break; } if (!(*d->str)) { if (strlen(str) > d->max_str) { send_to_char("String too long - Truncated.\n\r", d->character); *(str + d->max_str) = '\0'; terminator = 1; } CREATE(*d->str, char, strlen(str) + 3); strcpy(*d->str, str); } else { if (strlen(str) + strlen(*d->str) > d->max_str) { send_to_char("String too long. Last line skipped.\n\r", d->character); terminator = 1; } else { if (!(*d->str = (char *) realloc(*d->str, strlen(*d->str) + strlen(str) + 3))) { perror("string_add"); assert(0); } strcat(*d->str, str); } } if (terminator) { d->str = 0; if (d->connected == CON_EXDSCR) { SEND_TO_Q(MENU, d); d->connected = CON_SLCT; } } else strcat(*d->str, "\n\r"); } #undef MAX_STR /* interpret an argument for do_string */ void quad_arg(char *arg, int *type, char *name, int *field, char *string) { char buf[MAX_STRING_LENGTH]; /* determine type */ arg = one_argument(arg, buf); if (is_abbrev(buf, "char")) *type = TP_MOB; else if (is_abbrev(buf, "obj")) *type = TP_OBJ; else { *type = TP_ERROR; return; } /* find name */ arg = one_argument(arg, name); /* field name and number */ arg = one_argument(arg, buf); if (!(*field = old_search_block(buf, 0, strlen(buf), string_fields, 0))) return; /* string */ for (; isspace(*arg); arg++); for (; *string = *arg; arg++, string++); return; } /* modification of malloc'ed strings in chars/objects */ void do_string(struct char_data *ch, char *arg, int cmd) { char name[MAX_STRING_LENGTH], string[MAX_STRING_LENGTH]; struct extra_descr_data *ed, *tmp; int field, type; struct char_data *mob; struct obj_data *obj; if (IS_NPC(ch)) return; quad_arg(arg, &type, name, &field, string); if (type == TP_ERROR) { send_to_char( "Syntax:\n\rstring ('obj'|'char') <name> <field> [<string>].", ch); return; } if (!field) { send_to_char("No field by that name. Try 'help string'.\n\r", ch); return; } if (type == TP_MOB) { /* locate the beast */ if (!(mob = get_char_vis(ch, name))) { send_to_char("I don't know anyone by that name...\n\r", ch); return; } switch(field) { case 1: if (!IS_NPC(mob) && GetMaxLevel(ch) < IMPLEMENTOR) { send_to_char("You can't change that field for players.", ch); return; } if (!*string) { send_to_char("You have to supply a name!\n\r", ch); return; } ch->desc->str = &mob->player.name; if (!IS_NPC(mob)) send_to_char("WARNING: You have changed the name of a player.\n\r", ch); break; case 2: if (!IS_NPC(mob)) { send_to_char("That field is for monsters only.\n\r", ch); return; } if (!*string) { send_to_char("You have to supply a description!\n\r", ch); return; } ch->desc->str = &mob->player.short_descr; break; case 3: if (!IS_NPC(mob)){ send_to_char("That field is for monsters only.\n\r", ch); return; } ch->desc->str = &mob->player.long_descr; break; case 4:ch->desc->str = &mob->player.description; break; case 5: if (IS_NPC(mob)) { send_to_char("Monsters have no titles.\n\r",ch); return; } if ((GetMaxLevel(ch) >= GetMaxLevel(mob)) && (ch != mob)) ch->desc->str = &mob->player.title; else { send_to_char("Sorry, can't set the title of someone of higher level.\n\r", ch); return; } break; case 7: if (mob->player.sounds) { free(mob->player.sounds); mob->player.sounds = 0; } return; break; case 8: if (mob->player.distant_snds) { free(mob->player.distant_snds); mob->player.distant_snds = 0; } return; break; default: send_to_char("That field is undefined for monsters.\n\r", ch); return; break; } } else { /* type == TP_OBJ */ /* locate the object */ if (!(obj = get_obj_vis(ch, name))) { send_to_char("Can't find such a thing here..\n\r", ch); return; } switch(field) { case 1: if (!*string) { send_to_char("You have to supply a keyword.\n\r", ch); return; } else { ch->desc->str = &obj->name; break; } break; case 2: if (!*string) { send_to_char("You have to supply a keyword.\n\r", ch); return; } else { ch->desc->str = &obj->short_description; break; } case 3: ch->desc->str = &obj->description; break; case 4: if (!*string) { send_to_char("You have to supply a keyword.\n\r", ch); return; } /* try to locate extra description */ for (ed = obj->ex_description; ; ed = ed->next) if (!ed) { CREATE(ed , struct extra_descr_data, 1); ed->next = obj->ex_description; obj->ex_description = ed; CREATE(ed->keyword, char, strlen(string) + 1); strcpy(ed->keyword, string); ed->description = 0; ch->desc->str = &ed->description; send_to_char("New field.\n\r", ch); break; } else if (!str_cmp(ed->keyword, string)) /* the field exists */ { free(ed->description); ed->description = 0; ch->desc->str = &ed->description; send_to_char( "Modifying description.\n\r", ch); break; } ch->desc->max_str = MAX_STRING_LENGTH; return; /* the stndrd (see below) procedure does not apply here */ break; case 6: /* deletion */ if (!*string) { send_to_char("You must supply a field name.\n\r", ch); return; } /* try to locate field */ for (ed = obj->ex_description; ; ed = ed->next) if (!ed) { send_to_char("No field with that keyword.\n\r", ch); return; } else if (!str_cmp(ed->keyword, string)) { free(ed->keyword); if (ed->description) free(ed->description); /* delete the entry in the desr list */ if (ed == obj->ex_description) obj->ex_description = ed->next; else { for(tmp = obj->ex_description; tmp->next != ed; tmp = tmp->next); tmp->next = ed->next; } free(ed); send_to_char("Field deleted.\n\r", ch); return; } break; default: send_to_char( "That field is undefined for objects.\n\r", ch); return; break; } } if (*ch->desc->str) { free(*ch->desc->str); } if (*string) { /* there was a string in the argument array */ if (strlen(string) > length[field - 1]) { send_to_char("String too long - truncated.\n\r", ch); *(string + length[field - 1]) = '\0'; } CREATE(*ch->desc->str, char, strlen(string) + 1); strcpy(*ch->desc->str, string); ch->desc->str = 0; send_to_char("Ok.\n\r", ch); } else { /* there was no string. enter string mode */ send_to_char("Enter string. terminate with '@'.\n\r", ch); *ch->desc->str = 0; ch->desc->max_str = length[field - 1]; } } void bisect_arg(char *arg, int *field, char *string) { char buf[MAX_INPUT_LENGTH]; /* field name and number */ arg = one_argument(arg, buf); if (!(*field = old_search_block(buf, 0, strlen(buf), room_fields, 0))) return; /* string */ for (; isspace(*arg); arg++); for (; *string = *arg; arg++, string++); return; } void do_edit(struct char_data *ch, char *arg, int cmd) { int field, dflags, dir, exroom, dkey, rspeed, rdir, tele_room, tele_time, tele_mask, moblim, tele_cnt; unsigned r_flags; int s_type; char name[MAX_INPUT_LENGTH], string[512], buf[132]; struct extra_descr_data *ed, *tmp; struct room_data *rp; rp = real_roomp(ch->in_room); if ((IS_NPC(ch)) || (GetMaxLevel(ch)<LOW_IMMORTAL)) return; if (!ch->desc) /* someone is forced to do something. can be bad! */ return; /* the ch->desc->str field will cause problems... */ #ifndef TEST_SERVER if((GetMaxLevel(ch) < 55) && (rp->zone != GET_ZONE(ch))) { send_to_char("Sorry, you are not authorized to edit this zone.\n\r", ch); return; } #endif bisect_arg(arg, &field, string); if (!field) { send_to_char("No field by that name. Try 'help edit'.\n\r", ch); return; } r_flags = -1; s_type = -1; switch(field) { case 1: ch->desc->str = &rp->name; break; case 2: ch->desc->str = &rp->description; break; case 3: sscanf(string,"%u %d ",&r_flags,&s_type); if ((r_flags < 0) || (s_type < 0) || (s_type > 11)) { send_to_char("didn't quite get those, please try again.\n\r",ch); send_to_char("flags must be 0 or positive, and sectors must be from 0 to 11\n\r",ch); send_to_char("edit fs <flags> <sector_type>\n\r",ch); return; } rp->room_flags = r_flags; rp->sector_type = s_type; if (rp->sector_type == SECT_WATER_NOSWIM) { send_to_char("P.S. you need to do speed and flow\n\r",ch); send_to_char("For this river. (set to 0 as default)\n\r",ch); rp->river_speed = 0; rp->river_dir = 0; return; } return; break; case 4: sscanf(string,"%d %d %d %d ", &dir, &dflags, &dkey, &exroom); /* check if the exit exists */ if ((dir < 0) || (dir > 5)) { send_to_char("You need to use numbers for that (0 - 5)",ch); return; } if (rp->dir_option[dir]) { send_to_char("modifying exit.\n\r",ch); switch(dflags) { case 1: rp->dir_option[dir]->exit_info = EX_ISDOOR; break; case 2: rp->dir_option[dir]->exit_info = EX_ISDOOR | EX_PICKPROOF; break; case 3: rp->dir_option[dir]->exit_info = EX_CLIMB; break; case 4: rp->dir_option[dir]->exit_info = EX_CLIMB | EX_ISDOOR; break; case 5: rp->dir_option[dir]->exit_info = EX_CLIMB | EX_ISDOOR | EX_PICKPROOF; break; default: rp->dir_option[dir]->exit_info = 0; } rp->dir_option[dir]->key = dkey; if (real_roomp(exroom) != NULL) { rp->dir_option[dir]->to_room = exroom; } else { send_to_char("Deleting exit.\n\r",ch); free(rp->dir_option[dir]); rp->dir_option[dir] = 0; return; } } else if (real_roomp(exroom)==NULL) { send_to_char("Hey, John Yaya, that's not a valid room.\n\r", ch); return; } else { send_to_char("New exit\n\r",ch); CREATE(rp->dir_option[dir], struct room_direction_data, 1); switch(dflags) { case 1: rp->dir_option[dir]->exit_info = EX_ISDOOR; break; case 2: rp->dir_option[dir]->exit_info = EX_ISDOOR | EX_PICKPROOF; break; case 3: rp->dir_option[dir]->exit_info = EX_CLIMB; break; case 4: rp->dir_option[dir]->exit_info = EX_CLIMB | EX_ISDOOR; break; case 5: rp->dir_option[dir]->exit_info = EX_CLIMB | EX_ISDOOR | EX_PICKPROOF; break; default: rp->dir_option[dir]->exit_info = 0; } rp->dir_option[dir]->key = dkey; rp->dir_option[dir]->to_room = exroom; } if (rp->dir_option[dir]->exit_info>0) { string[0] = 0; send_to_char("enter keywords, 1 line only. \n\r",ch); send_to_char("terminate with an @ on the same line.\n\r",ch); ch->desc->str = &rp->dir_option[dir]->keyword; break; } else { return; } case 5: dir = -1; sscanf(string,"%d", &dir); if ((dir >=0) && (dir <= 5)) { send_to_char("Enter text, term. with '@' on a blank line",ch); string[0] = 0; if (rp->dir_option[dir]) { ch->desc->str = &rp->dir_option[dir]->general_description; } else { CREATE(rp->dir_option[dir], struct room_direction_data, 1); ch->desc->str = &rp->dir_option[dir]->general_description; } } else { send_to_char("Illegal direction\n\r",ch); send_to_char("Must enter 0-5.I will ask for text.\n\r",ch); return; } break; case 6: /* extra descriptions */ if (!*string) { send_to_char("You have to supply a keyword.\n\r", ch); return; } /* try to locate extra description */ for (ed = rp->ex_description; ; ed = ed->next) if (!ed) { CREATE(ed , struct extra_descr_data, 1); ed->next = rp->ex_description; rp->ex_description = ed; CREATE(ed->keyword, char, strlen(string) + 1); strcpy(ed->keyword, string); ed->description = 0; ch->desc->str = &ed->description; send_to_char("New field.\n\r", ch); break; } else if (!str_cmp(ed->keyword, string)) { /* the field exists */ free(ed->description); ed->description = 0; ch->desc->str = &ed->description; send_to_char( "Modifying description.\n\r", ch); break; } ch->desc->max_str = MAX_STRING_LENGTH; return; break; case 7: /* this is where the river stuff will go */ rspeed = 0; rdir = 0; sscanf(string,"%d %d ",&rspeed,&rdir); if ((rdir>= 0) && (rdir <= 5)) { rp->river_speed = rspeed; rp->river_dir = rdir; } else { send_to_char("Illegal dir. : edit riv <speed> <dir>\n\r",ch); } return; case 8: /* this is where the teleport stuff will go */ tele_room = -1; tele_time = -1; tele_mask = -1; sscanf(string,"%d %d %d",&tele_time,&tele_room,&tele_mask); if (tele_room < 0 || tele_time < 0 || tele_mask < 0) { send_to_char(" edit tele <time> <room_nr> <tele-flags>\n\r", ch); return; break; } else { if (IS_SET(TELE_COUNT, tele_mask)) { sscanf(string,"%d %d %d %d", &tele_time, &tele_room, &tele_mask, &tele_cnt); if (tele_cnt < 0) { send_to_char (" edit tele <time> <room_nr> <tele-flags> [tele-count]\n\r", ch); return; } else { real_roomp(ch->in_room)->tele_time = tele_time; real_roomp(ch->in_room)->tele_targ = tele_room; real_roomp(ch->in_room)->tele_mask = tele_mask; real_roomp(ch->in_room)->tele_cnt = tele_cnt; } } else { real_roomp(ch->in_room)->tele_time = tele_time; real_roomp(ch->in_room)->tele_targ = tele_room; real_roomp(ch->in_room)->tele_mask = tele_mask; real_roomp(ch->in_room)->tele_cnt = 0; return; } } return; case 9: if (sscanf(string, "%d", &moblim) < 1) { send_to_char("edit tunn <mob_limit>\n\r", ch); return; break; } else { real_roomp(ch->in_room)->moblim = moblim; if (!IS_SET(real_roomp(ch->in_room)->room_flags, TUNNEL)) SET_BIT(real_roomp(ch->in_room)->room_flags, TUNNEL); return; break; } case 10: /* deletion */ if (!*string) { send_to_char("You must supply a field name.\n\r", ch); return; } /* try to locate field */ for (ed = rp->ex_description; ; ed = ed->next) if (!ed) { send_to_char("No field with that keyword.\n\r", ch); return; } else if (!str_cmp(ed->keyword, string)) { free(ed->keyword); if (ed->description) free(ed->description); /* delete the entry in the desr list */ if (ed == rp->ex_description) rp->ex_description = ed->next; else { for(tmp = rp->ex_description; tmp->next != ed; tmp = tmp->next); tmp->next = ed->next; } free(ed); send_to_char("Field deleted.\n\r", ch); return; } break; default: send_to_char("I'm so confused :-)\n\r",ch); return; break; } if (*ch->desc->str) { free(*ch->desc->str); } if (*string) { /* there was a string in the argument array */ if (strlen(string) > room_length[field - 1]) { send_to_char("String too long - truncated.\n\r", ch); *(string + length[field - 1]) = '\0'; } CREATE(*ch->desc->str, char, strlen(string) + 1); strcpy(*ch->desc->str, string); ch->desc->str = 0; send_to_char("Ok.\n\r", ch); } else { /* there was no string. enter string mode */ send_to_char("Enter string. terminate with '@'.\n\r", ch); *ch->desc->str = 0; ch->desc->max_str = room_length[field - 1]; } } /* ********************************************************************** * Modification of character skills * ********************************************************************** */ void do_setskill(struct char_data *ch, char *arg, int cmd) { send_to_char("This routine is disabled untill it fitts\n\r", ch); send_to_char("The new structures (sorry Quinn) ....Bombman\n\r", ch); return; } /* db stuff *********************************************** */ /* One_Word is like one_argument, execpt that words in quotes "" are */ /* regarded as ONE word */ char *one_word(char *argument, char *first_arg ) { int begin, look_at; begin = 0; do { for ( ;isspace(*(argument + begin)); begin++); if (*(argument+begin) == '\"') { /* is it a quote */ begin++; for (look_at=0; (*(argument+begin+look_at) >= ' ') && (*(argument+begin+look_at) != '\"') ; look_at++) *(first_arg + look_at) = LOWER(*(argument + begin + look_at)); if (*(argument+begin+look_at) == '\"') begin++; } else { for (look_at=0; *(argument+begin+look_at) > ' ' ; look_at++) *(first_arg + look_at) = LOWER(*(argument + begin + look_at)); } *(first_arg + look_at) = '\0'; begin += look_at; } while (fill_word(first_arg)); return(argument+begin); } struct help_index_element *build_help_index(FILE *fl, int *num) { int nr = -1, issorted, i; struct help_index_element *list = 0, mem; char buf[81], tmp[81], *scan; long pos; for (;;) { pos = ftell(fl); fgets(buf, 81, fl); *(buf + strlen(buf) - 1) = '\0'; scan = buf; for (;;) { /* extract the keywords */ scan = one_word(scan, tmp); if (!*tmp) break; if (!list) { CREATE(list, struct help_index_element, 1); nr = 0; } else { RECREATE(list, struct help_index_element, ++nr+1); } list[nr].pos = pos; CREATE(list[nr].keyword, char, strlen(tmp) + 1); strcpy(list[nr].keyword, tmp); } /* skip the text */ do fgets(buf, 81, fl); while (*buf != '#'); if (*(buf + 1) == '~') break; } /* we might as well sort the stuff */ do { issorted = 1; for (i = 0; i < nr; i++) if (str_cmp(list[i].keyword, list[i + 1].keyword) > 0) { mem = list[i]; list[i] = list[i + 1]; list[i + 1] = mem; issorted = 0; } } while (!issorted); *num = nr; return(list); } void page_string(struct descriptor_data *d, char *str, int keep_internal) { if (!d) return; if (keep_internal) { CREATE(d->showstr_head, char, strlen(str) + 1); strcpy(d->showstr_head, str); d->showstr_point = d->showstr_head; } else d->showstr_point = str; show_string(d, ""); } void show_string(struct descriptor_data *d, char *input) { char buffer[MAX_STRING_LENGTH], buf[MAX_INPUT_LENGTH]; register char *scan, *chk; int lines = 0, toggle = 1; int i; one_argument(input, buf); if (*buf) { if (d->showstr_head){ free(d->showstr_head); d->showstr_head = 0; } d->showstr_point = 0; return; } if(d->character->term == 0) i = 22; else i = d->character->size - 7; /* show a chunk */ for (scan = buffer;; scan++, d->showstr_point++) { if((((*scan = *d->showstr_point) == '\n') || (*scan == '\r')) && ((toggle = -toggle) < 0)) lines++; else if (!*scan || (lines >= i)) { *scan = '\0'; SEND_TO_Q(buffer, d); /* see if this is the end (or near the end) of the string */ for (chk = d->showstr_point; isspace(*chk); chk++); if (!*chk) { if (d->showstr_head) { free(d->showstr_head); d->showstr_head = 0; } d->showstr_point = 0; } return; } } } void night_watchman() { long tc; struct tm *t_info; extern int mudshutdown; void send_to_all(char *messg); tc = time(0); t_info = localtime(&tc); if ((t_info->tm_hour == 8) && (t_info->tm_wday > 0) && (t_info->tm_wday < 6)) if (t_info->tm_min > 50) { log("Leaving the scene for the serious folks."); send_to_all("Closing down. Thank you for flying DikuMUD.\n\r"); mudshutdown = 1; } else if (t_info->tm_min > 40) send_to_all("ATTENTION: DikuMUD will shut down in 10 minutes.\n\r"); else if (t_info->tm_min > 30) send_to_all("Warning: The game will close in 20 minutes.\n\r"); } void check_reboot() { long tc; struct tm *t_info; char dummy; FILE *boot; extern int mudshutdown, reboot; tc = time(0); t_info = localtime(&tc); if ((t_info->tm_hour + 1) == REBOOT_AT && t_info->tm_min > 30) if (boot = fopen("./reboot", "r")) { if (t_info->tm_min > 50) { log("Reboot exists."); fread(&dummy, sizeof(dummy), 1, boot); if (!feof(boot)) /* the file is nonepty */ { log("Reboot is nonempty."); if (system("./reboot")) { log("Reboot script terminated abnormally"); send_to_all("The reboot was cancelled.\n\r"); system("mv ./reboot reboot.FAILED"); fclose(boot); return; } else system("mv ./reboot reboot.SUCCEEDED"); } send_to_all("Automatic reboot. Come back in a little while.\n\r"); mudshutdown = reboot = 1; } else if (t_info->tm_min > 40) send_to_all("ATTENTION: DikuMUD will reboot in 10 minutes.\n\r"); else if (t_info->tm_min > 30) send_to_all( "Warning: The game will close and reboot in 20 minutes.\n\r"); fclose(boot); } } #if 0 int workhours() { long tc; struct tm *t_info; tc = time(0); t_info = localtime(&tc); return((t_info->tm_wday > 0) && (t_info->tm_wday < 6) && (t_info->tm_hour >= 9) && (t_info->tm_hour < 17)); } /* * This procedure is *heavily* system dependent. If your system is not set up * properly for this particular way of reading the system load (It's weird all * right - but I couldn't think of anything better), change it, or don't use -l. * It shouldn't be necessary to use -l anyhow. It's oppressive and unchristian * to harness man's desire to play. Who needs a friggin' degree, anyhow? */ int load() { struct syslinfo { char sl_date[12]; /* "Tue Sep 16\0" */ char sl_time[8]; /* "11:10\0" */ char sl_load1[6]; /* "12.0\0" */ char sl_load2[10]; /* "+2.3 14u\0" */ } info; FILE *fl; int i, sum; static int previous[5]; static int p_point = -1; extern int slow_death; if (!(fl = fopen("/tmp/.sysline", "r"))) { perror("sysline. (dying)"); slow_death = 1; return(-1); } if (!fread(&info, sizeof(info), 1, fl)) { perror("fread sysline (dying)"); slow_death = 1; return(-1); } fclose(fl); if (p_point < 0) { previous[0] = atoi(info.sl_load1); for (i = 1; i< 5; i++) previous[i] = previous[0]; p_point = 1; return(previous[0]); } else { /* put new figure in table */ previous[p_point] = atoi(info.sl_load1); if (++p_point > 4) p_point = 0; for (i = 0, sum = 0; i < 5; i++) sum += previous[i]; return((int) sum / 5); } } char *nogames() { static char text[200]; FILE *fl; if (fl = fopen("lib/nogames", "r")) { log("/usr/games/nogames exists"); fgets(text, fl); return(text); fclose(fl); } else return(0); } /* emulate the game regulator */ void gr(int s) { char *txt = 0, buf[1024]; int ld = 0; static char *warnings[3] = { "If things don't look better within 3 minutes, the game will pause.\n\r", "The game will close temporarily 2 minutes from now.\n\r", "WARNING: The game will close in 1 minute.\n\r" }; static int wnr = 0; extern int slow_death, mudshutdown; void send_to_all(char *messg); void coma(int s); if (((ld = load()) >= 6) || (txt = nogames()) || slow_death) { if (ld >= 6) { sprintf(buf, "The system load is greater than 6.0 (%d)\n\r", ld); send_to_all(buf); } else if (slow_death) send_to_all("The game is dying.\n\r"); else { strcpy(buf, "Game playing is no longer permitted on this machine:\n\r"); strcat(buf, txt); strcat(buf, "\n\r"); send_to_all(buf); } if (wnr < 3) send_to_all(warnings[wnr++]); else if (ld >= 6) { coma(s); wnr = 0; } else mudshutdown = 1; } else if (workhours()) mudshutdown = 1; /* this shouldn't happen */ else if (wnr) { send_to_all("Things look brighter now - you can continue playing.\n\r"); wnr = 0; } } #endif