/*___________________________________________________________________________*
)()( 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;
}
}
}