/************************************************************************** * # # # ## # # ### ## ## ### http://www.lyonesse.it * * # # # # # ## # # # # # * * # # # # # ## ## # # ## ## ## # # ## * * # # # # # ## # # # # # # # # # # # * * ### # ## # # ### ## ## ### # # #### ## Ver. 1.0 * * * * -Based on CircleMud & Smaug- Copyright (c) 2001-2002 by Mithrandir * * * * ********************************************************************** * * * * File: stables.c * * * * mounts and vehicles save code * * * **************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "comm.h" #include "db.h" #include "handler.h" #include "interpreter.h" #include "constants.h" /* externs */ extern VEHICLE_DATA *first_vehicle; extern VEHICLE_DATA *last_vehicle; extern VEHICLE_INDEX *vehicle_types[MAX_VEH_TYPE]; extern bool LoadingCharObj; /* external functions */ AFFECTED_DATA *aff_by_bitvector( CHAR_DATA *ch, int bitv ); VEHICLE_DATA *new_vehicle(void); OBJ_DATA *fread_one_obj( FILE *fp, int *location ); int save_objs(OBJ_DATA *obj, FILE *fp, int mode, int location); void mob_to_yoke( CHAR_DATA *mob, VEHICLE_DATA *vehicle ); /* globals */ STABLE_RENT *first_stable_rent = NULL; STABLE_RENT *last_stable_rent = NULL; /* ****************************************************************** */ /* STABLE INDEX routines */ /* ****************************************************************** */ void LoadStableRentIndex(void) { FILE *fp; STABLE_RENT *strent; char iname[128], *line; char name1[128], name2[128], name3[128]; sprintf(iname, "%sindex", LIB_STABLES); if ( !( fp = fopen(iname, "r") ) ) { log(" No Stables actually in game."); return; } for ( ; ; ) { if ( feof(fp) ) break; line = fread_line(fp); if ( *line == '$' ) break; if ( *line == '*' ) continue; CREATE(strent, STABLE_RENT, 1); sscanf(line, "%d %hd %d %s %s %s", &strent->stable_vnum, &strent->type, &strent->id_player, name1, name2, name3); strent->filename = str_dup(name1); strent->playername = str_dup(name2); strent->typedescr = str_dup(name3); LINK(strent, first_stable_rent, last_stable_rent, next, prev); } fclose(fp); } void fwrite_rent_index( void ) { FILE *fp; STABLE_RENT *strent; char iname[128]; if ( !first_stable_rent ) return; sprintf(iname, "%sindex", LIB_STABLES); if ( !( fp = fopen(iname, "w") ) ) { log("SYSERR: fwrite_rent_index() - cannot create index file."); return; } for ( strent = first_stable_rent; strent; strent = strent->next ) fprintf(fp, "%d %hd %d %s %s %s\n", strent->stable_vnum, strent->type, strent->id_player, strent->filename, strent->playername, strent->typedescr); fprintf(fp, "$\n"); fclose(fp); } /* ****************************************************************** */ /* RENT routines */ /* ****************************************************************** */ void fwrite_rent_mount(CHAR_DATA *mount, FILE *fp) { // save mount data fprintf(fp, "#MOUNT\n"); fprintf(fp, "Mob_vnum %d\n", GET_MOB_VNUM(mount)); fprintf(fp, "Owner_id %d\n", MOB_OWNER(mount)); fprintf(fp, "End\n"); } void rent_mount(CHAR_DATA *ch, CHAR_DATA *mount) { FILE *fp; STABLE_RENT *strent; char fname[128]; if ( IS_NPC(ch) ) return; // here we loose mounts without Vnum if ( !IS_NPC(mount) || GET_MOB_VNUM(mount) == NOTHING ) return; CREATE(strent, STABLE_RENT, 1); strent->filename = str_dup(fname); strent->id_player = GET_IDNUM(ch); strent->playername = str_dup(GET_PC_NAME(ch)); strent->type = ST_RENT_MOUNT; strent->typedescr = str_dup(GET_PC_NAME(mount)); strent->stable_vnum = ch->in_room->number; LINK(strent, first_stable_rent, last_stable_rent, next, prev); // save mount sprintf(fname, "%s%ld.txt", LIB_STABLES, time(0)); if (!(fp = fopen(fname, "w"))) { log("SYSERR: fwrite_rent_mount() - cannot create file %s", fname); return; } fwrite_rent_mount(mount, fp); fprintf(fp, "#END\n"); fclose(fp); fwrite_rent_index(); } void fwrite_rent_vehicle(VEHICLE_DATA *vehicle, FILE *fp) { fprintf(fp, "\n#VEHICLE\n"); fprintf(fp, "Name %s\n", vehicle->name); fprintf(fp, "Type %hd\n", vehicle->type->vnum); fprintf(fp, "Owner_id %d\n", vehicle->owner_id); if ( vehicle->short_description ) fprintf(fp, "Shortdescr %s~\n", vehicle->short_description); if ( vehicle->description ) fprintf(fp, "Descr %s~\n", vehicle->description); fprintf(fp, "Val_max %hd %hd %hd %hd %hd\n", vehicle->max_val.capacity, vehicle->max_val.health, vehicle->max_val.speed, vehicle->max_val.passengers, vehicle->max_val.draft_mobs); /* * doesn't save curr_val.passengers and curr_val.draft_mobs * because there mustn't be passengers inside when we save * and draft_mobs is handled by mob_to_yoke while reloading */ fprintf(fp, "Val_curr %hd %hd %hd\n", vehicle->curr_val.capacity, vehicle->curr_val.health, vehicle->curr_val.speed); fprintf(fp, "Flags %d\n", vehicle->flags); // save vehicle hithced mobs if ( vehicle->first_yoke ) { YOKE_DATA *yoke; AFFECTED_DATA *aff; int adur; for ( yoke = vehicle->first_yoke; yoke; yoke = yoke->next ) { // here we loose yoked mobs without Vnum if ( GET_MOB_VNUM(yoke->mob) == NOTHING ) continue; if ( ( aff = aff_by_bitvector(yoke->mob, AFF_TAMED) ) ) adur = aff->duration; else adur = 0; fprintf(fp, "Mob_vnum %d %d\n", GET_MOB_VNUM(yoke->mob), adur); } } fprintf(fp, "End\n"); // save vehicle contents if ( vehicle->first_content ) save_objs(vehicle->last_content, fp, 1, 0); } void rent_vehicle(CHAR_DATA *ch, VEHICLE_DATA *vehicle) { FILE *fp; STABLE_RENT *strent; char fname[128]; if ( IS_NPC(ch) ) return; CREATE(strent, STABLE_RENT, 1); strent->filename = str_dup(fname); strent->id_player = GET_IDNUM(ch); strent->playername = str_dup(GET_PC_NAME(ch)); strent->type = ST_RENT_VEHICLE; strent->typedescr = str_dup(vehicle->name); strent->stable_vnum = ch->in_room->number; LINK(strent, first_stable_rent, last_stable_rent, next, prev); // save vehicle sprintf(fname, "%s%ld.txt", LIB_STABLES, time(0)); if (!(fp = fopen(fname, "w"))) { log("SYSERR: rent_vehicle() - cannot create file %s", fname); return; } fwrite_rent_vehicle(vehicle, fp); fprintf(fp, "#END\n"); fclose(fp); fwrite_rent_index(); } /* ****************************************************************** */ /* UNRENT routines */ /* ****************************************************************** */ #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !strcmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } /* read rented mount data */ CHAR_DATA *fread_rent_mount( FILE *fp, ROOM_DATA *sRoom ) { CHAR_DATA *mount = NULL; char *word; bool fMatch; for ( ; ; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER(word[0]) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'E': if ( !strcmp(word, "End") ) return (mount); break; case 'M': if ( !strcmp(word, "Mob_vnum") ) { int vnum = fread_number(fp); if ( !(mount = read_mobile(vnum, VIRTUAL)) ) { log("SYSERR: fread_rent_mount() - cannot find mob (vnum %d).", vnum); return (NULL); } char_to_room(mount, sRoom); fMatch = TRUE; break; } case 'O': if ( !strcmp(word, "Owner_id") ) { if ( mount ) MOB_OWNER(mount) = fread_number(fp); fMatch = TRUE; break; } break; } if ( !fMatch ) log( "fread_rent_mount: no match: %s", word ); } return (mount); } /* read rented vehicle data */ VEHICLE_DATA *fread_rent_vehicle( FILE *fp, ROOM_DATA *sRoom ) { VEHICLE_DATA *vehicle = new_vehicle(); char *word; bool fMatch; vehicle_to_room( vehicle, sRoom ); for ( ; ; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER(word[0]) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'D': KEY( "Descr", vehicle->description, fread_string_nospace(fp) ); break; case 'E': if ( !strcmp( word, "End" ) ) { // do some checks.. if ( !vehicle->type ) { log("SYSERR: fread_rent_vehicle() - unknown vehicle type."); return (NULL); } if ( !vehicle->name ) vehicle->name = str_dup(vehicle->type->name); if ( !vehicle->short_description ) vehicle->short_description = str_dup(vehicle->type->short_description); if ( !vehicle->description ) vehicle->description = str_dup(vehicle->type->description); return (vehicle); } break; case 'F': KEY( "Flags", vehicle->flags, fread_number(fp) ); break; case 'M': if ( !strcmp( word, "Mob_vnum" ) ) { CHAR_DATA *mob; int vnum, adur; vnum = fread_number(fp); adur = fread_number(fp); if ( (mob = read_mobile(vnum, VIRTUAL)) ) { /* hmm.. calc for elapsed?? */ if ( adur != 0 ) { AFFECTED_DATA af; // re-tame the mob.. af.duration = adur; af.bitvector = AFF_TAMED; affect_join(mob, &af, FALSE, FALSE, FALSE, FALSE); } char_to_room(mob, sRoom); mob_to_yoke(mob, vehicle); } fMatch = TRUE; break; } break; case 'N': KEY( "Name", vehicle->name, str_dup(fread_word(fp)) ); break; case 'O': KEY( "Owner_id", vehicle->owner_id, fread_number(fp) ); break; case 'S': KEY( "Shortdescr", vehicle->short_description, fread_string_nospace(fp) ); break; case 'T': if (!str_cmp(word, "Type")) { int vnum = fread_number(fp); if (vnum < 0 || vnum >= MAX_VEH_TYPE) { log("SYSERR: fread_rent_vehicle() - invalid vehicle type vnum %d.", vnum); exit(1); } if (!vehicle_types[vnum]) { log("SYSERR: fread_rent_vehicle() - invalid vehicle type vnum %d.", vnum); exit(1); } vehicle->type = vehicle_types[vnum]; fMatch = TRUE; break; } break; case 'V': if ( !strcmp( word, "Val_curr" ) ) { vehicle->curr_val.capacity = fread_number(fp); vehicle->curr_val.health = fread_number(fp); vehicle->curr_val.speed = fread_number(fp); fMatch = TRUE; break; } if ( !strcmp( word, "Val_max" ) ) { vehicle->max_val.capacity = fread_number(fp); vehicle->max_val.health = fread_number(fp); vehicle->max_val.speed = fread_number(fp); vehicle->max_val.passengers = fread_number(fp); vehicle->max_val.draft_mobs = fread_number(fp); fMatch = TRUE; break; } break; } if ( !fMatch ) log( "fread_rent_vehicle: no match: %s", word ); } return (vehicle); } #define MAX_BAG_ROWS 5 /* this is used to unrent mounts from a stable */ void unrent_from_stable( CHAR_DATA *ch, STABLE_RENT *strent ) { FILE *fp; CHAR_DATA *mount; VEHICLE_DATA *vehicle; OBJ_DATA *obj, *obj2, *cont_row[MAX_BAG_ROWS]; char fname[128]; char letter; char *word; int location, j; sprintf(fname, "%s%s", LIB_STABLES, strent->filename); if ( !( fp = fopen(fname, "r") ) ) { log("SYSERR: unrent_from_stable() - cannot open file %s", fname); return; } for (j = 0; j < MAX_BAG_ROWS; j++) cont_row[j] = NULL; LoadingCharObj = TRUE; for ( ; ; ) { letter = fread_letter( fp ); if ( letter == '*' ) { fread_to_eol( fp ); continue; } if ( feof( fp ) ) break; if ( letter != '#' ) { log( "SYSERR: unrent_from_stable: # not found." ); break; } word = fread_word( fp ); if ( !strcmp( word, "VEHICLE" ) ) { if ( !( vehicle = fread_rent_vehicle(fp, ch->in_room) ) ) { log( "SYSERR: unrent_from_stable() cannot load vehicle data." ); send_to_char("There is a problem with your vehcile. Tell an Immortal.\r\n", ch); fclose( fp ); LoadingCharObj = FALSE; return; } LINK(vehicle, first_vehicle, last_vehicle, next, prev); continue; } else if ( !strcmp( word, "MOUNT" ) ) { if ( !( mount = fread_rent_mount(fp, ch->in_room) ) ) { log( "SYSERR: unrent_from_stable() cannot load mob data." ); send_to_char("There is a problem with your mount. Tell an Immortal.\r\n", ch); fclose( fp ); LoadingCharObj = FALSE; return; } } else if ( !strcmp( word, "OBJVEH" ) ) { if ( !vehicle ) { log("SYSERR: unrent_from_stable() - trying to load an object without a vehicle."); fclose(fp); LoadingCharObj = FALSE; return; } if ( ( obj = fread_one_obj( fp, &location ) ) == NULL ) continue; obj = obj_to_vehicle(obj, vehicle); for (j = MAX_BAG_ROWS - 1; j > -location; j--) { if (cont_row[j]) { for (; cont_row[j]; cont_row[j] = obj2) { obj2 = cont_row[j]->next_content; cont_row[j] = obj_to_vehicle( cont_row[j], vehicle ); } cont_row[j] = NULL; } } if (j == -location && cont_row[j]) { if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER || GET_OBJ_TYPE(obj) == ITEM_MISSILE_CONT) { obj_from_vehicle(obj); obj->first_content = NULL; obj->last_content = NULL; for (; cont_row[j]; cont_row[j] = obj2) { obj2 = cont_row[j]->next_content; obj_to_obj(cont_row[j], obj); } obj = obj_to_vehicle( obj, vehicle ); } else { for (; cont_row[j]; cont_row[j] = obj2) { obj2 = cont_row[j]->next_content; cont_row[j] = obj_to_vehicle( cont_row[j], vehicle ); } cont_row[j] = NULL; } } if (location < 0 && location >= -MAX_BAG_ROWS) { obj_from_vehicle(obj); if ((obj2 = cont_row[-location - 1]) != NULL) { while (obj2->next_content) obj2 = obj2->next_content; obj2->next_content = obj; } else cont_row[-location - 1] = obj; } } else if ( !strcmp( word, "END" ) ) // Done break; } fclose(fp); LoadingCharObj = FALSE; /* remove withdrawed vehicle from list */ UNLINK(strent, first_stable_rent, last_stable_rent, next, prev); strent->next = NULL; strent->prev = NULL; if ( strent->filename ) STRFREE(strent->filename); if ( strent->playername ) STRFREE(strent->playername); if ( strent->typedescr ) STRFREE(strent->typedescr); DISPOSE(strent); // delete vehicle file remove(fname); // write updated index fwrite_rent_index(); } /* ****************************************************************** */ /* Commands */ /* ****************************************************************** */ ACMD(do_stablerent) { STABLE_RENT *strent; char sbuf[MAX_STRING_LENGTH]; if ( !first_stable_rent ) { send_to_char("No mounts rented in stables at the moment.\r\n", ch); return; } strcpy(sbuf, "List of mounts rented in stables:\r\n"); for ( strent = first_stable_rent; strent; strent = strent->next ) { sprintf(sbuf + strlen(sbuf), "Stable: [%d] - %s (%s) - rented by %s - filename: %s.\r\n", strent->stable_vnum, st_rent_descr[strent->type], strent->typedescr, strent->playername, strent->filename ); } page_string(ch->desc, sbuf, 1); }