/* * Save a character and inventory. * Would be cool to save NPC's too for quest purposes, * some of the infrastructure is provided. */ void save_char_obj( CHAR_DATA * ch ) { FILE * fp; CHAR_DATA * pet; char buf[ MAX_STRING_LENGTH ]; char strsave[ MAX_INPUT_LENGTH ]; if ( IS_NPC( ch ) ) { return; } if ( ch->desc && ch->desc->original ) { ch = ch->desc->original; } update_playerlist( ch ); ch->save_time = current_time; fclose( fpReserve ); /* player files parsed directories by Yaz 4th Realm */ sprintf( strsave, "%s%c/%s", PLAYER_DIR, LOWER( ch->name[ 0 ] ), capitalize( ch->name ) ); if ( !( fp = fopen( strsave, "w" ) ) ) { sprintf( buf, "Save_char_obj: fopen %s: ", ch->name ); bug( buf, 0 ); perror( strsave ); } else { fwrite_char( ch, fp ); if ( ch->carrying ) { fwrite_obj( ch, ch->carrying, fp, 0, FALSE ); } if ( !IS_NPC( ch ) && ch->pcdata->storage ) { fwrite_obj( ch, ch->pcdata->storage, fp, 0, TRUE ); } for ( pet = ch->in_room->people; pet; pet = pet->next_in_room ) { if ( IS_NPC( pet ) ) { if ( CHECK_BIT( pet->act, ACT_PET ) && ( pet->master == ch ) ) { save_pet( ch, fp, pet ); break; } } } tail_chain(); fprintf( fp, "#END\n" ); } fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; }
/* * Save a character and inventory. * Would be cool to save NPC's too for quest purposes, * some of the infrastructure is provided. */ void save_char_obj( CHAR_DATA *ch ) { FILE *fp; char buf [ MAX_STRING_LENGTH ]; char strsave [ MAX_INPUT_LENGTH ]; if ( IS_NPC( ch ) || ch->level < 2 ) return; if ( ch->desc && ch->desc->original ) ch = ch->desc->original; ch->save_time = current_time; fclose( fpReserve ); /* player files parsed directories by Yaz 4th Realm */ sprintf( strsave, "%s%s%s%s", PLAYER_DIR, initial( ch->name ), "/", capitalize( ch->name ) ); if ( !( fp = fopen( strsave, "w" ) ) ) { sprintf( buf, "Save_char_obj: fopen %s: ", ch->name ); bug( buf, 0 ); perror( strsave ); } else { fwrite_char( ch, fp ); if ( ch->carrying ) fwrite_obj( ch, ch->carrying, fp, 0 ); fprintf( fp, "#END\n" ); } fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; }
/* * Save a character and inventory. * Would be cool to save NPC's too for quest purposes, * some of the infrastructure is provided. */ void save_char_obj( CHAR_DATA *ch ) { char strsave[MAX_INPUT_LENGTH]; FILE *fp; if ( IS_NPC(ch) || ch->level < 2 ) return; if ( ch->desc != NULL && ch->desc->original != NULL ) ch = ch->desc->original; ch->save_time = current_time; fclose( fpReserve ); /* player files parsed directories by Yaz 4th Realm */ #if !defined(machintosh) && !defined(MSDOS) sprintf( strsave, "%s%s%s%s", PLAYER_DIR, initial( ch->name ), "/", capitalize( ch->name ) ); #else sprintf( strsave, "%s%s", PLAYER_DIR, capitalize( ch->name ) ); #endif if ( ( fp = fopen( strsave, "w" ) ) == NULL ) { bug( "Save_char_obj: fopen", 0 ); perror( strsave ); } else { fwrite_char( ch, fp ); if ( ch->carrying != NULL ) fwrite_obj( ch, ch->carrying, fp, 0 ); fprintf( fp, "#END\n" ); } fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; }
void save_world( CHAR_DATA * ch ) { FILE *mobfp; FILE *objfp; FILE *shipfp; int mobfile = 0; int shipfile = 0; char filename[256]; CHAR_DATA *rch; ROOM_INDEX_DATA *pRoomIndex; int iHash; log_string( "Preserving world state...." ); snprintf( filename, 256, "%s%s", SYSTEM_DIR, MOB_FILE ); if( ( mobfp = fopen( filename, "w" ) ) == NULL ) { bug( "%s", "save_world: fopen mob file" ); perror( filename ); } else mobfile++; snprintf( filename, 256, "%s%s", SYSTEM_DIR, SHIP_FILE ); if( ( shipfp = fopen( filename, "w" ) ) == NULL ) { bug( "%s", "save_world: fopen ship file" ); perror( filename ); } else shipfile++; for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) { for( pRoomIndex = room_index_hash[iHash]; pRoomIndex; pRoomIndex = pRoomIndex->next ) { if( pRoomIndex ) { if( !pRoomIndex->first_content /* Skip room if nothing in it */ || IS_SET( pRoomIndex->room_flags, ROOM_CLANSTOREROOM ) /* These rooms save on their own */ ) continue; snprintf( filename, 256, "%s%d", HOTBOOT_DIR, pRoomIndex->vnum ); if( ( objfp = fopen( filename, "w" ) ) == NULL ) { bug( "save_world: fopen %d", pRoomIndex->vnum ); perror( filename ); continue; } fwrite_obj( NULL, pRoomIndex->last_content, objfp, 0, OS_CARRY, TRUE ); fprintf( objfp, "%s", "#END\n" ); FCLOSE( objfp ); } } } if( mobfile ) { for( rch = first_char; rch; rch = rch->next ) { if( !IS_NPC( rch ) || rch == supermob || IS_SET( rch->act, ACT_PROTOTYPE ) || IS_SET( rch->act, ACT_PET ) ) continue; else save_mobile( mobfp, rch ); } fprintf( mobfp, "%s", "#END\n" ); FCLOSE( mobfp ); } if( shipfile ) { SHIP_DATA *ship = NULL; for( ship = first_ship; ship; ship = ship->next ) { write_ship( shipfp, ship ); } fprintf( shipfp, "%s", "#END\n" ); FCLOSE( shipfp ); } return; }
/* * Save the world's objects and mobs in their current positions -- Scion */ void save_mobile( FILE * fp, CHAR_DATA * mob ) { AFFECT_DATA *paf; SKILLTYPE *skill = NULL; if( !IS_NPC( mob ) || !fp ) return; fprintf( fp, "%s", "#MOBILE\n" ); fprintf( fp, "Vnum %d\n", mob->pIndexData->vnum ); fprintf( fp, "Level %d\n", mob->top_level ); fprintf( fp, "Gold %d\n", mob->gold ); fprintf( fp, "Resetvnum %d\n", mob->resetvnum ); fprintf( fp, "Resetnum %d\n", mob->resetnum ); if( mob->in_room ) { if( IS_SET( mob->act, ACT_SENTINEL ) ) { /* * Sentinel mobs get stamped with a "home room" when they are created * by create_mobile(), so we need to save them in their home room regardless * of where they are right now, so they will go to their home room when they * enter the game from a reboot or copyover -- Scion */ fprintf( fp, "Room %d\n", mob->home_vnum ); } else fprintf( fp, "Room %d\n", mob->in_room->vnum ); } else fprintf( fp, "Room %d\n", ROOM_VNUM_LIMBO ); #ifdef OVERLANDCODE fprintf( fp, "Coordinates %d %d %d\n", mob->x, mob->y, mob->map ); #endif if( mob->name && mob->pIndexData->player_name && str_cmp( mob->name, mob->pIndexData->player_name ) ) fprintf( fp, "Name %s~\n", mob->name ); if( mob->short_descr && mob->pIndexData->short_descr && str_cmp( mob->short_descr, mob->pIndexData->short_descr ) ) fprintf( fp, "Short %s~\n", mob->short_descr ); if( mob->long_descr && mob->pIndexData->long_descr && str_cmp( mob->long_descr, mob->pIndexData->long_descr ) ) fprintf( fp, "Long %s~\n", mob->long_descr ); if( mob->description && mob->pIndexData->description && str_cmp( mob->description, mob->pIndexData->description ) ) fprintf( fp, "Description %s~\n", mob->description ); fprintf( fp, "HpManaMove %d %d %d %d %d %d\n", mob->hit, mob->max_hit, mob->mana, mob->max_mana, mob->move, mob->max_move ); fprintf( fp, "Position %d\n", mob->position ); fprintf( fp, "Flags %d\n", mob->act ); fprintf( fp, "AffectedBy %s\n", print_bitvector( &mob->affected_by ) ); for( paf = mob->first_affect; paf; paf = paf->next ) { if( paf->type >= 0 && ( skill = get_skilltype( paf->type ) ) == NULL ) continue; if( paf->type >= 0 && paf->type < TYPE_PERSONAL ) fprintf( fp, "AffectData '%s' %f %3d %3d %s\n", skill->name, paf->duration, paf->modifier, paf->location, print_bitvector( &paf->bitvector ) ); else fprintf( fp, "Affect %3d %f %3d %3d %s\n", paf->type, paf->duration, paf->modifier, paf->location,print_bitvector( &paf->bitvector ) ); } de_equip_char( mob ); if( mob->first_carrying ) fwrite_obj( mob, mob->last_carrying, fp, 0, OS_CARRY, TRUE ); re_equip_char( mob ); fprintf( fp, "%s", "EndMobile\n\n" ); return; }
/* * Write an object and its contents. */ void fwrite_obj( struct obj_data *obj, FILE *fp, int iNest ) { // struct affected_type * paf = NULL; struct extra_descr_data * ed = NULL; int i; /* * Slick recursion to write lists backwards, * so loading them will load in forwards order. */ if ( obj->next_content ) fwrite_obj( obj->next_content, fp, iNest ); /* * Castrate storage characters. */ if ( obj->obj_flags.type_flag == ITEM_KEY ) return; fprintf( fp, "#OBJECT\n" ); fprintf( fp, "Nest %d\n", iNest ); fprintf( fp, "Name %s~\n", obj->name ); fprintf( fp, "ShortDescr %s~\n", obj->short_description ); fprintf( fp, "Description %s~\n", obj->description ); fprintf( fp, "ActionDescr %s~\n", obj->action_description ? obj->action_description : "" ); fprintf( fp, "Vnum %ld\n", obj->item_number ); fprintf( fp, "ExtraFlags %ld\n", obj->obj_flags.extra_flags ); fprintf( fp, "WearFlags %d\n", obj->obj_flags.wear_flags ); fprintf( fp, "ItemType %d\n", obj->obj_flags.type_flag ); fprintf( fp, "Weight %d\n", obj->obj_flags.weight ); fprintf( fp, "Timer %d\n", obj->obj_flags.timer ); fprintf( fp, "Cost %d\n", obj->obj_flags.cost ); fprintf( fp, "Values %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", obj->obj_flags.value[0], obj->obj_flags.value[1], obj->obj_flags.value[2], obj->obj_flags.value[3], obj->obj_flags.value[4], obj->obj_flags.value[5], obj->obj_flags.value[6], obj->obj_flags.value[7], obj->obj_flags.value[8], obj->obj_flags.value[9] ); switch ( obj->obj_flags.type_flag ) { case ITEM_POTION: case ITEM_SCROLL: if ( obj->obj_flags.value[1] > 0 ) { fprintf( fp, "Spell 1 '%s'\n", skill_name( obj->obj_flags.value[1] ) ); } if ( obj->obj_flags.value[2] > 0 ) { fprintf( fp, "Spell 2 '%s'\n", skill_name( obj->obj_flags.value[2] ) ); } if ( obj->obj_flags.value[3] > 0 ) { fprintf( fp, "Spell 3 '%s'\n", skill_name( obj->obj_flags.value[3] ) ); } break; case ITEM_STAFF: case ITEM_WAND: if ( obj->obj_flags.value[3] > 0 ) { fprintf( fp, "Spell 3 '%s'\n", skill_name( obj->obj_flags.value[3] ) ); } break; default: /* ERROR */ break; } for ( i = 0; i < MAX_OBJ_AFFECT; i++ ) fprintf( fp, "Affect %d %d\n", obj->affected[ i ].location, obj->affected[ i ].modifier ); /* paf = obj->affected; for ( paf = obj->affected; paf; paf = paf->next ) { fprintf( fp, "Affect %d %d %d %d %ld\n", paf->type, paf->duration, paf->modifier, paf->location, paf->bitvector ); } */ for ( ed = obj->ex_description; ed; ed = ed->next ) { fprintf( fp, "ExtraDescr %s~ %s~\n", ed->keyword, ed->description ); } fprintf( fp, "End\n\n" ); if ( obj->contains ) fwrite_obj( obj->contains, fp, iNest + 1 ); tail_chain( ); return; }
void fwrite_obj_char( struct char_data * ch, struct obj_data * obj, FILE * fp, int iNest ) { fwrite_obj( obj, fp, iNest ); }
/* * Write an object and its contents. */ void fwrite_obj( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, int iNest ) { AFFECT_DATA *paf; EXTRA_DESCR_DATA *ed; /* * Slick recursion to write lists backwards, * so loading them will load in forwards order. */ if ( obj->next_content ) fwrite_obj( ch, obj->next_content, fp, iNest ); /* * Castrate storage characters. */ if ( ch->level < obj->level || obj->item_type == ITEM_KEY || obj->deleted ) return; fprintf( fp, "#OBJECT\n" ); fprintf( fp, "Nest %d\n", iNest ); fprintf( fp, "Name %s~\n", obj->name ); fprintf( fp, "ShortDescr %s~\n", obj->short_descr ); fprintf( fp, "Description %s~\n", obj->description ); fprintf( fp, "Vnum %d\n", obj->pIndexData->vnum ); fprintf( fp, "ExtraFlags %d\n", obj->extra_flags ); fprintf( fp, "WearFlags %d\n", obj->wear_flags ); fprintf( fp, "WearLoc %d\n", obj->wear_loc ); fprintf( fp, "ItemType %d\n", obj->item_type ); fprintf( fp, "Weight %d\n", obj->weight ); fprintf( fp, "Level %d\n", obj->level ); fprintf( fp, "Timer %d\n", obj->timer ); fprintf( fp, "Cost %d\n", obj->cost ); fprintf( fp, "Values %d %d %d %d\n", obj->value[0], obj->value[1], obj->value[2], obj->value[3] ); switch ( obj->item_type ) { case ITEM_POTION: case ITEM_SCROLL: if ( obj->value[1] > 0 ) { fprintf( fp, "Spell 1 '%s'\n", skill_table[obj->value[1]].name ); } if ( obj->value[2] > 0 ) { fprintf( fp, "Spell 2 '%s'\n", skill_table[obj->value[2]].name ); } if ( obj->value[3] > 0 ) { fprintf( fp, "Spell 3 '%s'\n", skill_table[obj->value[3]].name ); } break; case ITEM_PILL: case ITEM_STAFF: case ITEM_WAND: if ( obj->value[3] > 0 ) { fprintf( fp, "Spell 3 '%s'\n", skill_table[obj->value[3]].name ); } break; } for ( paf = obj->affected; paf; paf = paf->next ) { fprintf( fp, "Affect %d %d %d %d %d\n", paf->type, paf->duration, paf->modifier, paf->location, paf->bitvector ); } for ( ed = obj->extra_descr; ed; ed = ed->next ) { fprintf( fp, "ExtraDescr %s~ %s~\n", ed->keyword, ed->description ); } fprintf( fp, "End\n\n" ); if ( obj->contains ) fwrite_obj( ch, obj->contains, fp, iNest + 1 ); tail_chain(); return; }