/**************************************************************************/
// db2.cpp -
/***************************************************************************
* 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"
extern int flag_lookup args((const char *name, const struct flag_type *flag_table));
struct social_old_type social_table[MAX_SOCIALS];
int social_count;
extern NOTE_DATA *anote_list;
/**************************************************************************/
// read in a socials file - old format
void oldload_socials( FILE *fp)
{
social_count=0;
for ( ; ; )
{
if(social_count+5>MAX_SOCIALS){
logf("oldload_socials()... Too many socials read in from file... "
"you should read in the ones you want, use importsocials to convert them "
"to the new format, then remove the socials from the helpfile list.");
exit_error( 1 , "oldload_socials", "Too many socials");
return;
}
struct social_old_type social;
char *temp;
// clear social
social.char_no_arg = NULL;
social.others_no_arg = NULL;
social.char_found = NULL;
social.others_found = NULL;
social.vict_found = NULL;
social.char_not_found = NULL;
social.char_auto = NULL;
social.others_auto = NULL;
temp = fread_word(fp);
if (!strcmp(temp,"#0")){
break; // done
}
#if defined(social_debug)
else{
logf("%s",temp);
}
#endif
strcpy(social.name,temp);
fread_to_eol(fp);
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.char_no_arg = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.char_no_arg = temp;
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.others_no_arg = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.others_no_arg = temp;
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.char_found = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.char_found = temp;
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.others_found = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.others_found = temp;
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.vict_found = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.vict_found = temp;
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.char_not_found = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.char_not_found = temp;
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.char_auto = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.char_auto = temp;
temp = fread_string_eol(fp);
if (!strcmp(temp,"$"))
social.others_auto = NULL;
else if (!strcmp(temp,"#"))
{
social_table[social_count] = social;
social_count++;
continue;
}
else
social.others_auto = temp;
social_table[social_count] = social;
social_count++;
}
logf("autonoting that old style social file was read in.");
autonote(NOTE_SNOTE, "p_anote()", "remove oldstyle socials loading from files listed in helplist.txt", "admin",
"Old style socials were loaded in from helplist.txt... you can import them using 'importsocials' "
"Once you have dealt with the issue of socials, remove the filename loading socials from helplist.txt... "
"You can usually find this helpfile(s) by typing 'grep SOCIALS *' in the help directory.", true);
anote_list=NULL;
return;
}
/**************************************************************************/
void load_mobiles( FILE *fp, int version )
{
MOB_INDEX_DATA *pMobIndex;
char *racename;
if ( !area_last ){
bug("Load_mobiles: no #AREA seen yet.");
exit_error( 1 , "load_mobiles", "no #AREA seen yet");
}
for ( ; ; )
{
vn_int vnum;
char letter;
int iHash;
letter = fread_letter( fp );
if ( letter != '#' )
{
bug("Load_mobiles: # not found.");
exit_error( 1 , "load_mobiles", "# not found");
}
vnum = fread_number( fp );
if ( vnum == 0 )
break;
vnum+= area_last->vnum_offset;
// make sure we don't have a duplicated mob vnum
fBootDb = false; // this is turned off to prevent logging of unfound vnums
if ( get_mob_index( vnum ) ){
char *aname="an unknown area.";
if( get_mob_index( vnum )->area
&& get_mob_index( vnum )->area->file_name){
aname=get_mob_index( vnum )->area->file_name;
}
bugf( "load_mobiles: vnum %d duplicated.", vnum );
logf("with %s (%s) from %s",
get_mob_index( vnum )->short_descr,
get_mob_index( vnum )->player_name,
aname);
exit_error( 1 , "load_mobiles", "duplicate vnum");
}
fBootDb = true;
last_vnum = vnum; // backup the last vnum for gdb use
pMobIndex= (MOB_INDEX_DATA *)alloc_perm( sizeof(*pMobIndex) );
pMobIndex->vnum = vnum;
pMobIndex->area = area_last;
pMobIndex->xp_mod= 100; // default value
// check mob vnum fits in areas vnum range
if ( vnum < pMobIndex->area->min_vnum + pMobIndex->area->vnum_offset)
{
bugf("Mob with Vnum %d is less than area %s <%s> vnum %d!",
vnum,
pMobIndex->area->name,
pMobIndex->area->file_name,
pMobIndex->area->min_vnum
);
}
if ( vnum > pMobIndex->area->max_vnum + pMobIndex->area->vnum_offset)
{
bugf("Mob with Vnum %d is greater than area %s <%s> vnum %d!",
vnum,
pMobIndex->area->name,
pMobIndex->area->file_name,
pMobIndex->area->max_vnum
);
}
pMobIndex->player_name = fread_string( fp );
pMobIndex->short_descr = fread_string( fp );
pMobIndex->long_descr = trim_trailing_carriage_return_line_feed(fread_string( fp ));
pMobIndex->description = fread_string( fp );
if (str_len(pMobIndex->description)>MSL-4)
{
bugf("load_mobiles: Description of mob %d is %d characters!!!"
"(more than %d)",
(int)last_vnum, str_len(pMobIndex->description), MSL-4);
exit_error( 1 , "load_mobiles", "description too long");
}
pMobIndex->long_descr[0] = UPPER(pMobIndex->long_descr[0]);
pMobIndex->description[0] = UPPER(pMobIndex->description[0]);
racename = fread_string( fp );
pMobIndex->race = race_lookup(racename);
if(pMobIndex->race == -1)
{
logf("Mob with Vnum %d has an unrecognised race '%s', "
"dynamically generating a race.", vnum, racename);
pMobIndex->race= race_generate_race_adding_to_race_table(racename);
}
free_string(racename);
// count all the usage stats while loading
race_table[pMobIndex->race]->inuse++;
total_npcracescount++;
if (race_table[pMobIndex->race]->lastarea!=area_last){
race_table[pMobIndex->race]->areacount++;
total_npcareacount++;
}
race_table[pMobIndex->race]->lastarea=area_last;
pMobIndex->act = fread_flag( fp ) | ACT_IS_NPC
| race_table[pMobIndex->race]->act;
if(AREA_IMPORT_FORMAT(AIF_FORMAT2)){
areaimport_mobile_affects_format2(fp, version, pMobIndex);
}else{
// AIF_STOCK - the default
areaimport_mobile_affects_stock(fp, version, pMobIndex);
}
pMobIndex->pShop = NULL;
// get alliance and tendency
switch(version){
case 1:
{
int talign = fread_number( fp );
pMobIndex->tendency = number_range(1,7)-4;
pMobIndex->alliance = (3*talign)/1000;
pMobIndex->group = fread_number( fp );
}
break;
case 2:
pMobIndex->tendency = fread_number( fp );
pMobIndex->alliance = fread_number( fp );
break;
default:
pMobIndex->tendency = fread_number( fp );
pMobIndex->alliance = fread_number( fp );
pMobIndex->xp_mod = fread_number( fp );
if (pMobIndex->xp_mod<0 || pMobIndex->xp_mod>500){
bugf( "Load_mobiles: mob vnum %d, XP_MOD is %d (>500 or <0!)",
vnum, pMobIndex->xp_mod);
}
break;
}
pMobIndex->level = fread_number( fp );
pMobIndex->hitroll = fread_number( fp );
/* read hit dice */
pMobIndex->hit[DICE_NUMBER] = fread_number( fp );
/* 'd' */ fread_letter( fp );
pMobIndex->hit[DICE_TYPE] = fread_number( fp );
/* '+' */ fread_letter( fp );
pMobIndex->hit[DICE_BONUS] = fread_number( fp );
/* read mana dice */
pMobIndex->mana[DICE_NUMBER] = fread_number( fp );
/* 'd' */ fread_letter( fp );
pMobIndex->mana[DICE_TYPE] = fread_number( fp );
/* '+' */ fread_letter( fp );
pMobIndex->mana[DICE_BONUS] = fread_number( fp );
/* read damage dice */
pMobIndex->damage[DICE_NUMBER] = fread_number( fp );
/* 'd' */ fread_letter( fp );
pMobIndex->damage[DICE_TYPE] = fread_number( fp );
/* '+' */ fread_letter( fp );
pMobIndex->damage[DICE_BONUS] = fread_number( fp );
pMobIndex->dam_type = attack_lookup(fread_word(fp));
// read armor class
if(version<6){
pMobIndex->ac[AC_PIERCE] = fread_number( fp ) * 10;
pMobIndex->ac[AC_BASH] = fread_number( fp ) * 10;
pMobIndex->ac[AC_SLASH] = fread_number( fp ) * 10;
pMobIndex->ac[AC_EXOTIC] = fread_number( fp ) * 10;
}else{
pMobIndex->ac[AC_PIERCE] = fread_number( fp );
pMobIndex->ac[AC_BASH] = fread_number( fp );
pMobIndex->ac[AC_SLASH] = fread_number( fp );
pMobIndex->ac[AC_EXOTIC] = fread_number( fp );
}
// read flags and add in data from the race table
pMobIndex->off_flags = fread_flag( fp )
| race_table[pMobIndex->race]->off;
pMobIndex->imm_flags = fread_flag( fp )
| race_table[pMobIndex->race]->imm;
pMobIndex->res_flags = fread_flag( fp )
| race_table[pMobIndex->race]->res;
pMobIndex->vuln_flags = fread_flag( fp )
| race_table[pMobIndex->race]->vuln;
// vital statistics
pMobIndex->start_pos = position_lookup(fread_word(fp));
if (pMobIndex->start_pos==-1){
bugf("load_mobiles: mob %d (%s) start position is invalid!",
(int)last_vnum, pMobIndex->short_descr);
exit_error( 1 , "load_mobiles", "invalid start position");
}
pMobIndex->default_pos = position_lookup(fread_word(fp));
if (pMobIndex->default_pos==-1){
bugf("load_mobiles: mob %d (%s) default position is invalid!",
(int)last_vnum, pMobIndex->short_descr);
exit_error( 1 , "load_mobiles", "invalid default position");
}
pMobIndex->sex = sex_lookup(fread_word(fp));
if (pMobIndex->sex==-1){
bugf("load_mobiles: mob %d (%s) sex category doesn't exist!",
(int)last_vnum, pMobIndex->short_descr);
exit_error( 1 , "load_mobiles", "invalid sex");
}
pMobIndex->wealth = fread_number( fp );
if (pMobIndex->wealth<0){
bugf("load_mobiles: mob %d (%s) wealth is less than 0!",
(int)last_vnum, pMobIndex->short_descr);
exit_error( 1 , "load_mobiles", "negative wealth");
}
if(pMobIndex->wealth > pMobIndex->level*10){
pMobIndex->wealth=pMobIndex->level*10;
}
pMobIndex->form = fread_flag( fp )
| race_table[pMobIndex->race]->form;
pMobIndex->parts = fread_flag( fp )
| race_table[pMobIndex->race]->parts;
// size
pMobIndex->size = size_lookup(fread_word(fp));
// material
pMobIndex->material = str_dup(lowercase(fread_word( fp )));
if(!str_cmp(pMobIndex->material,"0")){
replace_string(pMobIndex->material,"unknown");
}
for ( ; ; )
{
letter = fread_letter( fp );
if (letter == 'G') // read their group (if they have one)
{
char *word= fread_word(fp);
if(is_number(word)){
pMobIndex->group=atoi(word);
}else{
bugf("Unexpected input in loading mobile %d's group number "
"- must be numeric 'G %s'", pMobIndex->vnum, word);
exit_error( 1 , "load_mobiles", "unexpected group number input");
}
}
else if (letter == 'H') // read their helpgroup (if they have one)
{
char *word= fread_word(fp);
if(is_number(word)){
pMobIndex->helpgroup=atoi(word);
}else{
bugf("Unexpected input in loading mobile %d's helpgroup number "
"- must be numeric 'H %s'", pMobIndex->vnum, word);
exit_error( 1 , "load_mobiles", "unexpected helpgroup number input");
}
}
else if (letter == 'F')
{
char *word;
long vector;
word = fread_word(fp);
vector = fread_flag(fp);
if (!str_prefix(word,"act"))
REMOVE_BIT(pMobIndex->act,vector);
else if (!str_prefix(word,"aff"))
REMOVE_BIT(pMobIndex->affected_by,vector);
else if (!str_prefix(word,"off"))
REMOVE_BIT(pMobIndex->affected_by,vector);
else if (!str_prefix(word,"imm"))
REMOVE_BIT(pMobIndex->imm_flags,vector);
else if (!str_prefix(word,"res"))
REMOVE_BIT(pMobIndex->res_flags,vector);
else if (!str_prefix(word,"vul"))
REMOVE_BIT(pMobIndex->vuln_flags,vector);
else if (!str_prefix(word,"for"))
REMOVE_BIT(pMobIndex->form,vector);
else if (!str_prefix(word,"par"))
REMOVE_BIT(pMobIndex->parts,vector);
else
{
bugf("load_mobiles: flag '%s' not found.", word);
exit_error( 1 , "load_mobiles", "flag not found");
}
}
else if ( letter == 'M' )
{
MPROG_LIST *pMprog;
char *word;
int trigger = 0;
pMprog = (MPROG_LIST *)alloc_perm(sizeof(*pMprog));
word = fread_word( fp );
// support position flags
if(word[0]=='='){
pMprog->pos_flags= fread_flag(fp);
word= fread_word( fp );
}
if ( !(trigger = flag_lookup( word, mprog_flags )) )
{
bug("load_mobiles: invalid mobprog trigger.");
exit_error( 1 , "load_mobiles", "invalid mobprog trigger");
}
SET_BIT( pMobIndex->mprog_flags, trigger );
pMprog->trig_type = trigger;
// get the mobprog number, with vnum translation support
int mpvnum=fread_number( fp );
apply_area_vnum_offset( &mpvnum); // this system only works within a particular area
pMprog->temp_mpvnum = mpvnum; // hack for loading - fixed up in fix_mobprogs
pMprog->trig_phrase = fread_string( fp );
pMprog->next = pMobIndex->mprogs;
pMobIndex->mprogs = pMprog;
}
else
{
ungetc(letter,fp);
break;
}
}
iHash = vnum % MAX_KEY_HASH;
pMobIndex->next = mob_index_hash[iHash];
mob_index_hash[iHash] = pMobIndex;
top_mob_index++;
kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++;
// linked list of all pMobIndex records
pMobIndex->listnext=pMobIndexlist;
pMobIndexlist=pMobIndex;
}
return;
}
/**************************************************************************/
/**************************************************************************/
// Snarf an obj section
void load_objects( FILE *fp, int version )
{
OBJ_INDEX_DATA *pObjIndex;
if ( !area_last ){
bug("Load_objects: no #AREA seen yet.");
exit_error( 1 , "load_objects", "no #AREA seen yet");
}
for ( ; ; )
{
vn_int vnum;
char letter;
int iHash;
letter = fread_letter( fp );
if ( letter != '#' )
{
bug("Load_objects: # not found.");
exit_error( 1 , "load_objects", "# not found");
}
vnum = fread_number( fp );
if ( vnum == 0 )
break;
vnum+= area_last->vnum_offset;
fBootDb = false; // put here because get_obj_index() calls bug()
if ( get_obj_index( vnum ) )
{
char *aname="an unknown area.";
if(get_obj_index( vnum )->area
&& get_obj_index( vnum )->area->file_name){
aname=get_obj_index( vnum )->area->file_name;
}
bugf( "Load_objects: vnum %d duplicated.", vnum );
logf("with %s from %s",
get_obj_index( vnum )->short_descr,
aname);
exit_error( 1 , "load_objects", "duplicate vnum");
}
fBootDb = true;
last_vnum = vnum; // backup the last vnum for gdb use
pObjIndex = (OBJ_INDEX_DATA *)alloc_perm( sizeof(*pObjIndex) );
pObjIndex->vnum = vnum;
pObjIndex->area = area_last;
// check object vnum fits in areas vnum range
if ( vnum < pObjIndex->area->min_vnum + pObjIndex->area->vnum_offset)
{
bugf("Object with Vnum %d is less than area %s <%s> vnum %d!",
vnum,
pObjIndex->area->name,
pObjIndex->area->file_name,
pObjIndex->area->min_vnum
);
}
if ( vnum > pObjIndex->area->max_vnum + pObjIndex->area->vnum_offset)
{
bugf("Object with Vnum %d is greater than area %s <%s> vnum %d!",
vnum,
pObjIndex->area->name,
pObjIndex->area->file_name,
pObjIndex->area->max_vnum
);
}
pObjIndex->reset_num = 0;
pObjIndex->name = fread_string( fp );
pObjIndex->short_descr = fread_string( fp );
pObjIndex->description = fread_string( fp );
{
char * pStr = fread_string( fp );
pObjIndex->material = str_dup(lowercase(pStr));
free_string(pStr);
}
char *itypeword=fread_word( fp );
pObjIndex->item_type = item_lookup(itypeword);
if(pObjIndex->item_type<1){
bugf("Unrecognised item type '%s' for object %d", itypeword, pObjIndex->vnum);
exit_error( 1 , "load_objects", "unrecognised item type");
}
pObjIndex->extra_flags = fread_flag( fp );
if ( version > 3 )
{
pObjIndex->extra2_flags = fread_flag( fp );
// pObjIndex->extra3_flags = fread_flag( fp );
// Traps loading code here
if ( IS_SET( pObjIndex->extra2_flags, OBJEXTRA2_TRAP ))
{
pObjIndex->trap_trig = fread_number( fp );
pObjIndex->trap_dtype = fread_number( fp );
pObjIndex->trap_charge = fread_number( fp );
pObjIndex->trap_modifier= fread_number( fp );
}
else // initialize it to zero to be thorough
{
pObjIndex->trap_trig = 0;
pObjIndex->trap_dtype = 0;
pObjIndex->trap_charge = 0;
pObjIndex->trap_modifier= 0;
}
}
pObjIndex->wear_flags = fread_flag( fp );
if(AREA_IMPORT_FORMAT(AIF_FORMAT2)){
areaimport_object_translate_flags_format2(fp, version, pObjIndex);
}else if(AREA_IMPORT_FORMAT(AIF_FORMAT2)){
areaimport_object_translate_flags_format3(fp, version, pObjIndex);
}else{
// AIF_STOCK - the default
areaimport_object_translate_flags_stock(fp, version, pObjIndex);
}
load_object_values( fp, version, pObjIndex);
pObjIndex->level = fread_number( fp );
pObjIndex->weight = fread_number( fp );
pObjIndex->cost = fread_number( fp );
// condition
letter = fread_letter( fp );
switch (letter)
{
case ('P') : pObjIndex->condition = 100; break;
case ('G') : pObjIndex->condition = 90; break;
case ('A') : pObjIndex->condition = 75; break;
case ('W') : pObjIndex->condition = 50; break;
case ('D') : pObjIndex->condition = 25; break;
case ('B') : pObjIndex->condition = 10; break;
case ('R') : pObjIndex->condition = 1; break;
default: pObjIndex->condition = 100; break;
}
if( version<2){
pObjIndex->absolute_size=pObjIndex->weight;
pObjIndex->relative_size=50;
}else{
pObjIndex->absolute_size = fread_number(fp);
pObjIndex->relative_size = fread_number(fp);
}
if( version<3){
pObjIndex->class_allowances = 0;
}else{
if(version<5){
int tempint= (sh_int)fread_flag(fp);
// convert the class restriction into the allowance counter part
if(tempint){
pObjIndex->class_allowances=~tempint;
pObjIndex->class_allowances=tempint&0x1FF; // only the relevant bits
}
}
}
// optional parameters
for ( ; ; )
{
char letter;
letter = fread_letter( fp );
if ( letter == 'A'){
AFFECT_DATA *paf;
paf = (AFFECT_DATA *)alloc_perm( sizeof(*paf) );
paf->where = WHERE_OBJEXTRA;
paf->type = -1;
paf->level = pObjIndex->level;
paf->duration = -1;
paf->location = translate_old_apply_number(fread_number( fp ));
paf->modifier = fread_number( fp );
paf->bitvector = 0;
paf->next = pObjIndex->affected;
pObjIndex->affected = paf;
top_affect++;
// convert to WHERE_MODIFIER if appropriate
if(version==2){
if(paf->location!=APPLY_NONE){
paf->where=WHERE_MODIFIER;
}
if(paf->location==1){
paf->modifier=paf->modifier*2;
}else if(paf->location==2){
paf->modifier=paf->modifier*2;
paf->location=APPLY_RE;
}else if(paf->location==3){
paf->modifier=paf->modifier*2;
paf->location=APPLY_ME;
}else if(paf->location==4){
paf->modifier=paf->modifier*2;
paf->location=APPLY_QU;
}else if(paf->location==5){
paf->modifier=paf->modifier*2;
paf->location=APPLY_CO;
}else if(paf->location==APPLY_HIT){
paf->modifier=paf->modifier/3;
}
}
}else if (letter == 'B'){
AFFECT_DATA *paf;
paf = (AFFECT_DATA *)alloc_perm( sizeof(*paf) );
paf->where = WHERE_OBJEXTRA2;
paf->type = -1;
paf->level = pObjIndex->level;
paf->duration = -1;
paf->location = translate_old_apply_number(fread_number( fp ));
paf->modifier = fread_number( fp );
paf->bitvector = 0;
paf->next = pObjIndex->affected;
pObjIndex->affected = paf;
top_affect++;
}else if ( letter == 'L' && AREA_IMPORT_FORMAT(AIF_FORMAT3)){
// load percentage - ignored
fread_number(fp);
}else if ( letter == 'C' || letter == '_'){
if(letter == 'C' && AREA_IMPORT_FORMAT(AIF_FORMAT3)){
fread_string(fp); // a clan field
}else{
if(letter == '_'){ // the _ so we can eventually remove the classrestrict
fread_letter( fp ); // C
fread_letter( fp ); // A
}
pObjIndex->class_allowances=fread_wordflag(classnames_flags, fp);
}
}else if ( letter == 'R' ){
// format of R optional object line - class groups restrictions
// R [classgroup_restriction] [affectprofile] [priority] [flags]
OBJRESTRICT_LIST_DATA *pr;
classgroup_type * cg;
affectprofile_type *ap;
char * classgroup =fread_word ( fp );
char * affectprofile=fread_word ( fp );
int priority=fread_number( fp );
int flags=fread_flag( fp );
flags=0; // to get rid of compiler warning :)
cg=classgroup_lookup(classgroup);
ap=affectprofile_lookup(affectprofile);
if(!cg || !ap){
if(!cg){
bugf("Unknown classgroup '%s' for object vnum %d restriction, IGNORING!",
classgroup, vnum);
}
if(!ap){
bugf("Unknown affectprofile '%s' for object vnum %d restriction, IGNORING!",
affectprofile, vnum);
}
}else{
pr=new OBJRESTRICT_LIST_DATA;
pr->affectprofile=ap;
pr->classgroup=cg;
pr->priority=priority;
// can't have positive affect modifiers
if(ap->wear_amount>0){
bugf("positive ap->wear_amount for %s, inverted.", ap->name);
ap->wear_amount=0-ap->wear_amount;
}
// Add it to the restricts list
pr->next = pObjIndex->restrict;
pObjIndex->restrict = pr;
SET_BIT(pObjIndex->objrestrict,(1<<cg->bitindex)); // create bit quick lookup
}
}else if (letter == 'F'){
AFFECT_DATA *paf=NULL;
paf = (AFFECT_DATA *)alloc_perm( sizeof(*paf) );
letter = fread_letter(fp);
switch (letter)
{
case 'A':
paf->where = WHERE_AFFECTS;
break;
case 'B':
paf->where = WHERE_AFFECTS2;
break;
case 'I':
paf->where = WHERE_IMMUNE;
break;
case 'K':
paf->where = WHERE_SKILLS;
break;
case 'R':
paf->where = WHERE_RESIST;
break;
case 'V':
paf->where = WHERE_VULN;
break;
case 'Z':
paf->where = WHERE_OBJECTSPELL;
break;
default:
bugf( "Load_objects: Unknown where flag 'F %c'.", letter);
exit_error( 1 , "load_objects", "unknown where flag");
}
if ( paf->where == WHERE_SKILLS )
{
char *skillname = fread_word(fp);
paf->type = skill_lookup(skillname);
if(paf->type<0){
bugf("Unknown skillname '%s' found while reading area file.",
skillname);
exit_error( 1 , "load_objects", "unknown skill name");
}
paf->modifier = fread_number( fp );
paf->bitvector = 0;
} else if (paf->where == WHERE_OBJECTSPELL){
paf->location = APPLY_NONE;
char *spellname = fread_word(fp);
paf->type = skill_lookup(spellname);
if(paf->type<0){
bugf("Unknown spellname '%s' found while reading area file.",
spellname);
exit_error( 1 , "load_objects", "unknown spell name");
}
paf->level = fread_number(fp);
paf->duration = fread_number(fp);
paf->bitvector = fread_flag(fp);
}else {
paf->type = -1;
paf->location = translate_old_apply_number(fread_number(fp));
paf->modifier = fread_number(fp);
if(version==1 && AREA_IMPORT_FORMAT(AIF_FORMAT2)){
paf->bitvector = fread_number(fp);
}else{
// AIF_STOCK - the default
paf->bitvector = fread_flag(fp);
}
}
paf->duration = -1;
paf->level = pObjIndex->level;
paf->next = pObjIndex->affected;
pObjIndex->affected = paf;
top_affect++;
}
// some muds have Z for object spells
else if ( letter == 'Z' )
{
int sn;
AFFECT_DATA *paf;
char *last_word;
paf = (AFFECT_DATA*) alloc_perm (sizeof (*paf));
last_word=fread_word (fp);
sn = skill_lookup (last_word);
if (0 > sn)
{
bugf("Load_objects: unknown spell '%s'.", last_word);
exit_error( 1 , "load_objects", "unknown spell");
}else{
paf->type = sn;
}
paf->where = WHERE_OBJECTSPELL;
paf->location = APPLY_NONE;
paf->level = fread_number (fp);
paf->duration = fread_number (fp);
paf->modifier = 0;
paf->bitvector = 0;
paf->next = pObjIndex->affected;
pObjIndex->affected = paf;
}
else if ( letter == 'E' )
{
EXTRA_DESCR_DATA *ed;
ed = (EXTRA_DESCR_DATA *)alloc_perm( sizeof(*ed) );
ed->keyword = fread_string( fp );
ed->description = fread_string( fp );
if (str_len(ed->description)>MSL-4 || str_len(ed->keyword)>MSL-4 )
{
bugf("load_objects_three: Extended description in object "
"%d is %d characters!!! (more than %d)",
(int)last_vnum, str_len(ed->description), MSL-4);
exit_error( 1 , "load_objects", "extended description too long");
}
// chop off the . if it starts with that (version 3 up)
if (version>2 && ed->description[0]=='.')
{
char *temp_string;
temp_string = str_dup(ed->description);
free_string(ed->description);
ed->description= str_dup(temp_string+1);
free_string(temp_string);
}
ed->next = pObjIndex->extra_descr;
pObjIndex->extra_descr = ed;
top_ed++;
}else{ // end of optional parameters
ungetc( letter, fp );// most likely a # starting next object
break;
}
}
iHash = vnum % MAX_KEY_HASH;
pObjIndex->next = obj_index_hash[iHash];
obj_index_hash[iHash] = pObjIndex;
top_obj_index++;
}
return;
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/