From f5ce466ea20743ecabec3fdd1832f8c7b56dc00b Mon Sep 17 00:00:00 2001 From: Rumble Date: Wed, 17 Jan 2007 01:41:47 +0000 Subject: [PATCH] Made do_toggle appreciate abbreviations, and made sure a toggle is done automatically on such options (on/off) which can handle this. Cleanup of house.c and objsave.c - now, when loading objects from a rentfile (either house- or crashfile), the items are loaded into a temporary list of type obj_save_data. This stores location data for the autoequip function, and makes it a lot easier to handle listrent. Another bonus us that one only has to change load code in one spot. (this spot is called objsave_parse_objects(), and simply takes a FILE pointer as argument) Added "hcontrol show [room]" option to show items saved to a specific house file. (used the old House_listrent() code) Welcor --- lib/etc/hcontrol | Bin 0 -> 100 bytes lib/world/wld/306.wld | 2780 +++++++++++++++++++++-------------------- src/act.informative.c | 13 +- src/db.h | 8 + src/house.c | 92 +- src/objsave.c | 594 ++++----- 6 files changed, 1780 insertions(+), 1707 deletions(-) diff --git a/lib/etc/hcontrol b/lib/etc/hcontrol index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a7ba87505fd89df1e889db77a39c4b2c4d6ad201 100644 GIT binary patch literal 100 zcmcane!ZNDfq`L-=UP`F#lQ$6kifp1Yz}W8{ok(u6zhBbfB%jL|My#ka&a60(jaBC bz1F&d GET_LEVEL(ch)) { @@ -2024,15 +2025,17 @@ ACMD(do_toggle) break; default: if (!*arg2) { - send_to_char(ch, "Value must either be 'on' or 'off'.\r\n"); - return; + TOGGLE_BIT(PRF_FLAGS(ch), tog_messages[toggle].toggle); + result = (PRF_FLAGGED(ch, tog_messages[toggle].toggle)); +// send_to_char(ch, "Value must either be 'on' or 'off'.\r\n"); +// return; } else if (!strcmp(arg2, "on")) { SET_BIT(PRF_FLAGS(ch), tog_messages[toggle].toggle); result = 1; } else if (!strcmp(arg2, "off")) { REMOVE_BIT(PRF_FLAGS(ch), tog_messages[toggle].toggle); } else { - send_to_char(ch, "Value must either be 'on' or 'off'.\r\n"); + send_to_char(ch, "Value for %s must either be 'on' or 'off'.\r\n", tog_messages[toggle].command); return; } } diff --git a/src/db.h b/src/db.h index a6ef478..2798a30 100644 --- a/src/db.h +++ b/src/db.h @@ -266,6 +266,14 @@ struct ban_list_element { struct ban_list_element *next; }; +/* for the "buffered" rent and house object loading */ +struct obj_save_data_t { + struct obj_data *obj; + int locate; + struct obj_save_data_t *next; +}; +typedef struct obj_save_data_t obj_save_data; + /* global buffering system */ diff --git a/src/house.c b/src/house.c index 0671ae8..b1c13f7 100644 --- a/src/house.c +++ b/src/house.c @@ -21,8 +21,8 @@ #include "constants.h" /* external functions */ -struct obj_data *Obj_from_store(struct obj_file_elem object, int *location); -int Obj_to_store(struct obj_data *obj, FILE *fl, int location); +obj_save_data *objsave_parse_objects(FILE *fl); +int objsave_save_obj_record(struct obj_data *obj, FILE *fl, int location); /* local globals */ struct house_control_rec house_control[MAX_HOUSES]; @@ -36,7 +36,7 @@ void House_restore_weight(struct obj_data *obj); void House_delete_file(room_vnum vnum); int find_house(room_vnum vnum); void House_save_control(void); -void hcontrol_list_houses(struct char_data *ch); +void hcontrol_list_houses(struct char_data *ch, char *arg); void hcontrol_build_house(struct char_data *ch, char *arg); void hcontrol_destroy_house(struct char_data *ch, char *arg); void hcontrol_pay_house(struct char_data *ch, char *arg); @@ -63,9 +63,8 @@ int House_load(room_vnum vnum) { FILE *fl; char filename[MAX_STRING_LENGTH]; - struct obj_file_elem object; + obj_save_data *loaded, *current; room_rnum rnum; - int i; if ((rnum = real_room(vnum)) == NOWHERE) return (0); @@ -73,16 +72,20 @@ int House_load(room_vnum vnum) return (0); if (!(fl = fopen(filename, "r+b"))) /* no file found */ return (0); - while (!feof(fl)) { - fread(&object, sizeof(struct obj_file_elem), 1, fl); - if (ferror(fl)) { - perror("SYSERR: Reading house file in House_load"); - fclose(fl); - return (0); - } - if (!feof(fl)) - obj_to_room(Obj_from_store(object, &i), rnum); - } + + loaded = objsave_parse_objects(fl); + + for (current = loaded; current != NULL; current = current->next) + obj_to_room(current->obj, rnum); + + /* now it's safe to free the obj_save_data list - all members of it + * have been put in the correct lists by obj_to_room() + */ + while (loaded != NULL) { + current = loaded; + loaded = loaded->next; + free(current); + } fclose(fl); @@ -100,7 +103,7 @@ int House_save(struct obj_data *obj, FILE *fp) if (obj) { House_save(obj->contains, fp); House_save(obj->next_content, fp); - result = Obj_to_store(obj, fp, 0); + result = objsave_save_obj_record(obj, fp, 0); if (!result) return (0); @@ -173,9 +176,8 @@ void House_listrent(struct char_data *ch, room_vnum vnum) FILE *fl; char filename[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; - struct obj_file_elem object; - struct obj_data *obj; - int i; + obj_save_data *loaded, *current; + int len = 0; if (!House_get_filename(vnum, filename, sizeof(filename))) return; @@ -184,17 +186,25 @@ void House_listrent(struct char_data *ch, room_vnum vnum) return; } *buf = '\0'; - while (!feof(fl)) { - fread(&object, sizeof(struct obj_file_elem), 1, fl); - if (ferror(fl)) { - fclose(fl); - return; - } - if (!feof(fl) && (obj = Obj_from_store(object, &i)) != NULL) { - send_to_char(ch, " [%5d] (%5dau) %s\r\n", GET_OBJ_VNUM(obj), GET_OBJ_RENT(obj), obj->short_description); - free_obj(obj); - } - } + len = snprintf(buf, sizeof(buf), "filename: %s\r\n", filename); + + loaded = objsave_parse_objects(fl); + + for (current = loaded; current != NULL; current = current->next) + len += snprintf(buf+len, sizeof(buf)-len, " [%5d] (%5dau) %s\r\n", + GET_OBJ_VNUM(current->obj), GET_OBJ_RENT(current->obj), current->obj->short_description); + + /* now it's safe to free the obj_save_data list - all members of it + * have been put in the correct lists by obj_to_room() + */ + while (loaded != NULL) { + current = loaded; + loaded = loaded->next; + extract_obj(current->obj); + free(current); + } + + page_string(ch->desc,buf,0); fclose(fl); } @@ -294,14 +304,30 @@ const char *HCONTROL_FORMAT = "Usage: hcontrol build \r\n" " hcontrol destroy \r\n" " hcontrol pay \r\n" -" hcontrol show\r\n"; +" hcontrol show [house vnum | .]\r\n"; -void hcontrol_list_houses(struct char_data *ch) +void hcontrol_list_houses(struct char_data *ch, char *arg) { int i; char *timestr, *temp; char built_on[128], last_pay[128], own_name[MAX_NAME_LENGTH + 1]; + if (arg && *arg) { + room_vnum toshow; + + if (*arg == '.') + toshow = GET_ROOM_VNUM(IN_ROOM(ch)); + else + toshow = atoi(arg); + + if ((i = find_house(toshow)) == NOWHERE) { + send_to_char(ch, "Unknown house, \"%s\".\r\n", arg); + return; + } + House_listrent(ch, toshow); + return; + } + if (!num_of_houses) { send_to_char(ch, "No houses have been defined.\r\n"); return; @@ -502,7 +528,7 @@ ACMD(do_hcontrol) else if (is_abbrev(arg1, "pay")) hcontrol_pay_house(ch, arg2); else if (is_abbrev(arg1, "show")) - hcontrol_list_houses(ch); + hcontrol_list_houses(ch, arg2); else send_to_char(ch, "%s", HCONTROL_FORMAT); } diff --git a/src/objsave.c b/src/objsave.c index 2325711..baeedec 100644 --- a/src/objsave.c +++ b/src/objsave.c @@ -50,9 +50,7 @@ int Crash_offer_rent(struct char_data *ch, struct char_data *receptionist, int d int Crash_report_unrentables(struct char_data *ch, struct char_data *recep, struct obj_data *obj); void Crash_report_rent(struct char_data *ch, struct char_data *recep, struct obj_data *obj, long *cost, long *nitems, int display, int factor); struct obj_data *Obj_from_store(struct obj_file_elem object, int *location); -int Obj_to_store(struct obj_data *obj, FILE *fl, int location); void update_obj_file(void); -int Crash_write_rentcode(struct char_data *ch, FILE *fl, struct rent_info *rent); int gen_receptionist(struct char_data *ch, struct char_data *recep, int cmd, char *arg, int mode); int Crash_save(struct obj_data *obj, FILE *fp, int location); void Crash_rent_deadline(struct char_data *ch, struct char_data *recep, long cost); @@ -68,54 +66,11 @@ int Crash_load_objs(struct char_data *ch); void tag_argument(char *argument, char *tag); void strip_string(char *buffer); int handle_obj(struct obj_data *obj, struct char_data *ch, int locate, struct obj_data **cont_rows); +obj_save_data *objsave_parse_objects(FILE *fl); +int objsave_write_rentcode(FILE *fl, int rentcode, int cost_per_day, struct char_data *ch); +int objsave_save_obj_record(struct obj_data *obj, FILE *fl, int location); -/* - * The following function is pulled from my genolc.c file. - * Feel free to use any similar function - */ - -/* Change BITSIZE to 1LL for bitvector_t of long long*/ -#ifdef BITSIZE -#undef BITSIZE -#endif - -#define BITSIZE 1 - -#ifdef BITSET -#undef BITSET -#endif - -#define BITSET(bit_pattern, bit) (bit_pattern & (BITSIZE << bit)) - -struct obj_data *Obj_from_store(struct obj_file_elem object, int *location) -{ - struct obj_data *obj; - int j; - - *location = 0; - if (real_object(object.item_number) != NOTHING) { - obj = read_object(object.item_number, VIRTUAL); -#if USE_AUTOEQ - *location = object.location; -#endif - GET_OBJ_VAL(obj, 0) = object.value[0]; - GET_OBJ_VAL(obj, 1) = object.value[1]; - GET_OBJ_VAL(obj, 2) = object.value[2]; - GET_OBJ_VAL(obj, 3) = object.value[3]; - GET_OBJ_EXTRA(obj) = object.extra_flags; - GET_OBJ_WEIGHT(obj) = object.weight; - GET_OBJ_TIMER(obj) = object.timer; - obj->obj_flags.bitvector = object.bitvector; - - for (j = 0; j < MAX_OBJ_AFFECT; j++) - obj->affected[j] = object.affected[j]; - - return (obj); - } else - return (NULL); -} - -/* This procedure removes the '\r\n' from a string so that it may be +/* This procedure turns the '\r\n' into '\n' in a string so that it may be saved to a file. Use it only on buffers, not on the orginal strings. */ void strip_string(char *buffer) @@ -133,7 +88,11 @@ void strip_string(char *buffer) } } -int Obj_to_store(struct obj_data *obj, FILE *fp, int locate) +/* + * Writes one object record to FILE. + * Old name: Obj_to_store() +*/ +int objsave_save_obj_record(struct obj_data *obj, FILE *fp, int locate) { int counter2; struct extra_descr_data *ex_desc; @@ -352,19 +311,18 @@ void auto_equip(struct char_data *ch, struct obj_data *obj, int location) obj_to_char(obj, ch); } - int Crash_delete_file(char *name) { - char filename[50]; + char filename[MAX_INPUT_LENGTH]; FILE *fl; if (!get_filename(filename, sizeof(filename), CRASH_FILE, name)) - return (0); + return FALSE; if (!(fl = fopen(filename, "r"))) { if (errno != ENOENT) /* if it fails but NOT because of no file */ log("SYSERR: deleting crash file %s (1): %s", filename, strerror(errno)); - return (0); + return FALSE; } fclose(fl); @@ -372,7 +330,7 @@ int Crash_delete_file(char *name) if (remove(filename) < 0 && errno != ENOENT) log("SYSERR: deleting crash file %s (2): %s", filename, strerror(errno)); - return (1); + return TRUE; } @@ -381,61 +339,63 @@ int Crash_delete_crashfile(struct char_data *ch) char fname[MAX_INPUT_LENGTH]; int numread; FILE *fl; - int rentcode,timed,netcost,gold,account,nitems; - char line[MAX_INPUT_LENGTH]; + int rentcode; + char line[READ_SIZE]; if (!get_filename(fname, sizeof(fname), CRASH_FILE, GET_NAME(ch))) - return (0); + return FALSE; if (!(fl = fopen(fname, "r"))) { if (errno != ENOENT) /* if it fails, NOT because of no file */ log("SYSERR: checking for crash file %s (3): %s", fname, strerror(errno)); - return (0); + return FALSE; } numread = get_line(fl,line); fclose(fl); + if (numread == FALSE) - return (0); - sscanf(line,"%d %d %d %d %d %d",&rentcode,&timed,&netcost,&gold, - &account,&nitems); + return FALSE; + sscanf(line,"%d ",&rentcode); if (rentcode == RENT_CRASH) Crash_delete_file(GET_NAME(ch)); - return (1); + return TRUE; } int Crash_clean_file(char *name) { - char fname[MAX_STRING_LENGTH], filetype[20]; + char fname[MAX_INPUT_LENGTH], filetype[20]; int numread; FILE *fl; int rentcode, timed, netcost, gold, account, nitems; - char line[MAX_STRING_LENGTH]; + char line[READ_SIZE]; if (!get_filename(fname, sizeof(fname), CRASH_FILE, name)) - return (0); + return FALSE; /* * open for write so that permission problems will be flagged now, at boot * time. */ - if (!(fl = fopen(fname, "r"))) { + if (!(fl = fopen(fname, "rw"))) { if (errno != ENOENT) /* if it fails, NOT because of no file */ log("SYSERR: OPENING OBJECT FILE %s (4): %s", fname, strerror(errno)); - return (0); + return FALSE; } numread = get_line(fl,line); fclose(fl); if (numread == FALSE) - return (0); + return FALSE; + sscanf(line, "%d %d %d %d %d %d",&rentcode,&timed,&netcost, &gold,&account,&nitems); if ((rentcode == RENT_CRASH) || - (rentcode == RENT_FORCED) || (rentcode == RENT_TIMEDOUT)) { + (rentcode == RENT_FORCED) || + (rentcode == RENT_TIMEDOUT) ) { if (timed < time(0) - (crash_file_timeout * SECS_PER_REAL_DAY)) { Crash_delete_file(name); switch (rentcode) { @@ -453,16 +413,16 @@ int Crash_clean_file(char *name) break; } log(" Deleting %s's %s file.", name, filetype); - return (1); + return TRUE; } /* Must retrieve rented items w/in 30 days */ } else if (rentcode == RENT_RENTED) if (timed < time(0) - (rent_file_timeout * SECS_PER_REAL_DAY)) { Crash_delete_file(name); log(" Deleting %s's rent file.", name); - return (1); + return TRUE; } - return (0); + return FALSE; } @@ -479,13 +439,9 @@ void update_obj_file(void) void Crash_listrent(struct char_data *ch, char *name) { FILE *fl; - char fname[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH]; - /* struct obj_file_elem object; */ - struct obj_data *obj; - int rentcode,timed,netcost,gold,account,nitems; - int nr; - char line[MAX_STRING_LENGTH]; - int numread; + char fname[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH], line[READ_SIZE]; + obj_save_data *loaded, *current; + int rentcode,timed,netcost,gold,account,nitems, numread, len; if (!get_filename(fname, sizeof(fname), CRASH_FILE, name)) return; @@ -494,7 +450,7 @@ void Crash_listrent(struct char_data *ch, char *name) send_to_char(ch, "%s has no rent file.\r\n", name); return; } - sprintf(buf, "%s\r\n", fname); + len = snprintf(buf, sizeof(buf),"%s\r\n", fname); numread = get_line(fl, line); @@ -505,63 +461,50 @@ void Crash_listrent(struct char_data *ch, char *name) return; } - sscanf(line,"%d %d %d %d %d %d",&rentcode,&timed,&netcost, - &gold,&account,&nitems); + sscanf(line,"%d %d %d %d %d %d", + &rentcode,&timed,&netcost,&gold,&account,&nitems); switch (rentcode) { case RENT_RENTED: - strcat(buf, "Rent\r\n"); + len += snprintf(buf+len, sizeof(buf)-len, "Rent\r\n"); break; case RENT_CRASH: - strcat(buf, "Crash\r\n"); + len += snprintf(buf+len, sizeof(buf)-len,"Crash\r\n"); break; case RENT_CRYO: - strcat(buf, "Cryo\r\n"); + len += snprintf(buf+len, sizeof(buf)-len, "Cryo\r\n"); break; case RENT_TIMEDOUT: case RENT_FORCED: - strcat(buf, "TimedOut\r\n"); + len += snprintf(buf+len, sizeof(buf)-len, "TimedOut\r\n"); break; default: - strcat(buf, "Undef\r\n"); + len += snprintf(buf+len, sizeof(buf)-len, "Undef\r\n"); break; } - while(get_line(fl, line)) { - if(*line == '#') { /* swell - its an item */ - sscanf(line,"#%d",&nr); - if(nr != NOTHING) { /* then we can dispense with it easily */ - obj=read_object(nr,VIRTUAL); - if (!obj) - continue; - sprintf(buf,"%s[%5d] (%5dau) %-20s\r\n",buf, - nr, GET_OBJ_RENT(obj), - obj->short_description); - extract_obj(obj); - } else { /* its nothing, and a unique item. bleh. partial parse.*/ - /* Policy states that all NOTHING objs should be rent 0 */ - } - } - } + loaded = objsave_parse_objects(fl); + + for (current = loaded; current != NULL; current=current->next) + len += snprintf(buf+len, sizeof(buf)-len, "[%5d] (%5dau) %-20s\r\n", + GET_OBJ_VNUM(current->obj), + GET_OBJ_RENT(current->obj), + current->obj->short_description); + + /* + * now it's safe to free the obj_save_data list and the objects on it. + */ + while (loaded != NULL) { + current = loaded; + loaded = loaded->next; + extract_obj(current->obj); + free(current); + } page_string(ch->desc,buf,0); fclose(fl); } - -int Crash_write_rentcode(struct char_data *ch, FILE *fl, struct rent_info *rent) -{ - - if(fprintf(fl,"%d %d %d %d %d %d\r\n",rent->rentcode, rent->time, - rent->net_cost_per_diem,rent->gold,rent->account,rent->nitems) < 1) { - perror("Syserr: Writing rent code"); - return (0); - } - - return (1); -} - - /* * Return values: * 0 - successful load, keep char in rent room. @@ -584,13 +527,13 @@ int Crash_save(struct obj_data *obj, FILE *fp, int location) Crash_save(obj->next_content, fp, location); Crash_save(obj->contains, fp, MIN(0, location) - 1); - result = Obj_to_store(obj, fp, location); + result = objsave_save_obj_record(obj, fp, location); for (tmp = obj->in_obj; tmp; tmp = tmp->in_obj) GET_OBJ_WEIGHT(tmp) -= GET_OBJ_WEIGHT(obj); if (!result) - return (0); + return FALSE; } return (TRUE); } @@ -638,17 +581,17 @@ void Crash_extract_objs(struct obj_data *obj) int Crash_is_unrentable(struct obj_data *obj) { if (!obj) - return (0); + return FALSE; if (OBJ_FLAGGED(obj, ITEM_NORENT) || GET_OBJ_RENT(obj) < 0 || GET_OBJ_RNUM(obj) == NOTHING || GET_OBJ_TYPE(obj) == ITEM_KEY) { log("Crash_is_unrentable: removing object %s", obj->short_description); - return (1); + return TRUE; } - return (0); + return FALSE; } @@ -689,7 +632,6 @@ void Crash_calculate_rent(struct obj_data *obj, int *cost) void Crash_crashsave(struct char_data *ch) { char buf[MAX_INPUT_LENGTH]; - struct rent_info rent; int j; FILE *fp; @@ -702,10 +644,8 @@ void Crash_crashsave(struct char_data *ch) if (!(fp = fopen(buf, "w"))) return; - rent.rentcode = RENT_CRASH; - rent.time = time(0); - - fprintf(fp,"%d %d 0 0 0 0\r\n",rent.rentcode,rent.time); + if (!objsave_write_rentcode(fp, RENT_CRASH, 0, ch)) + return; for (j = 0; j < NUM_WEARS; j++) if (GET_EQ(ch, j)) { @@ -731,7 +671,6 @@ void Crash_crashsave(struct char_data *ch) void Crash_idlesave(struct char_data *ch) { char buf[MAX_INPUT_LENGTH]; - struct rent_info rent; int j; int cost, cost_eq; FILE *fp; @@ -779,15 +718,9 @@ void Crash_idlesave(struct char_data *ch) return; } } - rent.net_cost_per_diem = cost; - rent.rentcode = RENT_TIMEDOUT; - rent.time = time(0); - rent.gold = GET_GOLD(ch); - rent.account = GET_BANK_GOLD(ch); - - fprintf(fp,"%d %d %d %d %d 0\r\n",rent.rentcode,rent.time, - rent.net_cost_per_diem,rent.gold,rent.account); + if (!objsave_write_rentcode(fp, RENT_TIMEDOUT, cost, ch)) + return; for (j = 0; j < NUM_WEARS; j++) { if (GET_EQ(ch, j)) { @@ -813,7 +746,6 @@ void Crash_idlesave(struct char_data *ch) void Crash_rentsave(struct char_data *ch, int cost) { char buf[MAX_INPUT_LENGTH]; - struct rent_info rent; int j; FILE *fp; @@ -829,14 +761,8 @@ void Crash_rentsave(struct char_data *ch, int cost) Crash_extract_norent_eq(ch); Crash_extract_norents(ch->carrying); - rent.net_cost_per_diem = cost; - rent.rentcode = RENT_RENTED; - rent.time = time(0); - rent.gold = GET_GOLD(ch); - rent.account = GET_BANK_GOLD(ch); - - fprintf(fp,"%d %d %d %d %d 0\r\n",rent.rentcode,rent.time, - rent.net_cost_per_diem,rent.gold,rent.account); + if (!objsave_write_rentcode(fp, RENT_RENTED, cost, ch)) + return; for (j = 0; j < NUM_WEARS; j++) if (GET_EQ(ch, j)) { @@ -858,11 +784,27 @@ void Crash_rentsave(struct char_data *ch, int cost) Crash_extract_objs(ch->carrying); } +int objsave_write_rentcode(FILE *fl, int rentcode, int cost_per_day, struct char_data *ch) +{ + if (fprintf(fl, "%d %ld %d %d %d %d\r\n", + rentcode, // rentcode + (long) time(0), // time of save + cost_per_day, // cost per day + GET_GOLD(ch), // current gold balance + GET_BANK_GOLD(ch), // current account balance + 0) // number of items - not used atm + < 1) + { + perror("Syserr: Writing rent code"); + return FALSE; + } + return TRUE; + +} void Crash_cryosave(struct char_data *ch, int cost) { char buf[MAX_INPUT_LENGTH]; - struct rent_info rent; int j; FILE *fp; @@ -880,15 +822,8 @@ void Crash_cryosave(struct char_data *ch, int cost) GET_GOLD(ch) = MAX(0, GET_GOLD(ch) - cost); - rent.rentcode = RENT_CRYO; - rent.time = time(0); - rent.gold = GET_GOLD(ch); - rent.account = GET_BANK_GOLD(ch); - rent.net_cost_per_diem = 0; - - fprintf(fp,"%d %d %d %d %d 0\r\n",rent.rentcode,rent.time, - rent.net_cost_per_diem,rent.gold,rent.account); - + if (!objsave_write_rentcode(fp, RENT_CRYO, 0, ch)) + return; for (j = 0; j < NUM_WEARS; j++) if (GET_EQ(ch, j)) { @@ -985,7 +920,7 @@ int Crash_offer_rent(struct char_data *ch, struct char_data *receptionist, norent += Crash_report_unrentables(ch, receptionist, GET_EQ(ch, i)); if (norent) - return (0); + return FALSE; totalcost = min_rent_cost * factor; @@ -997,13 +932,13 @@ int Crash_offer_rent(struct char_data *ch, struct char_data *receptionist, if (!numitems) { act("$n tells you, 'But you are not carrying anything! Just quit!'", FALSE, receptionist, 0, ch, TO_VICT); - return (0); + return FALSE; } if (numitems > max_obj_save) { sprintf(buf, "$n tells you, 'Sorry, but I cannot store more than %d items.'", max_obj_save); act(buf, FALSE, receptionist, 0, ch, TO_VICT); - return (0); + return FALSE; } if (display) { sprintf(buf, "$n tells you, 'Plus, my %d coin fee..'", @@ -1015,7 +950,7 @@ int Crash_offer_rent(struct char_data *ch, struct char_data *receptionist, if (totalcost > GET_GOLD(ch) + GET_BANK_GOLD(ch)) { act("$n tells you, '...which I see you can't afford.'", FALSE, receptionist, 0, ch, TO_VICT); - return (0); + return FALSE; } else if (factor == RENT_FACTOR) Crash_rent_deadline(ch, receptionist, totalcost); } @@ -1053,7 +988,7 @@ int gen_receptionist(struct char_data *ch, struct char_data *recep, if (free_rent) { act("$n tells you, 'Rent is free here. Just quit, and your objects will be saved!'", FALSE, recep, 0, ch, TO_VICT); - return (1); + return TRUE; } if (CMD_IS("rent")) { @@ -1128,17 +1063,202 @@ void Crash_save_all(void) } } +/* + * parses the object records stored in fl, and returns the first object in a + * linked list, which also handles location if worn. + * this list can then be handled by house code, listrent code, autoeq code, etc. + */ +obj_save_data *objsave_parse_objects(FILE *fl) +{ + obj_save_data *head, *current; + char line[READ_SIZE]; + int t[4],i, nr; + struct obj_data *temp; + + CREATE(current, obj_save_data, 1); + head = current; + current->locate = 0; + + temp = NULL; + while (TRUE) { + char tag[6]; + int num; + + /* if the file is done, wrap it all up */ + if(get_line(fl, line) == FALSE || (*line == '$' && line[1] == '~')) + { + if (temp == NULL && current->obj == NULL) + { + // remove current from list + obj_save_data *t = head; + if (t == current) + { + free(current); + head = NULL; + } + else + { + while (t) + { + if (t->next == current) + t->next = NULL; + + t = t->next; + } + free(current); + } + } + else if (temp != NULL && current->obj == NULL) + { + current->obj = temp; + } + else if (temp == NULL && current->obj != NULL) + { + // do nothing + } + else if (temp != NULL && current->obj != NULL) + { + if (temp != current->obj) + log("inconsistent object pointers in objsave_parse_objects: %p/%p", temp, current->obj); + } + + break; + } + + /* if it's a new record, wrap up the old one, and make space for a new one */ + if (*line == '#') { + /* check for false alarm. */ + if (sscanf(line, "#%d", &nr) == 1) + { + if (temp) + { + current->obj = temp; + CREATE(current->next, obj_save_data, 1); + current=current->next; + + current->locate = 0; + temp = NULL; + } + } + else + continue; + /* we have the number, check it, load obj. */ + if (nr == NOTHING) { /* then it is unique */ + temp = create_obj(); + temp->item_number=NOTHING; + } else if (nr < 0) { + continue; + } else { + if(real_object(nr) != NOTHING) { + temp=read_object(nr,VIRTUAL); + // go read next line - nothing more to see here + } else { + log("Nonexistent object %d found in rent file.", nr); + } + } + // go read next line - nothing more to see here + continue; + } + + tag_argument(line, tag); + num = atoi(line); + + switch(*tag) { + case 'A': + if (!strcmp(tag, "ADes")) { + char error[40]; + snprintf(error, sizeof(error)-1, "rent(Ades):%s", temp->name); + temp->action_description = fread_string(fl, error); + } else if (!strcmp(tag, "Aff ")) { + sscanf(line, "%d %d %d", &t[0], &t[1], &t[2]); + if (t[0] < MAX_OBJ_AFFECT) { + temp->affected[t[0]].location = t[1]; + temp->affected[t[0]].modifier = t[2]; + } + } + break; + case 'C': + if (!strcmp(tag, "Cost")) + GET_OBJ_COST(temp) = num; + break; + case 'D': + if (!strcmp(tag, "Desc")) + temp->description = strdup(line); + break; + case 'E': + if(!strcmp(tag, "EDes")) { + struct extra_descr_data *new_desc; + char error[40]; + snprintf(error, sizeof(error)-1, "rent(Edes): %s", temp->name); + if (temp->item_number != NOTHING && /* Regular object */ + temp->ex_description && /* with ex_desc == prototype */ + (temp->ex_description == obj_proto[real_object(temp->item_number)].ex_description)) + temp->ex_description = NULL; + CREATE(new_desc, struct extra_descr_data, 1); + new_desc->keyword = fread_string(fl, error); + new_desc->description = fread_string(fl, error); + new_desc->next = temp->ex_description; + temp->ex_description = new_desc; + } + break; + case 'F': + if (!strcmp(tag, "Flag")) + GET_OBJ_EXTRA(temp) = asciiflag_conv(line); + break; + case 'L': + if(!strcmp(tag, "Loc ")) + current->locate = num; + break; + case 'N': + if (!strcmp(tag, "Name")) + temp->name = strdup(line); + break; + case 'P': + if (!strcmp(tag, "Perm")) + temp->obj_flags.bitvector = asciiflag_conv(line); + break; + case 'R': + if (!strcmp(tag, "Rent")) + GET_OBJ_RENT(temp) = num; + break; + case 'S': + if (!strcmp(tag, "Shrt")) + temp->short_description = strdup(line); + break; + case 'T': + if (!strcmp(tag, "Type")) + GET_OBJ_TYPE(temp) = num; + break; + case 'W': + if (!strcmp(tag, "Wear")) + GET_OBJ_WEAR(temp) = asciiflag_conv(line); + else if (!strcmp(tag, "Wght")) + GET_OBJ_WEIGHT(temp) = num; + break; + case 'V': + if (!strcmp(tag, "Vals")) { + sscanf(line, "%d %d %d %d", &t[0], &t[1], &t[2], &t[3]); + for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) + GET_OBJ_VAL(temp, i) = t[i]; + } + break; + default: + log("Unknown tag in rentfile: %s", tag); + } + } + + return head; +} + int Crash_load_objs(struct char_data *ch) { FILE *fl; char fname[MAX_STRING_LENGTH]; - char line[256]; - int t[10],i,num_of_days; - int orig_rent_code; - struct obj_data *temp; - int locate=0, nr,cost,num_objs=0; + char line[READ_SIZE]; + int i, num_of_days, orig_rent_code, cost, num_objs=0; struct obj_data *cont_row[MAX_BAG_ROWS]; int rentcode,timed,netcost,gold,account,nitems; + obj_save_data *loaded, *current; if (!get_filename(fname, sizeof(fname), CRASH_FILE, GET_NAME(ch))) return 1; @@ -1204,131 +1324,19 @@ int Crash_load_objs(struct char_data *ch) { break; } - temp = NULL; - while (get_line(fl, line)) { - char tag[6]; - int num; - - /* first, we get the number. Not too hard. */ - if(*line == '$' && line[1] == '~') { - if (temp) - num_objs += handle_obj(temp, ch, locate, cont_row); - break; - } - if (*line == '#') { - if (sscanf(line, "#%d", &nr) != 1) { - continue; - } else { - if (temp) - num_objs += handle_obj(temp, ch, locate, cont_row); - temp = NULL; - locate = 0; - } - /* we have the number, check it, load obj. */ - if (nr == NOTHING) { /* then it is unique */ - temp = create_obj(); - temp->item_number=NOTHING; - } else if (nr < 0) { - continue; - } else { - if(nr >= 999999) - continue; - if(real_object(nr) != NOTHING) { - temp=read_object(nr,VIRTUAL); - if (!temp) { - continue; - } - } else { - log("Nonexistent object %d found in rent file.", nr); - continue; - } - } - } - - tag_argument(line, tag); - num = atoi(line); - - switch(*tag) { - case 'A': - if (!strcmp(tag, "ADes")) { - char error[40]; - snprintf(error, sizeof(error)-1, "rent(Ades):%s", temp->name); - temp->action_description = fread_string(fl, error); - } else if (!strcmp(tag, "Aff ")) { - sscanf(line, "%d %d %d", &t[0], &t[1], &t[2]); - if (t[0] < MAX_OBJ_AFFECT) { - temp->affected[t[0]].location = t[1]; - temp->affected[t[0]].modifier = t[2]; - } - } - break; - case 'C': - if (!strcmp(tag, "Cost")) - GET_OBJ_COST(temp) = num; - break; - case 'D': - if (!strcmp(tag, "Desc")) - temp->description = strdup(line); - break; - case 'E': - if(!strcmp(tag, "EDes")) { - struct extra_descr_data *new_desc; - char error[40]; - snprintf(error, sizeof(error)-1, "rent(Edes): %s", temp->name); - if (temp->item_number != NOTHING && /* Regular object */ - temp->ex_description && /* with ex_desc == prototype */ - (temp->ex_description == obj_proto[real_object(temp->item_number)].ex_description)) - temp->ex_description = NULL; - CREATE(new_desc, struct extra_descr_data, 1); - new_desc->keyword = fread_string(fl, error); - new_desc->description = fread_string(fl, error); - new_desc->next = temp->ex_description; - temp->ex_description = new_desc; - } - break; - case 'F': - if (!strcmp(tag, "Flag")) - GET_OBJ_EXTRA(temp) = asciiflag_conv(line); - break; - case 'L': - if(!strcmp(tag, "Loc ")) - locate = num; - break; - case 'N': - if (!strcmp(tag, "Name")) - temp->name = strdup(line); - break; - case 'P': - if (!strcmp(tag, "Perm")) - temp->obj_flags.bitvector = asciiflag_conv(line); - break; - case 'R': - if (!strcmp(tag, "Rent")) - GET_OBJ_RENT(temp) = num; - break; - case 'S': - if (!strcmp(tag, "Shrt")) - temp->short_description = strdup(line); - break; - case 'T': - if (!strcmp(tag, "Type")) - GET_OBJ_TYPE(temp) = num; - break; - case 'W': - if (!strcmp(tag, "Wear")) - GET_OBJ_WEAR(temp) = asciiflag_conv(line); - else if (!strcmp(tag, "Wght")) - GET_OBJ_WEIGHT(temp) = num; - break; - case 'V': - if (!strcmp(tag, "Vals")) { - sscanf(line, "%d %d %d %d", &t[0], &t[1], &t[2], &t[3]); - for (i = 0; i < 4; i++) - GET_OBJ_VAL(temp, i) = t[i]; - } - break; - } - } + loaded = objsave_parse_objects(fl); + for (current = loaded; current != NULL; current=current->next) + num_objs += handle_obj(current->obj, ch, current->locate, cont_row); + + /* + * now it's safe to free the obj_save_data list - all members of it + * have been put in the correct lists by handle_obj() + */ + while (loaded != NULL) { + current = loaded; + loaded = loaded->next; + free(current); + } /* Little hoarding check. -gg 3/1/98 */ mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "%s (level %d) has %d objects (max %d).", @@ -1349,7 +1357,7 @@ int handle_obj(struct obj_data *temp, struct char_data *ch, int locate, struct o struct obj_data *obj1; if (!temp) /* this should never happen, but.... */ - return (0); + return FALSE; auto_equip(ch, temp, locate); @@ -1447,6 +1455,6 @@ int handle_obj(struct obj_data *temp, struct char_data *ch, int locate, struct o } } /* locate less than zero */ - return (1); + return TRUE; }