/*___________________________________________________________________________* )()( DalekenMUD 1.12 (C) 2000 )()( `][' by Martin Thomson, Lee Brooks, `][' || Ken Herbert and David Jacques || || ----------------------------------------------------------------- || || Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, || || David Love, Guilherme 'Willie' Arnold, and Mitchell Tse. || || Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael || || Chastain, Michael Quan, and Mitchell Tse. || || Original Diku Mud copyright (C) 1990, 1991 || || by Sebastian Hammer, Michael Seifert, Hans Henrik St{rfeldt, || || Tom Madsen, and Katja Nyboe. || || ----------------------------------------------------------------- || || Any use of this software must follow the licenses of the || || creators. Much time and thought has gone into this software and || || you are benefitting. We hope that you share your changes too. || || What goes around, comes around. || || ----------------------------------------------------------------- || || scriptsave.c || || Methods for saving a file for olc input. || *_/<>\_________________________________________________________________/<>\_*/ /* * This file was created to demonstrate the flexibility of the OLC system. * Using this file, you can create a file which contains a list of commands * that will successfully create a single area on a MUD that has similar OLC * syntax to that of Daleken. This script saver has been tested on both * Daleken and another Envy based MUD called Asgaard and it has been 99% * successful on both. * * Warning: this file may not work as it is not regularly tested. */ /* * If you want to save an area as an OLC script you will have to include this * file in your Makefile as well as adding the following line to interp.c: { "scriptsave", do_scriptsave, POS_DEAD, L_MAS, LOG_ALWAYS }, */ #include "mud.h" #include "olc.h" /* * Scriptsave, saves an area as an OLC script. * A cheat for those who would only build on one mud but have the * area in many places, without the work. */ #define SCRIPTSAVE_DALEKEN 1 #define SCRIPTSAVE_ASGAARD 2 void scriptsave_area args( ( FILE * fp, AREA_DATA * pArea, int shift, int type ) ); void scriptsave_objects args( ( FILE * fp, AREA_DATA * pArea, int shift, int type ) ); void scriptsave_mobiles args( ( FILE * fp, AREA_DATA * pArea, int shift, int type ) ); void scriptsave_rooms args( ( FILE * fp, AREA_DATA * pArea, int shift, int type ) ); void scriptsave_exits args( ( FILE * fp, AREA_DATA * pArea, int shift, int type ) ); void scriptsave_resets args( ( FILE *fp, RESET_DATA * pReset, int shift, int type ) ); /* * Scriptsave. * * Written by Symposium to allow builders who play multiple muds to * utilise the similarities with OLC by saving areas as an OLC script. * This means you can move areas to other mud which have strange area * formats. * New types can easily be added to suit your favourite mud(s). */ void do_scriptsave( CHAR_DATA *ch, const char *argument ) { CHAR_DATA *rch; FILE *fp; AREA_DATA *pArea; char comm[MAX_INPUT_LENGTH]; char filename[MAX_INPUT_LENGTH]; int vnum_shift = 0, type; rch = get_char( ch ); if( !authorized( rch, "scriptsave" ) ) return; argument = one_argument( argument, comm ); if( !str_cmp( comm, "daleken" ) ) { type = SCRIPTSAVE_DALEKEN; } else if( !str_cmp( comm, "asgaard" ) ) { type = SCRIPTSAVE_ASGAARD; } else { do_help( ch, "Scriptsave" ); return; } argument = one_argument( argument, comm ); if( !str_cmp( comm, "area" ) ) { pArea = get_editing_area( ch ); } else if( is_number( comm ) ) { pArea = get_area_data( atoi( comm ) ); } else { do_help( ch, "scriptsave" ); return; } if( !pArea ) { send_to_char( "Non-existant area.\n\r", ch ); return; } if( !IS_BUILDER( ch, pArea ) ) { send_to_char( "You are not a builder for this area.\n\r", ch ); return; } argument = one_argument( argument, comm ); if( !str_cmp( comm, "shift" ) ) { vnum_shift = atoi( argument ); if( vnum_shift % 100 != 0 ) { send_to_char( "Make the vnum shift a multiple of 100 please.\n\r", ch ); return; } } strcpy( filename, pArea->filename ); strcat( filename, ".olc" ); fp = open_file( filename, "w", FALSE ); if( !fp ) { bug( "Cannot open area file {%d}.", pArea->vnum ); return; } scriptsave_area( fp, pArea, vnum_shift, type ); scriptsave_objects( fp, pArea, vnum_shift, type ); scriptsave_mobiles( fp, pArea, vnum_shift, type ); scriptsave_rooms( fp, pArea, vnum_shift, type ); close_file( fp ); send_to_char( "Area saved.\n\r", ch ); return; } void scriptsave_area( FILE *fp, AREA_DATA * pArea, int shift, int type ) { char tmp[MAX_STRING_LENGTH]; fprintf( fp, "aedit\n" ); fprintf( fp, "name %s\n", pArea->name ); fprintf( fp, "vnum %d %d\n", pArea->lvnum + shift , pArea->uvnum + shift ); if( pArea->recall != ROOM_VNUM_TEMPLE ) fprintf( fp, "recall %d\n", pArea->recall ); switch( type ) { case SCRIPTSAVE_DALEKEN: fprintf( fp, "plane %s\n", pArea->plane ); if( pArea->repop && pArea->repop[0] ) fprintf( fp, "repop %s\n", fix_string( tmp, pArea->repop ) ); fprintf( fp, "temp %d\n", pArea->ave_temp ); if( ( pArea->area_flags & AREA_SAVE ) ) { int i = pArea->area_flags & AREA_SAVE; fprintf( fp, "%s\n", flag_string( area_flags, &i ) ); } break; case SCRIPTSAVE_ASGAARD: fprintf( fp, "plane %s\n", pArea->plane ); break; } fprintf( fp, "done\n\n" ); return; } void scriptsave_objects( FILE * fp, AREA_DATA * pArea, int shift, int type ) { int vnum; OBJ_INDEX_DATA *pObj; AFFECT_DATA *pAf; EXTRA_DESCR_DATA *pEd; char tmp[MAX_STRING_LENGTH]; fprintf( fp, "oedit\n" ); for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pObj = get_obj_index( vnum ) ) && pObj->area == pArea ) { fprintf( fp, "create %d\n", pObj->vnum + shift ); fprintf( fp, "name %s\n", pObj->name ); fprintf( fp, "short %s\n", pObj->short_descr ); fprintf( fp, "long %s\n", fix_string( tmp, pObj->description ) ); fprintf( fp, "level %d\n", pObj->level ); if( pObj->cost > 0 ) fprintf( fp, "cost %d\n", pObj->cost ); fprintf( fp, "weight %d\n", pObj->weight ); if( pObj->reset_chance < 1000 ) fprintf( fp, "repop %d\n", pObj->reset_chance ); fprintf( fp, "'%s\n", flag_string( type_flags, &pObj->item_type ) ); fprintf( fp, "%s\n", flag_string( wear_flags, &pObj->wear_flags ) ); fprintf( fp, "%s\n", flag_string( extra_flags, &pObj->extra_flags ) ); fprintf( fp, "%s\n", flag_string( material_flags, &pObj->material ) ); switch( type ) { case SCRIPTSAVE_DALEKEN: if( pObj->action && pObj->action[0] ) fprintf( fp, "action %s", fix_string( tmp, pObj->action ) ); if( pObj->required_skill > 0 ) fprintf( fp, "Required %s\n", skill_table[pObj->required_skill].name ); break; case SCRIPTSAVE_ASGAARD: break; } switch( pObj->item_type ) { default: case ITEM_FURNITURE: case ITEM_TRASH: case ITEM_KEY: case ITEM_BOAT: break; case ITEM_PORTAL: fprintf( fp, "v0 %d\n", pObj->value[0] + shift ); break; case ITEM_EXPLOSIVE: case ITEM_MONEY: case ITEM_TREASURE: fprintf( fp, "v0 %d\n", pObj->value[0] ); break; case ITEM_ARMOUR: fprintf( fp, "v1 %d\n", pObj->value[1] ); break; case ITEM_LIGHT: fprintf( fp, "v2 %d\n", pObj->value[2] ); break; case ITEM_STAFF: case ITEM_WAND: fprintf( fp, "v0 %d\nv1 %d\nv2 %d\nv3 %s\n", pObj->value[0], pObj->value[1], pObj->value[2], pObj->value > 0 ? skill_table[pObj->value[3]].name : "none" ); break; case ITEM_PLANT: if( type == SCRIPTSAVE_ASGAARD ) fprintf( fp, "say I created a plant\n" ); case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: fprintf( fp, "v0 %d\nv1 %s\nv2 %s\nv3 %s\n", pObj->value[0], pObj->value[1] > 0 ? skill_table[pObj->value[1]].name : "none", pObj->value[2] > 0 ? skill_table[pObj->value[2]].name : "none", pObj->value[3] > 0 ? skill_table[pObj->value[3]].name : "none" ); break; case ITEM_WEAPON: fprintf( fp, "v0 %s\nv3 %s\n", pObj->value[0] > 0 ? skill_table[pObj->value[0]].name : "none", flag_string( weapon_flags, &pObj->value[3] ) ); break; case ITEM_CORPSE_PC: case ITEM_CORPSE_NPC: if( type == SCRIPTSAVE_DALEKEN ) fprintf( fp, "v0 %s\n", race_table[pObj->value[0]].name ); break; case ITEM_CONTAINER: fprintf( fp, "v0 %d\nv1 %s\nv2 %d\n", pObj->value[0], flag_string( container_flags, &pObj->value[1] ), pObj->value[2] + shift ); break; case ITEM_DRINK_CON: fprintf( fp, "v0 %d\nv1 %d\n v2 %s\nv3 %d\n", pObj->value[0], pObj->value[1], flag_string( liquid_flags, &pObj->value[2] ), pObj->value[3] ); break; case ITEM_FOUNTAIN: fprintf( fp, "v2 %s\n", flag_string( liquid_flags, &pObj->value[2] ) ); break; case ITEM_FOOD: fprintf( fp, "v0 %d\nv3 %d\n", pObj->value[0], pObj->value[3] ); break; case ITEM_LIMB: if( type == SCRIPTSAVE_DALEKEN ) fprintf( fp, "v0 %s\n", flag_string( body_part_flags, &pObj->value[0] ) ); break; } for( pAf = pObj->affected; pAf; pAf = pAf->next ) { char temp[MAX_STRING_LENGTH]; strcpy( temp, flag_string( apply_flags, &pAf->location ) ); if( pAf->type == gsn_perm_spell ) fprintf( fp, "addperm %s\n", skill_table[pAf->location].name ); else if( type == SCRIPTSAVE_DALEKEN && ( !vnull( pAf->bitvector ) || pAf->type > 0 ) ) fprintf( fp, "addspell '%s' %s %d %s\n", skill_table[pAf->type].name, temp, pAf->modifier, flag_string( affect_flags, pAf->bitvector ) ); else fprintf( fp, "addaffect %s %d\n", temp, pAf->modifier ); } for( pEd = pObj->extra_descr; pEd; pEd = pEd->next ) { if( type == SCRIPTSAVE_DALEKEN ) fprintf( fp, "ed add %s\n", fix_string( tmp, pEd->keyword ) ); else fprintf( fp, "ed add '%s\n", fix_string( tmp, pEd->keyword ) ); fprintf( fp, "%s@\n", fix_string( tmp, pEd->description ) ); } } } fprintf( fp, "done\n\n" ); return; } void scriptsave_mobiles( FILE * fp, AREA_DATA * pArea, int shift, int type ) { int vnum; MOB_INDEX_DATA *pMob; char tmp[MAX_STRING_LENGTH]; fprintf( fp, "medit\n" ); for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pMob = get_mob_index( vnum ) ) && pMob->area == pArea ) { fprintf( fp, "create %d\n", pMob->vnum + shift ); fprintf( fp, "name %s\n", pMob->name ); fprintf( fp, "short %s\n", pMob->short_descr ); fprintf( fp, "long %s", fix_string( tmp, pMob->long_descr ) ); fprintf( fp, "desc\n%s@\n", fix_string( tmp, pMob->description ) ); fprintf( fp, "level %d\n", pMob->level ); fprintf( fp, "align %d\n", pMob->alignment ); if( pMob->reset_chance < 1000 ) fprintf( fp, "repop %d\n", pMob->reset_chance ); fprintf( fp, "%s\n", flag_string( act_flags, pMob->act ) ); fprintf( fp, "%s\n", flag_string( affect_flags, pMob->affected_by ) ); fprintf( fp, "%s\n", flag_string( sex_flags, &pMob->sex ) ); fprintf( fp, "%s\n", race_table[pMob->race].name ); if( pMob->spec_fun ) fprintf( fp, "specfun %s\n", spec_table[pMob->spec_fun].spec_name ); switch( type ) { case SCRIPTSAVE_DALEKEN: if( pMob->class != CLASS_NONE ) fprintf( fp, "class %s\n", flag_string( class_flags, &pMob->class ) ); if( pMob->body_parts != race_table[pMob->race].body_parts ) { int i = pMob->body_parts ^ race_table[pMob->race].body_parts; fprintf( fp, "%s\n", flag_string( body_part_flags, &i ) ); } break; case SCRIPTSAVE_ASGAARD: if( pMob->class != CLASS_NONE ) fprintf( fp, "%s\n", flag_string( class_flags, &pMob->class ) ); break; } if( pMob->pShop ) { int i; for( i = 0; i < MAX_TRADE; i++ ) if( pMob->pShop->buy_type[i] > 0 ) fprintf( fp, "shop type %d %s\n", i, flag_string( type_flags, &pMob->pShop->buy_type[i] ) ); fprintf( fp, "shop profit %d %d\n", pMob->pShop->profit_buy, pMob->pShop->profit_sell ); fprintf( fp, "shop hours %d %d\n", pMob->pShop->open_hour, pMob->pShop->close_hour ); } } } fprintf( fp, "done\n\n" ); return; } void scriptsave_rooms( FILE * fp, AREA_DATA * pArea, int shift, int type ) { ROOM_INDEX_DATA *pRoom; EXTRA_DESCR_DATA *pEd; int vnum; char tmp[MAX_STRING_LENGTH]; fprintf( fp, "redit\n" ); for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pRoom = get_room_index( vnum ) ) && pRoom->area == pArea ) { fprintf( fp, "create %d\n", pRoom->vnum + shift ); fprintf( fp, "goto %d\n", pRoom->vnum + shift ); fprintf( fp, "name %s\n", pRoom->name ); fprintf( fp, "desc\n%s@\n", fix_string( tmp, pRoom->description ) ); fprintf( fp, "%s\n", flag_string( room_flags, &pRoom->room_flags ) ); fprintf( fp, "%s\n", flag_string( sector_flags, &pRoom->sector_type ) ); for( pEd = pRoom->extra_descr; pEd; pEd = pEd->next ) { if( type == SCRIPTSAVE_DALEKEN ) fprintf( fp, "ed add %s\n", pEd->keyword ); else fprintf( fp, "ed add '%s\n", pEd->keyword ); fprintf( fp, "%s@\n", fix_string( tmp, pEd->description ) ); } scriptsave_resets( fp, pRoom->reset_first, shift, type ); } } scriptsave_exits( fp, pArea, shift, type ); fprintf( fp, "done\n\n" ); return; } void scriptsave_exits( FILE * fp, AREA_DATA * pArea, int shift, int type ) { ROOM_INDEX_DATA *pRoom; EXIT_DATA *pExit; int vnum; int door; char tmp[MAX_STRING_LENGTH]; for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pRoom = get_room_index( vnum ) ) && pRoom->area == pArea ) { fprintf( fp, "goto %d\n", pRoom->vnum + shift ); for( door = 0; door < MAX_DIR; door++ ) { if( ( pExit = pRoom->exit[door] ) && pExit->to_room ) { fprintf( fp, "%s room %d\n", dir_name[door], pExit->to_room->vnum + shift ); if( pExit->keyword && pExit->keyword[0] ) fprintf( fp, "%s name %s\n", dir_name[door], pExit->keyword ); if( pExit->description && pExit->description[0] ) fprintf( fp, "%s desc\n%s@\n", dir_name[door], fix_string( tmp, pExit->description ) ); if( pExit->key > 0 ) fprintf( fp, "%s key %d\n", dir_name[door], pExit->key + shift ); if( pExit->rs_flags != 0 && pExit->to_room->exit[rev_dir[door]] && pExit->to_room->exit[rev_dir[door]]->to_room == pRoom && pExit->to_room->vnum > pRoom->vnum ) fprintf( fp, "%s %s\n", dir_name[door], flag_string( exit_flags, &pExit->rs_flags ) ); } } } } return; } void scriptsave_resets( FILE *fp, RESET_DATA *pReset, int shift, int type ) { for( ; pReset; pReset = pReset->next ) { switch( pReset->command ) { case 'M': fprintf( fp, "reset 1000 mob %d %d\n", pReset->arg1 + shift, ( type != SCRIPTSAVE_DALEKEN && pReset->arg2 < 0 ) ? 0 : pReset->arg2 ); break; case 'O': fprintf( fp, "reset 1000 obj %d room\n", pReset->arg1 + shift ); break; case 'P': fprintf( fp, "reset 1000 obj %d in %d\n", pReset->arg1 + shift, pReset->arg2 + shift ); break; case 'G': case 'E': fprintf( fp, "reset 1000 obj %d %s\n", pReset->arg1 + shift, flag_string( wear_loc_flags, &pReset->arg2 ) ); break; case 'R': if( type != SCRIPTSAVE_DALEKEN ) break; if( pReset->arg1 == 0 ) fprintf( fp, "reset 1000 rand 0 %s\n", flag_string( direction_flags, &pReset->arg2 ) ); else fprintf( fp, "reset 1000 rand %d\n", pReset->arg1 ); break; case 'D': break; } } }