/**************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * 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. * ***************************************************************************/ /**************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ #if defined(macintosh) #include <types.h> #elif defined(WIN32) #include <sys/types.h> #include <time.h> #define NOCRYPT #else #include <sys/types.h> #include <sys/time.h> #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <time.h> #include "merc.h" #include "interp.h" #include "magic.h" #include "recycle.h" #include "tables.h" #include "lookup.h" #include "olc.h" #include "const.h" int const_lookup args ( (const char *name ) ); #define DIF(a,b) (~((~a)|(b))) /*stuff to set up key*/ #define KEY( literal, field, value ) if ( !str_cmp( word, literal ) ) { field = value; fMatch = TRUE; break; } /* provided to free strings */ #if defined(KEYS) #undef KEYS #endif #define KEYS( literal, field, value ) if ( !str_cmp( word, literal ) ) { free_string(field); field = value; fMatch = TRUE; break; } /*end stuff for key*/ /***************************************************************************** Name: fwrite_rooms Purpose: Save #ROOMS section of an area file. Called by: save_area(olc_save.c). ****************************************************************************/ void fwrite_rooms( FILE *fp, AREA_DATA *pArea ) { ROOM_INDEX_DATA *pRoomIndex; EXTRA_DESCR_DATA *pEd; EXIT_DATA *pExit; int iHash; int door; PROG_LIST *pRprog; char buf[MSL]; fprintf( fp, "#ROOMSNEW\n" ); for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) { for( pRoomIndex = room_index_hash[iHash]; pRoomIndex; pRoomIndex = pRoomIndex->next ) { if ( pRoomIndex->area == pArea ) { fprintf( fp, "#ROOM\n" ); fprintf( fp, "Vnum %d\n", pRoomIndex->vnum ); fprintf( fp, "Name %s~\n", pRoomIndex->name ); fprintf( fp, "Desc %s~\n", fix_string( pRoomIndex->description ) ); fprintf( fp, "Room_flags %d\n", pRoomIndex->room_flags ); fprintf( fp, "Sector_type %d\n", pRoomIndex->sector_type ); fprintf ( fp, "X %d %d %d %d %d %d %d %d %d %d %d\n", pRoomIndex->mineral[MIN_STEEL], pRoomIndex->mineral[MIN_IRON], pRoomIndex->mineral[MIN_COPPER], pRoomIndex->mineral[MIN_ADAMANTIUM], pRoomIndex->mineral[MIN_PLATINUM], pRoomIndex->mineral[MIN_BRONZE], pRoomIndex->mineral[MIN_SILVER], pRoomIndex->mineral[MIN_MARBLE], pRoomIndex->mineral[MIN_BRASS], pRoomIndex->mineral[MIN_GRANITE], pRoomIndex->mineral[MIN_ELECTRUM]); for ( pEd = pRoomIndex->extra_descr; pEd; pEd = pEd->next ) { fprintf( fp, "ExtraDesc\n"); fprintf( fp, "%s~\n",pEd->keyword ); fprintf( fp, "%s~\n", fix_string( pEd->description ) ); } for( door = 0; door < MAX_DIR; door++ ) /* I hate this! */ { if ( ( pExit = pRoomIndex->exit[door] ) && pExit->u1.to_room ) { fprintf( fp, "Exit\n"); fprintf( fp, "%d\n", pExit->orig_door ); fprintf( fp, "%s~\n", fix_string( pExit->description ) ); fprintf( fp, "%s~\n", pExit->keyword ); fprintf( fp, "%d\n", pExit->key); fprintf( fp, "%d\n", pExit->u1.to_room->vnum ); fprintf( fp, "%s\n", fwrite_flag(pExit->exit_info, buf) ); } if( pExit && !pExit->u1.to_room && pExit->to_shaft ) fwrite_mine( pExit, fp ); } if (pRoomIndex->mana_rate != 100 || pRoomIndex->heal_rate != 100){ fprintf ( fp, "ManaRate %d\n",pRoomIndex->mana_rate); fprintf ( fp, "HealRate %d\n", pRoomIndex->heal_rate); } for (pRprog = pRoomIndex->rprogs; pRprog; pRprog = pRprog->next) { fprintf(fp, "R %s %d %s~\n", prog_type_to_name(pRprog->trig_type), pRprog->vnum, pRprog->trig_phrase); } fprintf( fp, "EndRoom\n\n" ); } } } fprintf( fp, "#END\n\n\n\n" ); return; } /***************************************************************************** Name: fwrite_objects Purpose: Save one object to file. new ROM format saving -- Hugin Called by: save_objects (below). ****************************************************************************/ void fwrite_objects( FILE *fp, AREA_DATA *pArea ) { char letter; AFFECT_DATA *pAf; char buf[MAX_STRING_LENGTH]; PROG_LIST *pOprog; OBJ_INDEX_DATA *pObjIndex; int i; EXTRA_DESCR_DATA *pEd; fprintf( fp, "#OBJECTSNEW\n" ); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ) { if ( (pObjIndex = get_obj_index( i )) ) { fprintf( fp, "#OBJ\n" ); fprintf( fp, "Vnum %d\n", pObjIndex->vnum ); fprintf( fp, "Name %s~\n", pObjIndex->name ); fprintf( fp, "Short %s~\n", pObjIndex->short_descr ); fprintf( fp, "Desc %s~\n", fix_string( pObjIndex->description ) ); fprintf( fp, "Material %s~\n", pObjIndex->material ); fprintf( fp, "Item_type %s\n", item_name(pObjIndex->item_type)); fprintf( fp, "Extra %s\n", fwrite_flag( pObjIndex->extra_flags, buf ) ); fprintf( fp, "Extra2 %s\n", print_flags( pObjIndex->extra2_flags) ); fprintf( fp, "Wear %s\n", fwrite_flag( pObjIndex->wear_flags, buf ) ); /* * Using fwrite_flag to write mostValues gives a strange * looking area file, consider making a case for each * item type later. */ switch ( pObjIndex->item_type ) { default: fprintf( fp, "Values %s ", fwrite_flag( pObjIndex->value[0], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[1], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[2], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[3], buf ) ); fprintf( fp, "%s\n", fwrite_flag( pObjIndex->value[4], buf ) ); break; case ITEM_DRINK_CON: case ITEM_FOUNTAIN: fprintf( fp, "Values %d %d '%s' %d %d\n", pObjIndex->value[0], pObjIndex->value[1], liq_table[pObjIndex->value[2]].liq_name, pObjIndex->value[3], pObjIndex->value[4]); break; case ITEM_CONTAINER: fprintf( fp, "Values %d %s %d %d %d\n", pObjIndex->value[0], fwrite_flag( pObjIndex->value[1], buf ), pObjIndex->value[2], pObjIndex->value[3], pObjIndex->value[4]); break; case ITEM_WEAPON: if(IS_WEAPON_STAT(pObjIndex,WEAPON_TWO_HANDS)) { fprintf( fp, "Values %s %d %d %s %s\n", weapon_name(pObjIndex->value[0]), pObjIndex->value[1], pObjIndex->value[2], attack_table[pObjIndex->value[3]].name, fwrite_flag( pObjIndex->value[4], buf ) ); } else { fprintf( fp, "Values %s %d %d %s %s\n", weapon_name(pObjIndex->value[0]), pObjIndex->value[1], pObjIndex->value[2], attack_table[pObjIndex->value[3]].name, fwrite_flag( pObjIndex->value[4], buf ) ); } break; case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: fprintf( fp, "Values %d '%s' '%s' '%s' '%s'\n", pObjIndex->value[0] > 0 ? /* no negative numbers */ pObjIndex->value[0] : 0, pObjIndex->value[1] != -1 ? skill_table[pObjIndex->value[1]].name : "", pObjIndex->value[2] != -1 ? skill_table[pObjIndex->value[2]].name : "", pObjIndex->value[3] != -1 ? skill_table[pObjIndex->value[3]].name : "", pObjIndex->value[4] != -1 ? skill_table[pObjIndex->value[4]].name : ""); break; case ITEM_STAFF: case ITEM_WAND: fprintf( fp, "Values %d %d %d '%s' %d\n", pObjIndex->value[0], pObjIndex->value[1], pObjIndex->value[2], pObjIndex->value[3] != -1 ? skill_table[pObjIndex->value[3]].name : "", pObjIndex->value[4] ); break; case ITEM_BELT: case ITEM_SHEATH: fprintf( fp, "%d %d %d %d\n", pObjIndex->value[0], pObjIndex->value[1], pObjIndex->value[2], pObjIndex->value[3] ); break; case ITEM_QUIVER: fprintf( fp, "%d ", pObjIndex->value[0] ); fprintf( fp, "%d ", pObjIndex->value[1] ); fprintf( fp, "%d 0 0\n", pObjIndex->value[2]); break; case ITEM_ARROW: fprintf( fp, "0 %d ", pObjIndex->value[1] ); fprintf( fp, "%d 0 0\n", pObjIndex->value[2]); break; } fprintf( fp, "Level %d\n", pObjIndex->level ); fprintf( fp, "Weight %d\n", pObjIndex->weight ); fprintf( fp, "Cost %d\n", pObjIndex->cost ); fprintf( fp, "Plevel %d\n", pObjIndex->plevel ); fprintf( fp, "Exp %d\n", pObjIndex->exp ); fprintf( fp, "Xp_tolevel %d\n", pObjIndex->xp_tolevel ); if ( pObjIndex->condition > 90 ) letter = 'P'; else if ( pObjIndex->condition > 75 ) letter = 'G'; else if ( pObjIndex->condition > 50 ) letter = 'A'; else if ( pObjIndex->condition > 25 ) letter = 'W'; else if ( pObjIndex->condition > 10 ) letter = 'D'; else if ( pObjIndex->condition > 0 ) letter = 'B'; else letter = 'R'; fprintf( fp, "Condition %c\n", letter ); for( pEd = pObjIndex->extra_descr; pEd; pEd = pEd->next ) { fprintf( fp, "ExtraDesc\n%s~\n%s~\n", pEd->keyword, fix_string( pEd->description ) ); } for( pAf = pObjIndex->affected; pAf; pAf = pAf->next ) { if (pAf->where == TO_OBJECT || pAf->bitvector == 0) fprintf( fp, "AffectObj\n%d %d\n", pAf->location, pAf->modifier ); else { fprintf( fp, "F\n" ); switch(pAf->where) { case TO_AFFECTS: fprintf( fp, "Faff " ); break; case TO_IMMUNE: fprintf( fp, "Fimm " ); break; case TO_RESIST: fprintf( fp, "Fres " ); break; case TO_VULN: fprintf( fp, "Fvul " ); break; default: bug( "olc_save: Invalid Affect->where", 0); break; } fprintf( fp, "%d %d %s\n", pAf->location, pAf->modifier, fwrite_flag( pAf->bitvector, buf ) ); } } for (pOprog = pObjIndex->oprogs; pOprog; pOprog = pOprog->next) { fprintf(fp, "Oprg %s %d %s~\n", prog_type_to_name(pOprog->trig_type), pOprog->vnum, pOprog->trig_phrase); } fprintf( fp, "EndObj\n\n" ); } } fprintf( fp, "#END\n\n\n\n" ); return; } /***************************************************************************** Name: fwrite_mobiles Purpose: Save #MOBILES secion of an area file. Called by: save_area(olc_save.c). Notes: Changed for ROM OLC. ****************************************************************************/ void fwrite_mobiles( FILE *fp, AREA_DATA *pArea ) { int i; MOB_INDEX_DATA *pMobIndex; PROG_LIST *pMprog; char buf[MAX_STRING_LENGTH]; long temp; fprintf( fp, "#MOBILESNEW\n" ); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ) { if ( (pMobIndex = get_mob_index( i )) ) { sh_int race = pMobIndex->race; fprintf( fp, "#MOB\n" ); fprintf( fp, "Vnum %d\n", pMobIndex->vnum ); fprintf( fp, "Name %s~\n", pMobIndex->player_name ); fprintf( fp, "Short %s~\n", pMobIndex->short_descr ); fprintf( fp, "Long %s~\n", fix_string( pMobIndex->long_descr ) ); fprintf( fp, "Description %s~\n", fix_string( pMobIndex->description) ); fprintf( fp, "Race %s~\n", race_table[race].name ); fprintf( fp, "Act_flags %s\n", fwrite_flag( pMobIndex->act, buf ) ); fprintf( fp, "Aff %s\n", fwrite_flag( pMobIndex->affected_by, buf ) ); fprintf( fp, "Align %d\n", pMobIndex->alignment); fprintf( fp, "Group %d\n", pMobIndex->group); fprintf( fp, "Level %d\n", pMobIndex->level ); fprintf( fp, "Hitroll %d\n", pMobIndex->hitroll ); fprintf( fp, "Hit_dice %ldd%ld+%ld\n", pMobIndex->hit[DICE_NUMBER], pMobIndex->hit[DICE_TYPE], pMobIndex->hit[DICE_BONUS] ); fprintf( fp, "Mana_dice %ldd%ld+%ld\n", pMobIndex->mana[DICE_NUMBER], pMobIndex->mana[DICE_TYPE], pMobIndex->mana[DICE_BONUS] ); fprintf( fp, "Dam_dice %dd%d+%d\n", pMobIndex->damage[DICE_NUMBER], pMobIndex->damage[DICE_TYPE], pMobIndex->damage[DICE_BONUS] ); fprintf( fp, "Dam_type %s\n", attack_table[pMobIndex->dam_type].name ); fprintf( fp, "Armor %d %d %d %d\n", pMobIndex->ac[AC_PIERCE] / 10, pMobIndex->ac[AC_BASH] / 10, pMobIndex->ac[AC_SLASH] / 10, pMobIndex->ac[AC_EXOTIC] / 10 ); fprintf( fp, "Clevel%d\n", pMobIndex->cast_level ); fprintf( fp, "Cability %d\n", pMobIndex->cast_ability ); fprintf( fp, "Off %s\n", fwrite_flag( pMobIndex->off_flags, buf ) ); fprintf( fp, "Imm %s\n", fwrite_flag( pMobIndex->imm_flags, buf ) ); fprintf( fp, "Res %s\n", fwrite_flag( pMobIndex->res_flags, buf ) ); fprintf( fp, "Vuln %s\n", fwrite_flag( pMobIndex->vuln_flags, buf ) ); fprintf( fp, "Start_pos %s\n", position_table[pMobIndex->start_pos].short_name); fprintf( fp, "Default_pos %s\n", position_table[pMobIndex->default_pos].short_name); fprintf( fp, "Sex %s\n",sex_table[pMobIndex->sex].name); fprintf( fp, "Wealth %ld\n",pMobIndex->wealth ); fprintf( fp, "Form %s\n", fwrite_flag( pMobIndex->form, buf ) ); fprintf( fp, "Parts %s\n", fwrite_flag( pMobIndex->parts, buf ) ); fprintf( fp, "Size %s\n", size_table[pMobIndex->size].name ); fprintf( fp, "Material %s\n", IS_NULLSTR(pMobIndex->material) ? pMobIndex->material : "unknown" ); if ( pMobIndex->xp_tolevel >= 1000 ) fprintf( fp, "Xp_tolevel %d\n", pMobIndex->xp_tolevel); fprintf( fp, "Aggression %d\n", pMobIndex->aggression ); if ((temp = DIF(race_table[race].act,pMobIndex->act))) fprintf( fp, "Fact %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].aff,pMobIndex->affected_by))) fprintf( fp, "Faff1 %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].off,pMobIndex->off_flags))) fprintf( fp, "Foff %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].imm,pMobIndex->imm_flags))) fprintf( fp, "Fimm %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].res,pMobIndex->res_flags))) fprintf( fp, "Fres %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].vuln,pMobIndex->vuln_flags))) fprintf( fp, "Fvul %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].form,pMobIndex->form))) fprintf( fp, "Ffor %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].parts,pMobIndex->parts))) fprintf( fp, "Fpar %s\n", fwrite_flag(temp, buf) ); for (pMprog = pMobIndex->mprogs; pMprog; pMprog = pMprog->next) { fprintf(fp, "MobTrig %s %d %s~\n", prog_type_to_name(pMprog->trig_type), pMprog->vnum, pMprog->trig_phrase); } fprintf( fp, "EndMob\n\n" ); } } fprintf( fp, "#END\n\n\n\n" ); return; } /***************************************************************************** Name: fwrite_area Purpose: Save an area, note that this format is new. Called by: do_asave(olc_save.c). ****************************************************************************/ void fwrite_area( AREA_DATA *pArea ) { FILE *fp = NULL; char buf[MSL]; sprintf(buf, "%s%s", NEW_AREA_DIR,pArea->file_name); wiznet(buf,NULL,NULL,0,0,0); fp = file_open( buf, "w" ); fprintf( fp, "#AREADATA\n" ); fprintf( fp, "Name %s~\n", pArea->name ); fprintf( fp, "Builders %s~\n", fix_string( pArea->builders ) ); fprintf( fp, "VNUMs %d %d\n", pArea->min_vnum, pArea->max_vnum ); fprintf( fp, "Credits %s~\n", pArea->credits ); fprintf( fp, "RepopMsg %s~\n", pArea->repop_msg ); fprintf( fp, "Security %d\n", pArea->security ); fprintf( fp, "Soundfile %s~\n", pArea->soundfile ); fprintf( fp, "Temps %d %d\n", pArea->min_temp, pArea->max_temp ); fprintf( fp, "Temperature %d\n", pArea->temperature ); fprintf( fp, "Continent %d\n", pArea->continent ); fprintf( fp, "Levl %d %d\n", pArea->min_lev, pArea->max_lev ); fprintf( fp, "End\n\n\n\n" ); fwrite_mobiles( fp, pArea ); fwrite_objects( fp, pArea ); fwrite_rooms( fp, pArea ); save_specials( fp, pArea ); save_resets( fp, pArea ); save_shops( fp, pArea ); save_mobprogs( fp, pArea ); save_objprogs( fp, pArea ); save_roomprogs( fp, pArea ); save_help_new( ); fprintf( fp, "#$\n" ); file_close( fp ); return; } void do_saveconst(CHAR_DATA *ch, char *argument ) { int i; FILE *fp = file_open("../data/const.txt", "w" ); if(!fp) return; for(i = 0; const_table[i].name != NULL ; i++ ) fprintf(fp, "%-30s %d\n",const_table[i].name, *const_table[i].value ); fprintf(fp, "End\n"); file_close(fp); return; } int const_lookup(const char *name ) { int i; for( i = 0; const_table[i].name != NULL ; i++ ) if(!str_cmp(name, const_table[i].name ) ) return i; return -1; } void load_const() { FILE *fp; char *word; int i, value; if(!file_exists("../data/const.txt" ) ) { logf2("Constants do not exist! Find Davion and SLAY! SLAY!"); return; } fp = file_open("../data/const.txt", "r" ); for(;;) { word = fread_word(fp); if(!str_cmp(word, "End" ) ) return; if( ( i = const_lookup(word) ) == -1 ) { logf2("Invalid constant in const.txt!"); fread_number(fp); continue; } value = fread_number(fp); *const_table[i].value = value; } file_close(fp); return; }