/***************************************************************************** * DikuMUD (C) 1990, 1991 by: * * Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, * * and Katja Nyboe. * *---------------------------------------------------------------------------* * MERC 2.1 (C) 1992, 1993 by: * * Michael Chastain, Michael Quan, and Mitchell Tse. * *---------------------------------------------------------------------------* * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. * * Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, * * gorog, Grishnakh, Nivek, Tricops, and Fireblade. * *---------------------------------------------------------------------------* * SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. * * Their contributions are greatly appreciated. * *---------------------------------------------------------------------------* * LoP (C) 2006, 2007, 2008 by: the LoP team. * *****************************************************************************/ #include <stdio.h> #include <string.h> #include "h/mud.h" extern bool fBootDb; bool check_area_conflict( AREA_DATA *carea, int low_range, int hi_range ); CMDF( do_aassign ) { char buf[MSL]; AREA_DATA *tarea, *tmp; if( !ch || is_npc( ch ) ) return; set_char_color( AT_IMMORT, ch ); if( !argument || argument[0] == '\0' ) { send_to_char( "Usage: aassign <filename>\r\n", ch ); return; } if( !str_cmp( "none", argument ) || !str_cmp( "clear", argument ) ) { ch->pcdata->area = NULL; assign_area( ch ); if( !ch->pcdata->area ) send_to_char( "Area pointer cleared.\r\n", ch ); else send_to_char( "Originally assigned area restored.\r\n", ch ); return; } mudstrlcpy( buf, argument, sizeof( buf ) ); tarea = NULL; if( get_trust( ch ) >= PERM_HEAD || ( is_name( buf, ch->pcdata->bestowments ) && get_trust( ch ) >= sysdata.perm_modify_proto ) ) { for( tmp = first_area; tmp; tmp = tmp->next ) { if( !str_cmp( buf, tmp->filename ) ) { tarea = tmp; break; } } } if( !tarea ) { for( tmp = first_build; tmp; tmp = tmp->next ) { if( !str_cmp( buf, tmp->filename ) ) { if( get_trust( ch ) >= PERM_HEAD || is_name( tmp->filename, ch->pcdata->bestowments ) || ( ch->pcdata->council && is_name( "aassign", ch->pcdata->council->powers ) ) ) { tarea = tmp; break; } else { send_to_char( "You do not have permission to use that area.\r\n", ch ); return; } } } } if( !tarea ) { send_to_char( "No such area. Check 'zones' and 'vnums'.\r\n", ch ); return; } ch->pcdata->area = tarea; ch_printf( ch, "Assigning you: %s\r\n", tarea->name ); } int save_programs( MPROG_DATA *mprog, FILE *fp ) { int count = 0; if( ( mprog->arglist && mprog->arglist[0] != '\0' ) ) { if( mprog->type == IN_FILE_PROG ) { fprintf( fp, "> %s %s~\n", mprog_type_to_name( mprog->type ), mprog->arglist ); count++; } /* Don't let it save progs which came from files. That would be silly. */ else if( mprog->comlist && mprog->comlist[0] != '\0' && !mprog->fileprog ) { fprintf( fp, "> %s %s~\n%s~\n", mprog_type_to_name( mprog->type ), mprog->arglist, strip_cr( mprog->comlist ) ); count++; } } return count; } bool fold_area( AREA_DATA *tarea, char *filename, bool install ) { RESET_DATA *pReset, *tReset, *gReset; ROOM_INDEX_DATA *room; MOB_INDEX_DATA *pMobIndex; OBJ_INDEX_DATA *pObjIndex; MPROG_DATA *mprog; EXIT_DATA *xit; EXTRA_DESCR_DATA *ed; AFFECT_DATA *paf; NEIGHBOR_DATA *neigh; FILE *fp; char buf[MSL], newfilename[MSL], tempfilename[MSL]; int val0, val1, val2, val3, val4, val5, vnum, stat; bool first; if( xIS_SET( tarea->flags, AFLAG_PROTOTYPE ) ) { snprintf( newfilename, sizeof( newfilename ), "%s%s", BUILD_DIR, filename ); snprintf( tempfilename, sizeof( buf ), "%s%s.temp", BUILD_DIR, filename ); } else { snprintf( newfilename, sizeof( newfilename ), "%s%s", AREA_DIR, filename ); snprintf( tempfilename, sizeof( buf ), "%s%s.temp", AREA_DIR, filename ); } log_printf_plus( LOG_NORMAL, PERM_LEADER, "Saving %s...", newfilename ); if( install ) { xREMOVE_BIT( tarea->flags, AFLAG_PROTOTYPE ); snprintf( newfilename, sizeof( newfilename ), "%s%s", AREA_DIR, filename ); } if( !( fp = fopen( tempfilename, "w" ) ) ) { bug( "%s: cant open %s for writing.", __FUNCTION__, newfilename ); perror( newfilename ); return false; } /* Save area info */ if( tarea->name ) fprintf( fp, "#AREA %s~\n", tarea->name ); fprintf( fp, "#VERSION %d\n", AREA_VERSION_WRITE ); if( tarea->author ) fprintf( fp, "#AUTHOR %s~\n", tarea->author ); fprintf( fp, "#RANGES %d %d %d %d\n", tarea->low_soft_range, tarea->hi_soft_range, tarea->low_hard_range, tarea->hi_hard_range ); if( tarea->resetmsg ) fprintf( fp, "#RESETMSG %s~\n", tarea->resetmsg ); if( tarea->reset_frequency ) fprintf( fp, "#RESETFREQ %d\n", tarea->reset_frequency ); if( !xIS_EMPTY( tarea->flags ) ) fprintf( fp, "#FLAGS %s~\n", ext_flag_string( &tarea->flags, area_flags ) ); fprintf( fp, "#CLIMATE %d %d %d\n", tarea->weather->climate_temp, tarea->weather->climate_precip, tarea->weather->climate_wind ); for( neigh = tarea->weather->first_neighbor; neigh; neigh = neigh->next ) fprintf( fp, "#NEIGHBOR %s~\n", neigh->name ); /* save mobiles */ first = true; for( vnum = tarea->low_vnum; vnum <= tarea->hi_vnum; vnum++ ) { if( !( pMobIndex = get_mob_index( vnum ) ) ) continue; if( first ) fprintf( fp, "\n#MOBILES\n" ); first = false; if( install ) xREMOVE_BIT( pMobIndex->act, ACT_PROTOTYPE ); fprintf( fp, "Vnum %d\n", vnum ); if( pMobIndex->level ) fprintf( fp, "Level %d\n", pMobIndex->level ); if( pMobIndex->name ) fprintf( fp, "Name %s~\n", strip_cr( pMobIndex->name ) ); if( pMobIndex->short_descr ) fprintf( fp, "Short %s~\n", strip_cr( pMobIndex->short_descr ) ); if( pMobIndex->long_descr ) fprintf( fp, "Long %s~\n", strip_cr( pMobIndex->long_descr ) ); if( pMobIndex->description ) fprintf( fp, "Description\n %s~\n", strip_cr( pMobIndex->description ) ); if( !xIS_EMPTY( pMobIndex->act ) ) fprintf( fp, "Flags %s~\n", ext_flag_string( &pMobIndex->act, act_flags ) ); if( !xIS_EMPTY( pMobIndex->affected_by ) ) fprintf( fp, "Affected %s~\n", ext_flag_string( &pMobIndex->affected_by, a_flags ) ); if( !xIS_EMPTY( pMobIndex->xflags ) ) fprintf( fp, "Parts %s~\n", ext_flag_string( &pMobIndex->xflags, part_flags ) ); if( !xIS_EMPTY( pMobIndex->resistant ) ) fprintf( fp, "Resistant %s~\n", ext_flag_string( &pMobIndex->resistant, ris_flags ) ); if( !xIS_EMPTY( pMobIndex->immune ) ) fprintf( fp, "Immune %s~\n", ext_flag_string( &pMobIndex->immune, ris_flags ) ); if( !xIS_EMPTY( pMobIndex->susceptible ) ) fprintf( fp, "Susceptible %s~\n", ext_flag_string( &pMobIndex->susceptible, ris_flags ) ); if( !xIS_EMPTY( pMobIndex->attacks ) ) fprintf( fp, "Attacks %s~\n", ext_flag_string( &pMobIndex->attacks, attack_flags ) ); if( !xIS_EMPTY( pMobIndex->defenses ) ) fprintf( fp, "Defenses %s~\n", ext_flag_string( &pMobIndex->defenses, defense_flags ) ); if( pMobIndex->defposition ) fprintf( fp, "DefPosition %s~\n", pos_names[pMobIndex->defposition] ); if( pMobIndex->sex ) fprintf( fp, "Sex %s~\n", sex_names[pMobIndex->sex] ); if( pMobIndex->alignment ) fprintf( fp, "Alignment %d\n", pMobIndex->alignment ); fprintf( fp, "Hit %d %d\n", pMobIndex->minhit, pMobIndex->maxhit ); fprintf( fp, "Saves %d %d %d %d %d\n", pMobIndex->saving_poison_death, pMobIndex->saving_wand, pMobIndex->saving_para_petri, pMobIndex->saving_breath, pMobIndex->saving_spell_staff ); if( !xIS_EMPTY( pMobIndex->speaks ) ) fprintf( fp, "Speaks %s~\n", ext_flag_string( &pMobIndex->speaks, lang_names ) ); if( !xIS_EMPTY( pMobIndex->speaking ) ) fprintf( fp, "Speaking %s~\n", ext_flag_string( &pMobIndex->speaking, lang_names ) ); fprintf( fp, "%s", "Stats " ); for( stat = 0; stat < STAT_MAX; stat++ ) fprintf( fp, " %d", pMobIndex->perm_stats[stat] ); fprintf( fp, "%s", "\n" ); if( pMobIndex->ac ) fprintf( fp, "Armor %d\n", pMobIndex->ac ); if( pMobIndex->mgold ) fprintf( fp, "MGold %d\n", pMobIndex->mgold ); if( pMobIndex->gold ) fprintf( fp, "Gold %d\n", pMobIndex->gold ); if( pMobIndex->height ) fprintf( fp, "Height %d\n", pMobIndex->height ); if( pMobIndex->weight ) fprintf( fp, "Weight %d\n", pMobIndex->weight ); if( pMobIndex->numattacks ) fprintf( fp, "NumAttacks %d\n", pMobIndex->numattacks ); if( pMobIndex->hitroll ) fprintf( fp, "HitRoll %d\n", pMobIndex->hitroll ); if( pMobIndex->damroll ) fprintf( fp, "DamRoll %d\n", pMobIndex->damroll ); if( pMobIndex->spec_fun && pMobIndex->spec_funname ) fprintf( fp, "Special %s\n", pMobIndex->spec_funname ); if( pMobIndex->pShop ) { int stype; fprintf( fp, "NShop %d %d %d %d ", pMobIndex->pShop->profit_buy, pMobIndex->pShop->profit_sell, pMobIndex->pShop->open_hour, pMobIndex->pShop->close_hour ); for( stype = 0; stype < ITEM_TYPE_MAX; stype++ ) if( pMobIndex->pShop->buy_type[stype] ) fprintf( fp, " %s", o_types[stype] ); fprintf( fp, "%s", "~\n" ); } if( pMobIndex->rShop ) { int stype; fprintf( fp, "NRepair %d %d %d ", pMobIndex->rShop->profit_fix, pMobIndex->rShop->open_hour, pMobIndex->rShop->close_hour ); for( stype = 0; stype < ITEM_TYPE_MAX; stype++ ) if( pMobIndex->rShop->fix_type[stype] ) fprintf( fp, " %s", o_types[stype] ); fprintf( fp, "%s", "~\n" ); } if( pMobIndex->mudprogs ) { int count = 0; for( mprog = pMobIndex->mudprogs; mprog; mprog = mprog->next ) count = save_programs( mprog, fp ); if( count > 0 ) fprintf( fp, "%s", "|\n" ); } fprintf( fp, "End\n\n" ); } if( !first ) fprintf( fp, "#0\n\n\n" ); /* save objects */ first = true; for( vnum = tarea->low_vnum; vnum <= tarea->hi_vnum; vnum++ ) { if( !( pObjIndex = get_obj_index( vnum ) ) ) continue; if( first ) fprintf( fp, "#OBJECTS\n" ); first = false; if( install ) xREMOVE_BIT( pObjIndex->extra_flags, ITEM_PROTOTYPE ); fprintf( fp, "Vnum %d\n", vnum ); if( pObjIndex->level ) fprintf( fp, "Level %d\n", pObjIndex->level ); fprintf( fp, "%s", "Stats " ); for( stat = 0; stat < STAT_MAX; stat++ ) fprintf( fp, " %d", pObjIndex->stat_reqs[stat] ); fprintf( fp, "%s", "\n" ); if( pObjIndex->name ) fprintf( fp, "Name %s~\n", strip_cr( pObjIndex->name ) ); if( pObjIndex->short_descr ) fprintf( fp, "Short %s~\n", strip_cr( pObjIndex->short_descr ) ); if( pObjIndex->description ) fprintf( fp, "Description\n%s~\n", strip_cr( pObjIndex->description ) ); if( pObjIndex->action_desc ) fprintf( fp, "Action %s~\n", strip_cr( pObjIndex->action_desc ) ); fprintf( fp, "Type %s~\n", o_types[pObjIndex->item_type] ); if( !xIS_EMPTY( pObjIndex->extra_flags ) ) fprintf( fp, "Flags %s~\n", ext_flag_string( &pObjIndex->extra_flags, o_flags ) ); if( !xIS_EMPTY( pObjIndex->wear_flags ) ) fprintf( fp, "Wear %s~\n", ext_flag_string( &pObjIndex->wear_flags, w_flags ) ); if( pObjIndex->layers ) fprintf( fp, "Layers %d\n", pObjIndex->layers ); if( !xIS_EMPTY( pObjIndex->class_restrict ) ) fprintf( fp, "Classes %s~\n", ext_class_string( &pObjIndex->class_restrict ) ); if( !xIS_EMPTY( pObjIndex->race_restrict ) ) fprintf( fp, "Races %s~\n", ext_race_string( &pObjIndex->race_restrict ) ); val0 = pObjIndex->value[0]; val1 = pObjIndex->value[1]; val2 = pObjIndex->value[2]; val3 = pObjIndex->value[3]; val4 = pObjIndex->value[4]; val5 = pObjIndex->value[5]; switch( pObjIndex->item_type ) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: if( !is_valid_sn( val1 ) ) val1 = HAS_SPELL_INDEX; if( !is_valid_sn( val2 ) ) val2 = HAS_SPELL_INDEX; if( !is_valid_sn( val3 ) ) val3 = HAS_SPELL_INDEX; break; case ITEM_STAFF: case ITEM_WAND: if( !is_valid_sn( val3 ) ) val3 = HAS_SPELL_INDEX; break; case ITEM_SALVE: if( !is_valid_sn( val3 ) ) val3 = HAS_SPELL_INDEX; if( !is_valid_sn( val4 ) ) val4 = HAS_SPELL_INDEX; if( !is_valid_sn( val5 ) ) val5 = HAS_SPELL_INDEX; break; } if( val0 ) fprintf( fp, "Val0 %d\n", val0 ); if( val1 ) { fprintf( fp, "Val1 %d ", val1 ); if( pObjIndex->item_type == ITEM_PILL || pObjIndex->item_type == ITEM_POTION || pObjIndex->item_type == ITEM_SCROLL ) fprintf( fp, "'%s'", is_valid_sn( val1 ) ? skill_table[val1]->name : "NONE" ); fprintf( fp, "%s", "\n" ); } if( val2 ) { fprintf( fp, "Val2 %d ", val2 ); if( pObjIndex->item_type == ITEM_PILL || pObjIndex->item_type == ITEM_POTION || pObjIndex->item_type == ITEM_SCROLL ) fprintf( fp, "'%s'", is_valid_sn( val2 ) ? skill_table[val2]->name : "NONE" ); fprintf( fp, "%s", "\n" ); } if( val3 ) { fprintf( fp, "Val3 %d ", val3 ); switch( pObjIndex->item_type ) { case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: case ITEM_STAFF: case ITEM_WAND: case ITEM_SALVE: fprintf( fp, "'%s'", is_valid_sn( val3 ) ? skill_table[val3]->name : "NONE" ); break; } fprintf( fp, "%s", "\n" ); } if( val4 ) { fprintf( fp, "Val4 %d ", val4 ); if( pObjIndex->item_type == ITEM_SALVE ) fprintf( fp, "'%s'", is_valid_sn( val4 ) ? skill_table[val4]->name : "NONE" ); fprintf( fp, "%s", "\n" ); } if( val5 ) { fprintf( fp, "Val5 %d ", val5 ); if( pObjIndex->item_type == ITEM_SALVE ) fprintf( fp, "'%s'", is_valid_sn( val5 ) ? skill_table[val5]->name : "NONE" ); fprintf( fp, "%s", "\n" ); } if( pObjIndex->weight ) fprintf( fp, "Weight %d\n", pObjIndex->weight ); if( pObjIndex->cost ) fprintf( fp, "Cost %d\n", pObjIndex->cost ); for( ed = pObjIndex->first_extradesc; ed; ed = ed->next ) fprintf( fp, "E\n%s~\n%s~\n", ed->keyword, strip_cr( ed->description ) ); for( paf = pObjIndex->first_affect; paf; paf = paf->next ) { fprintf( fp, "%s", "Affect " ); if( paf->location >= 0 && paf->location < APPLY_MAX ) fprintf( fp, "'%s'", a_types[paf->location] ); else fprintf( fp, "'%d'", paf->location ); if( paf->location == APPLY_EXT_AFFECT && paf->modifier >= 0 && paf->modifier < AFF_MAX ) fprintf( fp, " '%s'", a_flags[paf->modifier] ); else if( paf->location >= APPLY_RESISTANT && paf->location <= APPLY_SUSCEPTIBLE && paf->modifier >= 0 && paf->modifier < RIS_MAX ) fprintf( fp, " '%s'", ris_flags[paf->modifier] ); else if( ( paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN ) && is_valid_sn( paf->modifier ) ) fprintf( fp, " '%d'", skill_table[paf->modifier]->slot ); else fprintf( fp, " '%d'", paf->modifier ); fprintf( fp, "%s", "\n" ); } if( pObjIndex->mudprogs ) { int count = 0; for( mprog = pObjIndex->mudprogs; mprog; mprog = mprog->next ) count = save_programs( mprog, fp ); if( count > 0 ) fprintf( fp, "%s", "|\n" ); } fprintf( fp, "%s", "End\n\n" ); } if( !first ) fprintf( fp, "%s", "#0\n\n\n" ); /* save rooms */ first = true; for( vnum = tarea->low_vnum; vnum <= tarea->hi_vnum; vnum++ ) { if( !( room = get_room_index( vnum ) ) ) continue; if( first ) fprintf( fp, "#ROOMS\n" ); first = false; if( install ) { CHAR_DATA *victim, *vnext; OBJ_DATA *obj, *obj_next; /* purge room of (prototyped) mobiles */ for( victim = room->first_person; victim; victim = vnext ) { vnext = victim->next_in_room; if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) ) extract_char( victim, true ); } /* purge room of (prototyped) objects */ for( obj = room->first_content; obj; obj = obj_next ) { obj_next = obj->next_content; if( xIS_SET( obj->extra_flags, ITEM_PROTOTYPE ) ) extract_obj( obj ); } } fprintf( fp, "Vnum %d\n", vnum ); if( room->name ) fprintf( fp, "Name %s~\n", strip_cr( room->name ) ); if( room->description ) fprintf( fp, "Description %s~\n", strip_cr( room->description ) ); if( !xIS_EMPTY( room->room_flags ) ) fprintf( fp, "Flags %s~\n", ext_flag_string( &room->room_flags, r_flags ) ); if( room->sector_type ) fprintf( fp, "Sector %s~\n", sect_flags[room->sector_type] ); if( room->tele_delay ) fprintf( fp, "Teledelay %d\n", room->tele_delay ); if( room->tele_vnum ) fprintf( fp, "Televnum %d\n", room->tele_vnum ); if( room->tunnel ) fprintf( fp, "Tunnel %d\n", room->tunnel ); for( xit = room->first_exit; xit; xit = xit->next ) { bool bashed = false; if( xIS_SET( xit->exit_info, EX_PORTAL ) ) /* don't save portals */ continue; if( xIS_SET( xit->exit_info, EX_MCREATED ) ) /* don't save mob created exits */ continue; fprintf( fp, "Exit %s\n", dir_name[xit->vdir] ); if( xit->description && xit->description[0] != '\0' ) fprintf( fp, "Description %s~\n", strip_cr( xit->description ) ); if( xit->keyword && xit->keyword[0] != '\0' ) fprintf( fp, "Keyword %s~\n", strip_cr( xit->keyword ) ); if( xIS_SET( xit->exit_info, EX_BASHED ) ) bashed = true; xREMOVE_BIT( xit->exit_info, EX_BASHED ); if( !xIS_EMPTY( xit->exit_info ) ) fprintf( fp, "Flags %s~\n", ext_flag_string( &xit->exit_info, ex_flags ) ); if( bashed ) xSET_BIT( xit->exit_info, EX_BASHED ); if( xit->key >= 0 ) fprintf( fp, "Key %d\n", xit->key ); if( xit->vnum ) fprintf( fp, "To %d\n", xit->vnum ); if( xit->pulltype ) fprintf( fp, "Pulltype %s~\n", pull_type_name( xit->pulltype ) ); if( xit->pull ) fprintf( fp, "Pull %d\n", xit->pull ); fprintf( fp, "%s", "End\n" ); } for( pReset = room->first_reset; pReset; pReset = pReset->next ) { switch( pReset->command ) /* extra arg1 arg2 arg3 */ { default: case '*': break; case 'm': case 'M': case 'o': case 'O': fprintf( fp, "R %c %d %d %d %d %d\n", UPPER( pReset->command ), pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3, pReset->rchance ); for( tReset = pReset->first_reset; tReset; tReset = tReset->next_reset ) { switch( tReset->command ) { case 'p': case 'P': case 'e': case 'E': fprintf( fp, " NR %c %d %d %d %d %d\n", UPPER( tReset->command ), tReset->extra, tReset->arg1, tReset->arg2, tReset->arg3, tReset->rchance ); if( tReset->first_reset ) { for( gReset = tReset->first_reset; gReset; gReset = gReset->next_reset ) { if( gReset->command != 'p' && gReset->command != 'P' ) continue; fprintf( fp, " NR %c %d %d %d %d %d\n", UPPER( gReset->command ), gReset->extra, gReset->arg1, gReset->arg2, gReset->arg3, gReset->rchance ); } } break; case 'g': case 'G': fprintf( fp, " NR %c %d %d %d %d\n", UPPER( tReset->command ), tReset->extra, tReset->arg1, tReset->arg2, tReset->rchance ); if( tReset->first_reset ) { for( gReset = tReset->first_reset; gReset; gReset = gReset->next_reset ) { if( gReset->command != 'p' && gReset->command != 'P' ) continue; fprintf( fp, " NR %c %d %d %d %d %d\n", UPPER( gReset->command ), gReset->extra, gReset->arg1, gReset->arg2, gReset->arg3, gReset->rchance ); } } break; case 't': case 'T': case 'h': case 'H': fprintf( fp, " NR %c %d %d %d %d %d\n", UPPER( tReset->command ), tReset->extra, tReset->arg1, tReset->arg2, tReset->arg3, tReset->rchance ); break; } } break; case 'd': case 'D': case 't': case 'T': case 'h': case 'H': fprintf( fp, "NR %c %d %d %d %d %d\n", UPPER( pReset->command ), pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3, pReset->rchance ); break; case 'r': case 'R': fprintf( fp, "NR %c %d %d %d %d\n", UPPER( pReset->command ), pReset->extra, pReset->arg1, pReset->arg2, pReset->rchance ); break; } } for( ed = room->first_extradesc; ed; ed = ed->next ) fprintf( fp, "E\n%s~\n%s~\n", ed->keyword, strip_cr( ed->description ) ); if( room->mudprogs ) { int count = 0; for( mprog = room->mudprogs; mprog; mprog = mprog->next ) count = save_programs( mprog, fp ); if( count > 0 ) fprintf( fp, "%s", "|\n" ); } fprintf( fp, "End\n\n" ); } if( !first ) fprintf( fp, "#0\n\n\n" ); /* END */ fprintf( fp, "#$\n" ); fclose( fp ); fp = NULL; rename( tempfilename, newfilename ); return true; } CMDF( do_savearea ) { AREA_DATA *tarea; char filename[256]; set_char_color( AT_IMMORT, ch ); if( is_npc( ch ) || !ch->pcdata || ( ( !argument || argument[0] == '\0' ) && !ch->pcdata->area ) || ( get_trust( ch ) < PERM_LEADER && !ch->pcdata->area ) ) { send_to_char( "You don't have an assigned area to save.\r\n", ch ); return; } if( !argument || argument[0] == '\0' || get_trust( ch ) < PERM_LEADER ) tarea = ch->pcdata->area; else { bool found = false; if( get_trust( ch ) < PERM_LEADER ) { send_to_char( "You can only save your own area.\r\n", ch ); return; } for( tarea = first_build; tarea; tarea = tarea->next ) { if( !str_cmp( tarea->filename, argument ) ) { found = true; break; } } if( !found ) { send_to_char( "Area not found.\r\n", ch ); return; } } if( !tarea ) { send_to_char( "No area to save.\r\n", ch ); return; } /* Ensure not wiping out their area with save before load - Scryn 8/11 */ if( !IS_SET( tarea->status, AREA_LOADED ) ) { send_to_char( "Your area is not loaded!\r\n", ch ); return; } if( !xIS_SET( tarea->flags, AFLAG_PROTOTYPE ) ) { ch_printf( ch, "Can't savearea %s, use foldarea instead.\r\n", tarea->filename ); return; } snprintf( filename, sizeof( filename ), "%s", tarea->filename ); ch_printf( ch, "Saving area %s...\r\n", tarea->filename ); fold_area( tarea, filename, false ); set_char_color( AT_IMMORT, ch ); send_to_char( "Finished saving the area.\r\n", ch ); } /* * Dangerous command. Can be used to install an area that was either: * (a) already installed but removed from area.lst * (b) designed offline * The mud will likely crash if: * (a) this area is already loaded * (b) it contains vnums that exist * (c) the area has errors * * NOTE: Use of this command is not recommended. -Thoric */ CMDF( do_unfoldarea ) { set_char_color( AT_IMMORT, ch ); if( !argument || argument[0] == '\0' ) { send_to_char( "Unfold what?\r\n", ch ); return; } fBootDb = true; load_area_file( last_area, argument ); fBootDb = false; } CMDF( do_foldarea ) { AREA_DATA *tarea; set_char_color( AT_IMMORT, ch ); if( is_npc( ch ) || !ch->pcdata || ( ( !argument || argument[0] == '\0' ) && !ch->pcdata->area ) || ( get_trust( ch ) < PERM_LEADER && !ch->pcdata->area ) ) { send_to_char( "You don't have an assigned area to fold.\r\n", ch ); return; } if( argument[0] == '\0' || get_trust( ch ) < PERM_LEADER ) tarea = ch->pcdata->area; else { bool found = false; if( get_trust( ch ) < PERM_LEADER ) { send_to_char( "You can only save your own area.\r\n", ch ); return; } for( tarea = first_area; tarea; tarea = tarea->next ) { if( !str_cmp( tarea->filename, argument ) ) { found = true; break; } } if( !found ) { send_to_char( "Area not found.\r\n", ch ); return; } } if( !tarea ) { send_to_char( "No area to fold.\r\n", ch ); return; } if( xIS_SET( tarea->flags, AFLAG_PROTOTYPE ) ) { ch_printf( ch, "Can't foldarea %s, use savearea instead.\r\n", tarea->filename ); return; } send_to_char( "Folding area...\r\n", ch ); fold_area( tarea, tarea->filename, false ); set_char_color( AT_IMMORT, ch ); send_to_char( "Done.\r\n", ch ); } extern int top_area; void write_area_list( void ) { AREA_DATA *tarea; FILE *fp; if( !( fp = fopen( AREA_LIST, "w" ) ) ) { bug( "FATAL: can't open %s for writing!", AREA_LIST ); return; } for( tarea = first_area; tarea; tarea = tarea->next ) fprintf( fp, "%s\n", tarea->filename ); fprintf( fp, "$\n" ); fclose( fp ); fp = NULL; } /* * A complicated to use command as it currently exists. -Thoric * Once area->author and area->name are cleaned up... it will be easier */ CMDF( do_installarea ) { AREA_DATA *tarea; char arg[MIL], buf[MSL]; int num; DESCRIPTOR_DATA *d; set_char_color( AT_IMMORT, ch ); argument = one_argument( argument, arg ); if( !arg || arg[0] == '\0' ) { send_to_char( "Usage: installarea <filename> [Area title]\r\n", ch ); return; } for( tarea = first_build; tarea; tarea = tarea->next ) { if( !str_cmp( tarea->filename, arg ) ) { if( argument && argument[0] != '\0' ) { STRSET( tarea->name, argument ); } /* Fold area with install flag -- auto-removes prototype flags */ send_to_char( "Saving and installing file...\r\n", ch ); if( !( fold_area( tarea, tarea->filename, true ) ) ) { send_to_char( "There was a problem in folding the area...\r\n", ch ); return; } /* Remove from prototype area list */ UNLINK( tarea, first_build, last_build, next, prev ); /* Add to real area list */ LINK( tarea, first_area, last_area, next, prev ); /* Remove it from the prototype sort list. BUGFIX: Samson 4-15-03 */ UNLINK( tarea, first_bsort, last_bsort, next_sort, prev_sort ); /* Sort the area into it's proper sort list. BUGFIX: Samson 4-15-03 */ sort_area( tarea, false ); /* Don't forget to update the list */ sort_area_by_name( tarea ); /* Fix up author if online */ for( d = first_descriptor; d; d = d->next ) { if( d->character && d->character->pcdata && d->character->pcdata->area == tarea ) { /* remove area from author */ d->character->pcdata->area = NULL; /* clear out author vnums */ d->character->pcdata->range_lo = 0; d->character->pcdata->range_hi = 0; save_char_obj( d->character ); } } top_area++; send_to_char( "Writing area.lst...\r\n", ch ); write_area_list( ); send_to_char( "Resetting new area.\r\n", ch ); num = tarea->nplayer; tarea->nplayer = 0; reset_area( tarea ); tarea->nplayer = num; send_to_char( "Renaming author's building file.\r\n", ch ); snprintf( buf, sizeof( buf ), "%s%s.installed", BUILD_DIR, tarea->filename ); snprintf( arg, sizeof( arg ), "%s%s", BUILD_DIR, tarea->filename ); rename( arg, buf ); send_to_char( "Done.\r\n", ch ); return; } } send_to_char( "No such area exists.\r\n", ch ); } CMDF( do_astat ) { AREA_DATA *tarea; bool proto = false, found = false; set_char_color( AT_PLAIN, ch ); tarea = ch->in_room->area; if( argument && argument[0] != '\0' ) { for( tarea = first_area; tarea; tarea = tarea->next ) { if( !str_cmp( tarea->filename, argument ) ) { found = true; break; } } if( !found ) { for( tarea = first_build; tarea; tarea = tarea->next ) { if( !str_cmp( tarea->filename, argument ) ) { found = true; proto = true; break; } } } if( !found ) { send_to_char( "Area not found. Check 'zones'.\r\n", ch ); return; } } ch_printf( ch, "\r\n&wName: &W%s\r\n", tarea->name ); ch_printf( ch, "&wFilename: &W%-20s\r\n", tarea->filename ); ch_printf( ch, "&wPrototype: &W%s\r\n", proto ? "yes" : "no" ); ch_printf( ch, "&wAuthor: &W%s\r\n", tarea->author ); ch_printf( ch, "&wAge: &W%-3d\r\n", tarea->age ); ch_printf( ch, "&wPlayers: &W%10d &wMax: &W%d\r\n", tarea->nplayer, tarea->max_players ); ch_printf( ch, "&wVnum range: &W%10d &w- &W%d\r\n", tarea->low_vnum, tarea->hi_vnum ); ch_printf( ch, "&wSoft range: &W%10d &w- &W%d\r\n", tarea->low_soft_range, tarea->hi_soft_range ); ch_printf( ch, "&wHard range: &W%10d &w- &W%d\r\n", tarea->low_hard_range, tarea->hi_hard_range ); ch_printf( ch, "&wArea flags: &W%s\r\n", ext_flag_string( &tarea->flags, area_flags ) ); ch_printf( ch, "&wResetmsg: &W%s\r\n", tarea->resetmsg ? tarea->resetmsg : "(default)" ); /* Rennard */ ch_printf( ch, "&wReset frequency: &W%d &wminutes.\r\n", tarea->reset_frequency ? tarea->reset_frequency : 15 ); } /* check other areas for a conflict while ignoring the current area */ bool check_for_area_conflicts( AREA_DATA *carea, int lo, int hi ) { AREA_DATA *area; for( area = first_area; area; area = area->next ) if( area != carea && check_area_conflict( area, lo, hi ) ) return true; for( area = first_build; area; area = area->next ) if( area != carea && check_area_conflict( area, lo, hi ) ) return true; return false; } void do_aset( CHAR_DATA *ch, char *argument ) { AREA_DATA *tarea; char arg1[MIL], arg2[MIL], arg3[MIL]; bool proto, found; int vnum, value; set_char_color( AT_IMMORT, ch ); argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); vnum = atoi( argument ); if( arg1[0] == '\0' || arg2[0] == '\0' ) { send_to_char( "Usage: aset <area filename> <field> <value>\r\n", ch ); send_to_char( "\r\nField being one of:\r\n", ch ); send_to_char( " low_vnum hi_vnum low_soft hi_soft low_hard hi_hard\r\n", ch ); send_to_char( " name filename author resetmsg resetfreq flags\r\n", ch ); return; } found = false; proto = false; for( tarea = first_area; tarea; tarea = tarea->next ) { if( !str_cmp( tarea->filename, arg1 ) ) { found = true; break; } } if( !found ) { for( tarea = first_build; tarea; tarea = tarea->next ) { if( !str_cmp( tarea->filename, arg1 ) ) { found = true; proto = true; break; } } } if( !found ) { send_to_char( "Area not found.\r\n", ch ); return; } if( !str_cmp( arg2, "name" ) ) { AREA_DATA *uarea; if( !argument || argument[0] == '\0' ) { send_to_char( "You can't set an area's name to nothing.\r\n", ch ); return; } for( uarea = first_area; uarea; uarea = uarea->next ) { if( !str_cmp( uarea->name, argument ) ) { send_to_char( "There is already an installed area with that name.\r\n", ch ); return; } } for( uarea = first_build; uarea; uarea = uarea->next ) { if( !str_cmp( uarea->name, argument ) ) { send_to_char( "There is already a prototype area with that name.\r\n", ch ); return; } } STRSET( tarea->name, argument ); send_to_char( "Done.\r\n", ch ); return; } if( !str_cmp( arg2, "filename" ) ) { char filename[256], newfilename[256]; if( proto ) { send_to_char( "You should only change the filename of installed areas.\r\n", ch ); return; } if( !argument || argument[0] == '\0' ) { send_to_char( "You can't set an area's filename to nothing.\r\n", ch ); return; } if( strstr( argument, "." ) ) { send_to_char( "You can't use a . in area filenames. (.are) is added onto the end automatically.\r\n", ch ); return; } snprintf( newfilename, sizeof( newfilename ), "%s.are", argument ); if( !can_use_path( ch, AREA_DIR, newfilename ) ) return; snprintf( filename, sizeof( filename ), "%s%s", AREA_DIR, tarea->filename ); STRSET( tarea->filename, newfilename ); snprintf( newfilename, sizeof( newfilename ), "%s%s", AREA_DIR, tarea->filename ); rename( filename, newfilename ); write_area_list( ); send_to_char( "Done.\r\n", ch ); return; } if( !str_cmp( arg2, "low_vnum" ) ) { if( check_for_area_conflicts( tarea, tarea->low_vnum, vnum ) ) { send_to_char( "That would conflict with another area.\r\n", ch ); return; } if( tarea->hi_vnum < vnum ) { send_to_char( "Can't set low_vnum higher than the hi_vnum.\r\n", ch ); return; } tarea->low_vnum = vnum; ch_printf( ch, "Low_vnum set to %d.\r\n", tarea->low_vnum ); return; } if( !str_cmp( arg2, "hi_vnum" ) ) { if( check_for_area_conflicts( tarea, tarea->hi_vnum, vnum ) ) { send_to_char( "That would conflict with another area.\r\n", ch ); return; } if( tarea->low_vnum > vnum ) { send_to_char( "Can't set hi_vnum lower than the low_vnum.\r\n", ch ); return; } tarea->hi_vnum = vnum; ch_printf( ch, "Hi_vnum set to %d.\r\n", tarea->hi_vnum ); return; } if( !str_cmp( arg2, "low_soft" ) ) { tarea->low_soft_range = URANGE( 0, vnum, MAX_LEVEL ); ch_printf( ch, "Low_soft set to level %d.\r\n", tarea->low_soft_range ); return; } if( !str_cmp( arg2, "hi_soft" ) ) { tarea->hi_soft_range = URANGE( 0, vnum, MAX_LEVEL ); ch_printf( ch, "Hi_soft set to level %d.\r\n", tarea->hi_soft_range ); return; } if( !str_cmp( arg2, "low_hard" ) ) { tarea->low_hard_range = URANGE( 0, vnum, MAX_LEVEL ); ch_printf( ch, "Low_hard set to level %d.\r\n", tarea->low_hard_range ); return; } if( !str_cmp( arg2, "hi_hard" ) ) { tarea->hi_hard_range = URANGE( 0, vnum, MAX_LEVEL ); ch_printf( ch, "Hi_hard set to level %d.\r\n", tarea->hi_hard_range ); return; } if( !str_cmp( arg2, "author" ) ) { STRSET( tarea->author, argument ); ch_printf( ch, "Author set to %s.\r\n", tarea->author ? tarea->author : "(Nothing)" ); return; } if( !str_cmp( arg2, "resetmsg" ) ) { STRSET( tarea->resetmsg, argument ); ch_printf( ch, "Resetmsg set to %s.\r\n", tarea->resetmsg ? tarea->resetmsg : "(Nothing)" ); return; } if( !str_cmp( arg2, "resetfreq" ) ) { tarea->reset_frequency = UMAX( 0, vnum ); ch_printf( ch, "Resetfreq set to %d.\r\n", tarea->reset_frequency ); return; } if( !str_cmp( arg2, "flags" ) ) { if( !argument || argument[0] == '\0' ) { send_to_char( "Usage: aset <filename> flags <flag> [flag]...\r\n", ch ); return; } while( argument[0] != '\0' ) { argument = one_argument( argument, arg3 ); value = get_flag( arg3, area_flags, AFLAG_MAX ); if( value < 0 || value >= AFLAG_MAX ) ch_printf( ch, "Unknown flag: %s\r\n", arg3 ); else xTOGGLE_BIT( tarea->flags, value ); } ch_printf( ch, "Flags set to %s.\r\n", ext_flag_string( &tarea->flags, area_flags ) ); return; } do_aset( ch, "" ); } /* List stuff in the range for which ever */ /* * 0 = rooms * 1 = objects * 2 = mobiles * 3 and higher does all three */ void do_arealist( CHAR_DATA *ch, short type, char *argument ) { ROOM_INDEX_DATA *room; OBJ_INDEX_DATA *obj; MOB_INDEX_DATA *mob; char arg1[MIL], arg2[MIL]; AREA_DATA *tarea; int vnum, lrange, trange; bool free = false; set_pager_color( AT_PLAIN, ch ); if( is_npc( ch ) || !ch->pcdata || ( !ch->pcdata->area && get_trust( ch ) < PERM_LEADER ) ) { send_to_char( "&YYou don't have an assigned area.\r\n", ch ); return; } tarea = ch->pcdata->area; if( !tarea && ch->in_room && ch->in_room->area ) tarea = ch->in_room->area; argument = one_argument( argument, arg1 ); if( !is_number( arg1 ) && !str_cmp( arg1, "free" ) ) { free = true; argument = one_argument( argument, arg1 ); } argument = one_argument( argument, arg2 ); lrange = ( arg1 && arg1[0] != '\0' && is_number( arg1 ) ? atoi( arg1 ) : tarea ? tarea->low_vnum : -1 ); trange = ( arg2 && arg2[0] != '\0' && is_number( arg2 ) ? atoi( arg2 ) : tarea ? tarea->hi_vnum : -1 ); if( tarea && ( lrange < tarea->low_vnum || trange > tarea->hi_vnum ) && get_trust( ch ) < PERM_LEADER ) { send_to_char( "&YThat is out of your vnum range.\r\n", ch ); return; } if( lrange <= 0 && trange <= 0 ) { send_to_char( "&YYou have to specify a low and high vnum and they have to be above 0.\r\n", ch ); return; } if( trange <= lrange ) { send_to_char( "&YThe first vnum should be lower then the second. EXAMPLE ( 400 500 ).\r\n", ch ); return; } if( !tarea && ( trange - lrange ) > 1000 ) { send_to_char( "&YLimiting the amount of stuff shown to 1000 possible vnums...\r\n", ch ); trange = ( lrange + 1000 ); } pager_printf( ch, "Displaying %svnums %d to %d.\r\n", free ? "free " : "", lrange, trange ); for( vnum = lrange; vnum <= trange; vnum++ ) { if( !free ) { if( ( type == 0 || type > 2 ) && ( room = get_room_index( vnum ) ) ) pager_printf( ch, "%s%5d) %s\r\n", type > 2 ? "ROOM #" : "", vnum, room->name ); if( ( type == 1 || type > 2 ) && ( obj = get_obj_index( vnum ) ) ) pager_printf( ch, "%s%5d) %-20s (%s)\r\n", type > 2 ? "OBJECT #" : "", vnum, obj->name, obj->short_descr ); if( ( type == 2 || type > 2 ) && ( mob = get_mob_index( vnum ) ) ) pager_printf( ch, "%s%5d) %-20s (%s)\r\n", type > 2 ? "MOBILE #" : "", vnum, mob->name, mob->short_descr ); } else { if( ( type == 0 || type > 2 ) && !( room = get_room_index( vnum ) ) ) pager_printf( ch, "%s%5d)\r\n", type > 2 ? "ROOM #" : "", vnum ); if( ( type == 1 || type > 2 ) && !( obj = get_obj_index( vnum ) ) ) pager_printf( ch, "%s%5d)\r\n", type > 2 ? "OBJECT #" : "", vnum ); if( ( type == 2 || type > 2 ) && !( mob = get_mob_index( vnum ) ) ) pager_printf( ch, "%s%5d)\r\n", type > 2 ? "MOBILE #" : "", vnum ); } } } CMDF( do_rlist ) { do_arealist( ch, 0, argument ); } CMDF( do_olist ) { do_arealist( ch, 1, argument ); } CMDF( do_mlist ) { do_arealist( ch, 2, argument ); } CMDF( do_vlist ) { do_arealist( ch, 3, argument ); }