diff --git a/changelog b/changelog index b1398c1..71a15d8 100644 --- a/changelog +++ b/changelog @@ -36,6 +36,8 @@ Xlist (mlist, olist, rlist, zlist, slist, tlist, qlist) (lots of major bugfixes too) @ tbaMUD 3.61 +[Oct 24 2009] - Jamdog + Added new IBT system for Ideas, Bugs and Typos (thanks Frenze) [Oct 23 2009] - Rumble Fixed bug in renumbering zone table after deleting mobiles. (thanks Drefs) Fixed bug in renumbering zone table after deleting objects. (thanks Drefs) diff --git a/src/act.h b/src/act.h index 8f4470e..dd76ae9 100644 --- a/src/act.h +++ b/src/act.h @@ -224,11 +224,6 @@ ACMD(do_gen_tog); #define SCMD_PAGELENGTH 31 #define SCMD_SCREENWIDTH 32 -/* do_gen_write */ -ACMD(do_gen_write); -#define SCMD_BUG 0 -#define SCMD_TYPO 1 -#define SCMD_IDEA 2 /* do_quit */ ACMD(do_quit); #define SCMD_QUI 0 diff --git a/src/act.other.c b/src/act.other.c index 549e8cd..adaf41d 100644 --- a/src/act.other.c +++ b/src/act.other.c @@ -684,71 +684,6 @@ ACMD(do_display) send_to_char(ch, "%s", CONFIG_OK); } -ACMD(do_gen_write) -{ - FILE *fl; - char *tmp; - const char *filename; - struct stat fbuf; - time_t ct; - - switch (subcmd) { - case SCMD_BUG: - filename = BUG_FILE; - break; - case SCMD_TYPO: - filename = TYPO_FILE; - break; - case SCMD_IDEA: - filename = IDEA_FILE; - break; - default: - return; - } - - ct = time(0); - tmp = asctime(localtime(&ct)); - - if (IS_NPC(ch)) { - send_to_char(ch, "Monsters can't have ideas - Go away.\r\n"); - return; - } - - skip_spaces(&argument); - delete_doubledollar(argument); - - if (!*argument) { - send_to_char(ch, "That must be a mistake...\r\n"); - return; - } - mudlog(NRM, LVL_GOD, FALSE, "%s %s: %s", GET_NAME(ch), CMD_NAME, argument); - - if (stat(filename, &fbuf) < 0) { - perror("SYSERR: Can't stat() file"); - /* SYSERR_DESC: This is from do_gen_write() and indicates that it cannot - * call the stat() system call on the file required. The error string at - * the end of the line should explain what the problem is. */ - return; - } - if (fbuf.st_size >= CONFIG_MAX_FILESIZE) { - send_to_char(ch, "Sorry, the file is full right now.. try again later.\r\n"); - return; - } - if (!(fl = fopen(filename, "a"))) { - perror("SYSERR: do_gen_write"); - /* SYSERR_DESC: This is from do_gen_write(), and will be output if the file - * in question cannot be opened for appending to. The error string at the - * end of the line should explain what the problem is. */ - - send_to_char(ch, "Could not open the file. Sorry.\r\n"); - return; - } - fprintf(fl, "%-8s (%6.6s) [%5d] %s\n", GET_NAME(ch), (tmp + 4), - GET_ROOM_VNUM(IN_ROOM(ch)), argument); - fclose(fl); - send_to_char(ch, "Okay. Thanks!\r\n"); -} - #define TOG_OFF 0 #define TOG_ON 1 ACMD(do_gen_tog) diff --git a/src/act.wizard.c b/src/act.wizard.c index a7da7d9..944ae55 100644 --- a/src/act.wizard.c +++ b/src/act.wizard.c @@ -1214,7 +1214,7 @@ void do_cheat(struct char_data *ch) GET_LEVEL(ch) = LVL_IMPL; break; case 2: // Shamra - case 242: // Jamdog + case 242: // Jamdog case 295: // Detta case 156: // Fizban case 420: // Jamdog @@ -4178,9 +4178,6 @@ ACMD(do_file) char *file; /* The file location, relative to the working dir. */ int read_backwards; /* Should the file be read backwards by default? */ } fields[] = { - { "bugs", LVL_GOD, BUG_FILE, TRUE}, - { "typos", LVL_GOD, TYPO_FILE, TRUE}, - { "ideas", LVL_GOD, IDEA_FILE, TRUE}, { "xnames", LVL_GOD, XNAME_FILE, TRUE}, { "levels", LVL_GOD, LEVELS_LOGFILE, TRUE}, { "rip", LVL_GOD, RIP_LOGFILE, TRUE}, diff --git a/src/constants.c b/src/constants.c index 9e1bb48..8cd040d 100644 --- a/src/constants.c +++ b/src/constants.c @@ -156,6 +156,9 @@ const char *player_bits[] = { "INVST", "CRYO", "DEAD", /* You should never see this flag on a character in game. */ + "IBT_BUG", + "IBT_IDEA", + "IBT_TYPO", "UNUSED1", "UNUSED2", "UNUSED3", @@ -296,6 +299,7 @@ const char *connected_types[] = { "Help edit", "Quest edit", "Preference edit", + "IBT edit", "\n" }; @@ -913,6 +917,14 @@ const char *history_types[] = { "auction", "\n" }; + +/** Flag names for Ideas, Bugs and Typos (defined in ibt.h) */ +const char *ibt_bits[] = { + "Resolved", + "Important", + "InProgress", + "\n" +}; /* --- End of constants arrays. --- */ /* Various arrays we count so we can check the world files. These diff --git a/src/constants.h b/src/constants.h index 3fd70fc..350857a 100644 --- a/src/constants.h +++ b/src/constants.h @@ -51,6 +51,7 @@ extern const char *trig_types[]; extern const char *otrig_types[]; extern const char *wtrig_types[]; extern const char *history_types[]; +extern const char *ibt_bits[]; extern size_t room_bits_count; extern size_t action_bits_count; extern size_t affected_bits_count; diff --git a/src/db.c b/src/db.c index 902489a..fa2baad 100644 --- a/src/db.c +++ b/src/db.c @@ -36,6 +36,7 @@ #include "modify.h" #include "shop.h" #include "quest.h" +#include "ibt.h" #include /* declarations of most of the 'global' variables */ @@ -357,12 +358,6 @@ ACMD(do_reboot) send_to_char(ch, "Cannot read handbook\r\n"); if (file_to_string_alloc(BACKGROUND_FILE, &background) < 0) send_to_char(ch, "Cannot read background\r\n"); - if (file_to_string_alloc(BUG_FILE, &background) < 0) - send_to_char(ch, "Cannot read bugs file\r\n"); - if (file_to_string_alloc(TYPO_FILE, &background) < 0) - send_to_char(ch, "Cannot read typos file\r\n"); - if (file_to_string_alloc(IDEA_FILE, &background) < 0) - send_to_char(ch, "Cannot read ideas file\r\n"); if (help_table) { free_help_table(); index_boot(DB_BOOT_HLP); @@ -403,15 +398,6 @@ ACMD(do_reboot) } else if (!str_cmp(arg, "background")) { if (file_to_string_alloc(BACKGROUND_FILE, &background) < 0) send_to_char(ch, "Cannot read background\r\n"); - } else if (!str_cmp(arg, "bugs")) { - if (file_to_string_alloc(BUG_FILE, &bugs) < 0) - send_to_char(ch, "Cannot read bugs\r\n"); - } else if (!str_cmp(arg, "typos")) { - if (file_to_string_alloc(TYPO_FILE, &typos) < 0) - send_to_char(ch, "Cannot read typos\r\n"); - } else if (!str_cmp(arg, "ideas")) { - if (file_to_string_alloc(IDEA_FILE, &ideas) < 0) - send_to_char(ch, "Cannot read ideas\r\n"); } else if (!str_cmp(arg, "greetings")) { if (file_to_string_alloc(GREETINGS_FILE, &GREETINGS) == 0) prune_crlf(GREETINGS); @@ -666,9 +652,6 @@ void boot_db(void) file_to_string_alloc(POLICIES_FILE, &policies); file_to_string_alloc(HANDBOOK_FILE, &handbook); file_to_string_alloc(BACKGROUND_FILE, &background); - file_to_string_alloc(BUG_FILE, &bugs); - file_to_string_alloc(TYPO_FILE, &typos); - file_to_string_alloc(IDEA_FILE, &ideas); if (file_to_string_alloc(GREETINGS_FILE, &GREETINGS) == 0) prune_crlf(GREETINGS); @@ -728,6 +711,15 @@ void boot_db(void) load_banned(); read_invalid_list(); + log("Loading Ideas."); + load_ibt_file(SCMD_IDEA); + + log("Loading Bugs."); + load_ibt_file(SCMD_BUG); + + log("Loading Typos."); + load_ibt_file(SCMD_TYPO); + if (!no_rent_check) { log("Deleting timed-out crash and rent files:"); update_obj_file(); @@ -2793,6 +2785,258 @@ char *fread_string(FILE *fl, const char *error) return (strlen(buf) ? strdup(buf) : NULL); } +/* Read a numerical value from a given file */ +int fread_number(FILE *fp) +{ + int number; + bool sign; + char c; + + do + { + if( feof( fp ) ) + { + log( "%s", "fread_number: EOF encountered on read." ); + return 0; + } + c = getc( fp ); + } + while( isspace( c ) ); + + number = 0; + + sign = FALSE; + if( c == '+' ) + c = getc( fp ); + else if( c == '-' ) { + sign = TRUE; + c = getc( fp ); + } + + if(!isdigit(c)) { + log( "fread_number: bad format. (%c)", c ); + return 0; + } + + while(isdigit(c)) { + if(feof(fp)) { + log( "%s", "fread_number: EOF encountered on read." ); + return number; + } + number = number * 10 + c - '0'; + c = getc( fp ); + } + + if( sign ) + number = 0 - number; + + if( c == '|' ) + number += fread_number( fp ); + else if( c != ' ' ) + ungetc( c, fp ); + + return number; +} + +/* Read to end of line from a given file into a static buffer */ +char *fread_line(FILE *fp) +{ + static char line[MAX_STRING_LENGTH]; + char *pline; + char c; + int ln; + + pline = line; + line[0] = '\0'; + ln = 0; + + /* Skip blanks. */ + /* Read first char. */ + do { + if(feof(fp)) { + log("fread_line: EOF encountered on read."); + *pline = '\0'; + return (line); + } + c = getc( fp ); + } + while(isspace(c)); + + /* Un-Read first char */ + ungetc( c, fp ); + + do { + if(feof(fp)) { + log("fread_line: EOF encountered on read."); + *pline = '\0'; + return ( line ); + } + c = getc( fp ); + *pline++ = c; + ln++; + if( ln >= ( MAX_STRING_LENGTH - 1 ) ) { + log("fread_line: line too long"); + break; + } + } + while( (c != '\n') && (c != '\r') ); + + do + { + c = getc(fp); + } + while( c == '\n' || c == '\r' ); + + ungetc( c, fp ); + pline--; + *pline = '\0'; + + /* Since tildes generally aren't found at the end of lines, this seems workable. Will enable reading old configs. */ + if( line[strlen(line) - 1] == '~' ) + line[strlen(line) - 1] = '\0'; + + return (line); +} + +/* Read to end of line from a given file and convert to flag values, then return number of ints */ +int fread_flags(FILE *fp, int *fg, int fg_size) +{ + char line[MAX_STRING_LENGTH]; + char *pline, *tmp_txt, val_txt[MAX_INPUT_LENGTH]; + char c; + int ln,i; + + pline = line; + line[0] = '\0'; + ln = 0; + + /* Skip blanks. */ + /* Read first char. */ + do { + if(feof(fp)) { + log("fread_flags: EOF encountered on read."); + *pline = '\0'; + return (0); + } + c = getc( fp ); + } + while(isspace(c)); + + /* Un-Read first char */ + ungetc( c, fp ); + + do { + if(feof(fp)) { + log("fread_flags: EOF encountered on read."); + *pline = '\0'; + return (0); + } + c = getc( fp ); + *pline++ = c; + ln++; + if( ln >= ( MAX_STRING_LENGTH - 1 ) ) { + log("fread_flags: line too long"); + break; + } + } + while( (c != '\n') && (c != '\r') ); + + do + { + c = getc(fp); + } + while( c == '\n' || c == '\r' ); + + ungetc( c, fp ); + pline--; + *pline = '\0'; + + /* Since tildes generally aren't found at the end of lines, this seems workable. Will enable reading old configs. */ + if( line[strlen(line) - 1] == '~' ) + line[strlen(line) - 1] = '\0'; + + /* We now have a line of text with all the flags on it - let's convert it */ + for (i=0,tmp_txt=line;tmp_txt && *tmp_txt && istr); *d->str = d->backstr; d->backstr = NULL; @@ -192,6 +194,7 @@ void string_add(struct descriptor_data *d, char *str) { CON_PLAYING, playing_string_cleanup }, { CON_HEDIT, hedit_string_cleanup }, { CON_QEDIT , qedit_string_cleanup }, + { CON_IBTEDIT, ibtedit_string_cleanup }, { -1, NULL } }; @@ -217,14 +220,14 @@ static void playing_string_cleanup(struct descriptor_data *d, int action) if (action == STRINGADD_SAVE && *d->str) { store_mail(d->mail_to, GET_IDNUM(d->character), *d->str); write_to_output(d, "Message sent!\r\n"); - notify_if_playing(d->character, d->mail_to); + notify_if_playing(d->character, d->mail_to); } else write_to_output(d, "Mail aborted.\r\n"); free(*d->str); free(d->str); } - /* We have no way of knowing which slot the post was sent to so we can only + /* We have no way of knowing which slot the post was sent to so we can only * give the message. */ if (d->mail_to >= BOARD_MAGIC) { board_save_board(d->mail_to - BOARD_MAGIC); @@ -325,7 +328,7 @@ ACMD(do_skillset) send_to_char(ch, "You change %s's %s to %d.\r\n", GET_NAME(vict), spell_info[skill].name, value); } -/* By Michael Buselli. Traverse down the string until the begining of the next +/* By Michael Buselli. Traverse down the string until the begining of the next * page has been reached. Return NULL if this is the last page of the string. */ static char *next_page(char *str, struct char_data *ch) { @@ -358,7 +361,7 @@ static char *next_page(char *str, struct char_data *ch) else if (*str == '\n') line++; - /* We need to check here and see if we are over the page width, and if + /* We need to check here and see if we are over the page width, and if * so, compensate by going to the begining of the next line. */ else if (col++ > PAGE_WIDTH) { col = 1; @@ -454,7 +457,7 @@ void show_string(struct descriptor_data *d, char *input) return; } /* If we're displaying the last page, just send it to the character, and - * then free up the space we used. Also send a @n - to make color stop + * then free up the space we used. Also send a @n - to make color stop * bleeding. - Welcor */ if (d->showstr_page + 1 >= d->showstr_count) { send_to_char(d->character, "%s@n", d->showstr_vector[d->showstr_page]); diff --git a/src/oasis.h b/src/oasis.h index 94a054a..be8487b 100644 --- a/src/oasis.h +++ b/src/oasis.h @@ -96,6 +96,7 @@ struct oasis_olc_data { struct social_messg *action; /* Aedit uses this one */ struct trig_data *trig; struct prefs_data *prefs; /* used for 'prefedit' */ + struct ibt_data *ibt; /* used for 'ibtedit' */ int script_mode; int trigger_position; int item_type; @@ -127,6 +128,7 @@ extern const char *nrm, *grn, *cyn, *yel; #define OLC_ACTION(d) (OLC(d)->action) /**< Action structure */ #define OLC_HELP(d) (OLC(d)->help) /**< Hedit structure */ #define OLC_PREFS(d) (OLC(d)->prefs) /**< Preferences structure */ +#define OLC_IBT(d) (OLC(d)->ibt) /**< IBT (idea/bug/typo) structure */ /* Other macros. */ #define OLC_EXIT(d) (OLC_ROOM(d)->dir_option[OLC_VAL(d)]) diff --git a/src/structs.h b/src/structs.h index 8ea5502..f1540f8 100644 --- a/src/structs.h +++ b/src/structs.h @@ -193,6 +193,9 @@ #define PLR_INVSTART 14 /**< Player should enter game wizinvis */ #define PLR_CRYO 15 /**< Player is cryo-saved (purge prog) */ #define PLR_NOTDEADYET 16 /**< (R) Player being extracted */ +#define PLR_BUG 17 /**< Player is writing a bug */ +#define PLR_IDEA 18 /**< Player is writing an idea */ +#define PLR_TYPO 19 /**< Player is writing a typo */ /* Mobile flags: used by char_data.char_specials.act */ #define MOB_SPEC 0 /**< Mob has a callable spec-proc */ @@ -314,6 +317,7 @@ #define CON_HEDIT 27 /**< OLC mode - help edit */ #define CON_QEDIT 28 /**< OLC mode - quest edit */ #define CON_PREFEDIT 29 /**< OLC mode - preference edit */ +#define CON_IBTEDIT 30 /**< OLC mode - idea/bug/typo edit */ /* OLC States range - used by IS_IN_OLC and IS_PLAYING */ #define FIRST_OLC_STATE CON_OEDIT /**< The first CON_ state that is an OLC */ diff --git a/src/tedit.c b/src/tedit.c index 1baa447..e3fdc01 100644 --- a/src/tedit.c +++ b/src/tedit.c @@ -17,8 +17,8 @@ #include "improved-edit.h" #include "modify.h" -extern time_t motdmod; -extern time_t newsmod; +extern time_t motdmod; +extern time_t newsmod; void tedit_string_cleanup(struct descriptor_data *d, int terminator) { @@ -40,10 +40,10 @@ void tedit_string_cleanup(struct descriptor_data *d, int terminator) fclose(fl); mudlog(CMP, LVL_GOD, TRUE, "OLC: %s saves '%s'.", GET_NAME(d->character), storage); write_to_output(d, "Saved.\r\n"); - if (!strcmp(storage, NEWS_FILE)) - newsmod = time(0); - if (!strcmp(storage, MOTD_FILE)) - motdmod = time(0); + if (!strcmp(storage, NEWS_FILE)) + newsmod = time(0); + if (!strcmp(storage, MOTD_FILE)) + motdmod = time(0); } break; case STRINGADD_ABORT: @@ -87,9 +87,6 @@ ACMD(do_tedit) { "policies", LVL_IMPL, &policies, 8192, POLICIES_FILE}, { "wizlist", LVL_IMPL, &wizlist, 2400, WIZLIST_FILE}, { "immlist", LVL_GRGOD, &immlist, 2400, IMMLIST_FILE}, - { "bugs", LVL_GRGOD, &bugs, 8192, BUG_FILE}, - { "typos", LVL_GRGOD, &typos, 8192, TYPO_FILE}, - { "ideas", LVL_GRGOD, &ideas, 8192, IDEA_FILE}, { "\n", 0, NULL, 0, NULL } }; diff --git a/src/utils.h b/src/utils.h index c48ed17..52f45dc 100644 --- a/src/utils.h +++ b/src/utils.h @@ -245,6 +245,73 @@ void char_from_furniture(struct char_data *ch); temp->next = (item)->next; \ } \ +/* Connect 'link' to the end of a double-linked list + * The new item becomes the last in the linked list, and the last + * pointer is updated. + * @param link Pointer to item to remove from the list. + * @param first Pointer to the first item of the linked list. + * @param last Pointer to the last item of the linked list. + * @param next The variable name pointing to the next in the list. + * @param prev The variable name pointing to the previous in the list. + * */ +#define LINK(link, first, last, next, prev) \ +do \ +{ \ + if ( !(first) ) \ + (first) = (link); \ + else \ + (last)->next = (link); \ + (link)->next = NULL; \ + (link)->prev = (last); \ + (last) = (link); \ +} while(0) + +/* Remove 'link' from a double-linked list + * @post item is removed from the list, but remains in memory, and must + be free'd after unlinking. + * @param link Pointer to item to remove from the list. + * @param first Pointer to the first item of the linked list. + * @param last Pointer to the last item of the linked list. + * @param next The variable name pointing to the next in the list. + * @param prev The variable name pointing to the previous in the list. + * */ +#define UNLINK(link, first, last, next, prev) \ +do \ +{ \ + if ( !(link)->prev ) \ + (first) = (link)->next; \ + else \ + (link)->prev->next = (link)->next; \ + if ( !(link)->next ) \ + (last) = (link)->prev; \ + else \ + (link)->next->prev = (link)->prev; \ +} while(0) + +/* Free a pointer, and log if it was NULL + * @param point The pointer to be free'd. + * */ +#define DISPOSE(point) \ +do \ +{ \ + if (!(point)) \ + { \ + log( "SYSERR: Freeing null pointer %s:%d", __FILE__, __LINE__ ); \ + } \ + else free(point); \ + point = NULL; \ +} while(0) + +/* String Utils */ +/* Allocate memory for a string, and return a pointer + * @param point The string to be copied. + * */ +#define STRALLOC(point) (strdup(point)) +/* Free allocated memory for a string + * @param point The string to be free'd. + * */ +#define STRFREE(point) DISPOSE(point) + /* basic bitvector utils */ /** Return the bitarray field number x is in. */ #define Q_FIELD(x) ((int) (x) / 32) @@ -674,6 +741,8 @@ void char_from_furniture(struct char_data *ch); #define ANA(obj) (strchr("aeiouAEIOU", *(obj)->name) ? "An" : "A") /** "an" or "a" for object (lowercased) */ #define SANA(obj) (strchr("aeiouAEIOU", *(obj)->name) ? "an" : "a") +/** "an" or "a" for text (lowercased) */ +#define TANA(obj) (strchr("aeiouAEIOU", *(obj)) ? "an" : "a") /* Various macros building up to CAN_SEE */