/**************************************************************************/
// obdb.cpp - reads in area files etc
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with all the licenses *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
***************************************************************************
* >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. *
* >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to *
* you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), *
* Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) *
* >> Oblivion 1.2 is copyright 1996 Wes Wagner *
**************************************************************************/
#include "include.h" // dawn standard includes
#include "areas.h"
#include "db.h"
#include "clan.h"
#include "olc.h"
extern int flag_lookup args((const char *name, const struct flag_type *flag_table));
void apply_area_vnum_offset(int *old_vnum);
/**************************************************************************/
// Snarf a room section.
void load_rooms( FILE *fp, int version )
{
ROOM_INDEX_DATA *pRoomIndex;
if ( area_last == NULL )
{
bug("Load_rooms: no #AREA seen yet.");
exit_error( 1 , "load_rooms", "no #AREA seen yet");
}
for ( ; ; )
{
vn_int vnum;
char letter;
int door;
int iHash;
letter = fread_letter( fp );
if ( letter != '#' )
{
bug("Load_rooms: # not found.");
exit_error( 1 , "load_rooms", "# not found");
}
vnum = fread_number( fp );
if ( vnum == 0 )
break;
vnum+= area_last->vnum_offset;
// check for a duplicate room number
fBootDb = false;
ROOM_INDEX_DATA *dup_room_index=get_room_index( vnum );
if ( dup_room_index)
{
bugf( "Load_rooms: vnum %d duplicated with room from areafile '%s'.",
vnum, dup_room_index->area?dup_room_index->area->file_name:"unknown");
exit_error( 1 , "load_rooms", "Duplicate vnum");
}
fBootDb = true;
last_vnum = vnum; // backup the last vnum for gdb use
pRoomIndex = new_room_index();
pRoomIndex->area = area_last;
pRoomIndex->vnum = vnum;
pRoomIndex->name = fread_string( fp );
pRoomIndex->description = fread_string( fp );
if (str_len(pRoomIndex->description)>MSL-4)
{
bugf("load_rooms: description of room %d is %d characters!!! (more than %d)",
(int)last_vnum, str_len(pRoomIndex->description), MSL-4);
exit_error( 1 , "load_rooms", "too many characters in room description");
}
fread_number( fp ); // just a 0 - padding, not really used
pRoomIndex->room_flags = fread_flag( fp );
if(AREA_IMPORT_FORMAT(AIF_FORMAT3)){
fread_number( fp ); // read in a room affects flag - not used on dawn
}
pRoomIndex->sector_type = fread_number( fp );
if(AREA_IMPORT_FORMAT(AIF_FORMAT2)){
areaimport_room_flags_format2(fp, version, pRoomIndex);
}else{
// AIF_STOCK - the default
areaimport_room_flags_stock(fp, version, pRoomIndex);
}
pRoomIndex->light = 0;
for ( door = 0; door < MAX_DIR; door++ ){
pRoomIndex->exit[door] = NULL;
}
// defaults
pRoomIndex->heal_rate = 100;
pRoomIndex->mana_rate = 100;
// check vnum fits in area vnum range
if ( vnum < pRoomIndex->area->min_vnum + pRoomIndex->area->vnum_offset)
{
bugf("Room with Vnum %d is less than area %s <%s> vnum %d!",
vnum,
pRoomIndex->area->name,
pRoomIndex->area->file_name,
pRoomIndex->area->min_vnum
);
}
if ( vnum > pRoomIndex->area->max_vnum + pRoomIndex->area->vnum_offset)
{
bugf("Room with Vnum %d is greater than area %s <%s> vnum %d!",
vnum,
pRoomIndex->area->name,
pRoomIndex->area->file_name,
pRoomIndex->area->max_vnum
);
}
for ( ; ; )
{
letter = fread_letter( fp );
if ( letter == 'S' )
break;
if ( letter == 'H'){ // healing room
pRoomIndex->heal_rate = fread_number(fp);
}else if ( letter == 'M'){ // mana room
pRoomIndex->mana_rate = fread_number(fp);
}else if ( letter == 'C'){ // clan
if (pRoomIndex->clan)
{
bug("Load_rooms: duplicate clan fields.");
exit_error( 1 , "load_rooms", "duplicate clan fields");
}
pRoomIndex->clan = clan_slookup(fread_string(fp));
}else if ( AREA_IMPORT_FORMAT(AIF_FORMAT3) &&
(letter=='c' || letter=='s' || letter=='R') )
{ // AREA_IMPORT_FORMAT3 only stuff
if(letter == 'c' ){
// format3 class restriction system
fread_string(fp);
}else if(letter == 's' ){
// format3 sex based restriction system
fread_number(fp);
}else if(letter == 'R' ){
// format3 race based restriction system
fread_string(fp);
}
}else if ( UPPER(letter) == 'X' ){
// MSP Room sound
pRoomIndex->msp_sound = fread_string( fp );
}else if (UPPER(letter) == 'D'){
EXIT_DATA *pexit;
door = fread_number( fp );
if ( door < 0 || door >=MAX_DIR )
{
bugf( "load_rooms: vnum %d has bad door number.", vnum );
exit_error( 1 , "load_rooms", "bad door numbers");
}
pexit = (EXIT_DATA *)alloc_perm( sizeof(*pexit) );
pexit->description = fread_string( fp );
pexit->keyword = fread_string( fp );
if(version==1){
int locks= fread_number( fp );
switch ( locks )
{
case 1: pexit->rs_flags = EX_ISDOOR; break;
case 2: pexit->rs_flags = EX_ISDOOR | EX_PICKPROOF; break;
case 3: pexit->rs_flags = EX_ISDOOR | EX_NOPASS; break;
case 4: pexit->rs_flags = EX_ISDOOR|EX_NOPASS|EX_PICKPROOF;
break;
}
}else{
pexit->rs_flags = fread_flag( fp );
}
pexit->key = fread_number( fp );
pexit->u1.vnum = fread_number( fp );
apply_area_vnum_offset(&pexit->u1.vnum);
pexit->exit_info=pexit->rs_flags;
pRoomIndex->exit[door] = pexit;
top_exit++;
}
else if ( UPPER(letter) == 'E' )
{
EXTRA_DESCR_DATA *ed;
ed = (EXTRA_DESCR_DATA *)alloc_perm( sizeof(*ed) );
ed->keyword = fread_string( fp );
ed->description = fread_string( fp );
ed->next = pRoomIndex->extra_descr;
pRoomIndex->extra_descr = ed;
top_ed++;
}
else if (UPPER(letter) == 'O')
{
if (pRoomIndex->owner[0] != '\0')
{
bug("Load_rooms: duplicate owner.");
exit_error( 1 , "load_rooms", "duplicate owner");
}
pRoomIndex->owner = fread_string(fp);
}
else if ( letter == 'F' )
{
room_echo_data *re= new_room_echo();
re->firsthour = fread_number( fp );
re->lasthour = fread_number( fp );
int lowroll = fread_number( fp );
int highroll = fread_number( fp );
re->percentage = UMAX(highroll,lowroll)-UMIN(highroll,lowroll);
re->echotext = fread_string( fp );
re->next = pRoomIndex->echoes;
pRoomIndex->echoes= re;
}
else
{
bugf( "Load_rooms: vnum %d has flag '%c' which is not 'DESOF'.", vnum, letter );
exit_error( 1 , "load_rooms", "invalid flag");
}
}
iHash = vnum % MAX_KEY_HASH;
pRoomIndex->next = room_index_hash[iHash];
room_index_hash[iHash] = pRoomIndex;
top_room++;
top_vnum_room = top_vnum_room < vnum ? vnum : top_vnum_room;
assign_area_vnum( vnum );
}
return;
}
/**************************************************************************/
void load_object_values( FILE *fp, int version, OBJ_INDEX_DATA *pObjIndex)
{
assertp(fp);
switch(pObjIndex->item_type)
{
case ITEM_WEAPON:
pObjIndex->value[0] = weapontype(fread_word(fp));
pObjIndex->value[1] = fread_number(fp);
pObjIndex->value[2] = fread_number(fp);
pObjIndex->value[3] = attack_lookup(fread_word(fp));
pObjIndex->value[4] = fread_flag(fp);
break;
case ITEM_CAULDRON:
case ITEM_CONTAINER:
case ITEM_FLASK:
case ITEM_MORTAR:
pObjIndex->value[0] = fread_number(fp);
pObjIndex->value[1] = fread_flag(fp);
pObjIndex->value[2] = fread_number(fp);
pObjIndex->value[3] = fread_number(fp);
pObjIndex->value[4] = fread_number(fp);
break;
case ITEM_DRINK_CON:
case ITEM_FOUNTAIN:
pObjIndex->value[0] = fread_number(fp);
pObjIndex->value[1] = fread_number(fp);
pObjIndex->value[2] = liq_lookup(fread_word(fp));
if(version<2){
pObjIndex->value[3] = fread_number(fp);
}else{
pObjIndex->value[3] = fread_flag(fp);
}
pObjIndex->value[4] = fread_number(fp);
break;
case ITEM_PARCHMENT:
pObjIndex->value[0] = fread_number(fp);
pObjIndex->value[1] = fread_number(fp);
pObjIndex->value[2] = fread_number(fp);
pObjIndex->value[3] = language_safe_lookup(fread_word( fp ))->unique_id;
pObjIndex->value[4] = fread_number(fp);
break;
case ITEM_INSTRUMENT:
pObjIndex->value[0] = fread_number(fp);
pObjIndex->value[1] = fread_number(fp);
pObjIndex->value[2] = fread_number(fp);
pObjIndex->value[3] = fread_number(fp);
pObjIndex->value[4] = fread_number(fp);
break;
case ITEM_WAND:
case ITEM_STAFF:
case ITEM_POULTICE:
pObjIndex->value[0] = fread_number(fp);
pObjIndex->value[1] = fread_number(fp);
pObjIndex->value[2] = fread_number(fp);
pObjIndex->value[3] = skill_lookup(fread_word(fp));
pObjIndex->value[4] = fread_number(fp);
break;
case ITEM_POTION:
case ITEM_PILL:
case ITEM_SCROLL:
pObjIndex->value[0] = fread_number(fp);
pObjIndex->value[1] = skill_lookup(fread_word(fp));
pObjIndex->value[2] = skill_lookup(fread_word(fp));
pObjIndex->value[3] = skill_lookup(fread_word(fp));
pObjIndex->value[4] = skill_lookup(fread_word(fp));
{
int snr=skill_lookup("reserved");
if(snr!=-1){ // convert reserved into -1
for(int i=1; i<5; i++){
if(pObjIndex->value[i]==snr){
pObjIndex->value[i]=-1;
}
}
}
}
break;
case ITEM_COMPONENT:
pObjIndex->value[0] = fread_number(fp);
pObjIndex->value[1] = skill_lookup(fread_word(fp));
pObjIndex->value[2] = fread_number(fp);
pObjIndex->value[3] = fread_number(fp);
pObjIndex->value[4] = fread_number(fp);
break;
default:
pObjIndex->value[0] = fread_flag( fp );
pObjIndex->value[1] = fread_flag( fp );
pObjIndex->value[2] = fread_flag( fp );
pObjIndex->value[3] = fread_flag( fp );
pObjIndex->value[4] = fread_flag( fp );
break;
}
// pObjIndex->creator = fread_flag( fp );
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/