static void do_thrash(struct radix_tree_root *tree, char *thrash_state, int tag) { int insert_chunk; int delete_chunk; int tag_chunk; int untag_chunk; int total_tagged = 0; int total_present = 0; for (insert_chunk = 1; insert_chunk < THRASH_SIZE; insert_chunk *= N) for (delete_chunk = 1; delete_chunk < THRASH_SIZE; delete_chunk *= N) for (tag_chunk = 1; tag_chunk < THRASH_SIZE; tag_chunk *= N) for (untag_chunk = 1; untag_chunk < THRASH_SIZE; untag_chunk *= N) { int i; unsigned long index; int nr_inserted = 0; int nr_deleted = 0; int nr_tagged = 0; int nr_untagged = 0; int actual_total_tagged; int actual_total_present; for (i = 0; i < insert_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] != NODE_ABSENT) continue; item_check_absent(tree, index); item_insert(tree, index); assert(thrash_state[index] != NODE_PRESENT); thrash_state[index] = NODE_PRESENT; nr_inserted++; total_present++; } for (i = 0; i < delete_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] == NODE_ABSENT) continue; item_check_present(tree, index); if (item_tag_get(tree, index, tag)) { assert(thrash_state[index] == NODE_TAGGED); total_tagged--; } else { assert(thrash_state[index] == NODE_PRESENT); } item_delete(tree, index); assert(thrash_state[index] != NODE_ABSENT); thrash_state[index] = NODE_ABSENT; nr_deleted++; total_present--; } for (i = 0; i < tag_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] != NODE_PRESENT) { if (item_lookup(tree, index)) assert(item_tag_get(tree, index, tag)); continue; } item_tag_set(tree, index, tag); item_tag_set(tree, index, tag); assert(thrash_state[index] != NODE_TAGGED); thrash_state[index] = NODE_TAGGED; nr_tagged++; total_tagged++; } for (i = 0; i < untag_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] != NODE_TAGGED) continue; item_check_present(tree, index); assert(item_tag_get(tree, index, tag)); item_tag_clear(tree, index, tag); item_tag_clear(tree, index, tag); assert(thrash_state[index] != NODE_PRESENT); thrash_state[index] = NODE_PRESENT; nr_untagged++; total_tagged--; } actual_total_tagged = 0; actual_total_present = 0; for (index = 0; index < THRASH_SIZE; index++) { switch (thrash_state[index]) { case NODE_ABSENT: item_check_absent(tree, index); break; case NODE_PRESENT: item_check_present(tree, index); assert(!item_tag_get(tree, index, tag)); actual_total_present++; break; case NODE_TAGGED: item_check_present(tree, index); assert(item_tag_get(tree, index, tag)); actual_total_present++; actual_total_tagged++; break; } } gang_check(tree, thrash_state, tag); printf("%d(%d) %d(%d) %d(%d) %d(%d) / " "%d(%d) present, %d(%d) tagged\n", insert_chunk, nr_inserted, delete_chunk, nr_deleted, tag_chunk, nr_tagged, untag_chunk, nr_untagged, total_present, actual_total_present, total_tagged, actual_total_tagged); } }
void copy_tag_check(void) { RADIX_TREE(tree, GFP_KERNEL); unsigned long idx[ITEMS]; unsigned long start, end, count = 0, tagged, cur, tmp; int i; // printf("generating radix tree indices...\n"); start = rand(); end = rand(); if (start > end && (rand() % 10)) { cur = start; start = end; end = cur; } /* Specifically create items around the start and the end of the range * with high probability to check for off by one errors */ cur = rand(); if (cur & 1) { item_insert(&tree, start); if (cur & 2) { if (start <= end) count++; item_tag_set(&tree, start, 0); } } if (cur & 4) { item_insert(&tree, start-1); if (cur & 8) item_tag_set(&tree, start-1, 0); } if (cur & 16) { item_insert(&tree, end); if (cur & 32) { if (start <= end) count++; item_tag_set(&tree, end, 0); } } if (cur & 64) { item_insert(&tree, end+1); if (cur & 128) item_tag_set(&tree, end+1, 0); } for (i = 0; i < ITEMS; i++) { do { idx[i] = rand(); } while (item_lookup(&tree, idx[i])); item_insert(&tree, idx[i]); if (rand() & 1) { item_tag_set(&tree, idx[i], 0); if (idx[i] >= start && idx[i] <= end) count++; } /* if (i % 1000 == 0) putchar('.'); */ } // printf("\ncopying tags...\n"); tagged = tag_tagged_items(&tree, start, end, ITEMS, XA_MARK_0, XA_MARK_1); // printf("checking copied tags\n"); assert(tagged == count); check_copied_tags(&tree, start, end, idx, ITEMS, 0, 1); /* Copy tags in several rounds */ // printf("\ncopying tags...\n"); tmp = rand() % (count / 10 + 2); tagged = tag_tagged_items(&tree, start, end, tmp, XA_MARK_0, XA_MARK_2); assert(tagged == count); // printf("%lu %lu %lu\n", tagged, tmp, count); // printf("checking copied tags\n"); check_copied_tags(&tree, start, end, idx, ITEMS, 0, 2); verify_tag_consistency(&tree, 0); verify_tag_consistency(&tree, 1); verify_tag_consistency(&tree, 2); // printf("\n"); item_kill_tree(&tree); }
void load_objects(FILE * fp) { OBJ_INDEX_DATA *pObjIndex; if (!area_last) { /* OLC */ bug("Load_objects: no #AREA seen yet.", 0); exit(1); } for (;;) { sh_int vnum; char letter; int iHash; letter = fread_letter(fp); if (letter != '#') { bug("Load_objects: # not found.", 0); exit(1); } vnum = fread_number(fp); if (vnum == 0) break; fBootDb = FALSE; if (get_obj_index(vnum) != NULL) { bug("Load_objects: vnum %d duplicated.", vnum); exit(1); } fBootDb = TRUE; pObjIndex = alloc_perm(sizeof(*pObjIndex)); pObjIndex->vnum = vnum; pObjIndex->area = area_last; /* OLC */ pObjIndex->new_format = TRUE; pObjIndex->reset_num = 0; newobjs++; pObjIndex->name = fread_string(fp); pObjIndex->short_descr = fread_string(fp); pObjIndex->description = fread_string(fp); pObjIndex->material = fread_string(fp); pObjIndex->item_type = item_lookup(fread_word(fp)); pObjIndex->extra_flags = fread_flag(fp); pObjIndex->wear_flags = fread_flag(fp); switch (pObjIndex->item_type) { case ITEM_WEAPON: pObjIndex->value[0] = weapon_type(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_CONTAINER: 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)); pObjIndex->value[3] = fread_number(fp); pObjIndex->value[4] = fread_number(fp); break; case ITEM_WAND: case ITEM_STAFF: 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)); 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->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 = 0; break; default: pObjIndex->condition = 100; break; } for (;;) { char letter; letter = fread_letter(fp); if (letter == 'A') { AFFECT_DATA *paf; paf = alloc_perm(sizeof(*paf)); paf->where = TO_OBJECT; paf->type = -1; paf->level = pObjIndex->level; paf->duration = -1; paf->location = fread_number(fp); paf->modifier = fread_number(fp); paf->bitvector = 0; paf->next = pObjIndex->affected; pObjIndex->affected = paf; top_affect++; } else if (letter == 'F') { AFFECT_DATA *paf; paf = alloc_perm(sizeof(*paf)); letter = fread_letter(fp); switch (letter) { case 'A': paf->where = TO_AFFECTS; break; case 'I': paf->where = TO_IMMUNE; break; case 'R': paf->where = TO_RESIST; break; case 'V': paf->where = TO_VULN; break; default: bug("Load_objects: Bad where on flag set.", 0); exit(1); } paf->type = -1; paf->level = pObjIndex->level; paf->duration = -1; paf->location = fread_number(fp); paf->modifier = fread_number(fp); paf->bitvector = fread_flag(fp); paf->next = pObjIndex->affected; pObjIndex->affected = paf; top_affect++; } else if (letter == 'E') { EXTRA_DESCR_DATA *ed; ed = alloc_perm(sizeof(*ed)); ed->keyword = fread_string(fp); ed->description = fread_string(fp); ed->next = pObjIndex->extra_descr; pObjIndex->extra_descr = ed; top_ed++; } else { ungetc(letter, fp); break; } } iHash = vnum % MAX_KEY_HASH; pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; top_obj_index++; top_vnum_obj = top_vnum_obj < vnum ? vnum : top_vnum_obj; /* OLC */ assign_area_vnum(vnum); /* OLC */ } return; }
/* --------------------------------------------------------------------- * CMD_EVAL * This monster evaluates an if/or/and statement * There are five kinds of statement: * 1) keyword and value (no $-code) if random 30 * 2) keyword, comparison and value if people > 2 * 3) keyword and actor if isnpc $n * 4) keyword, actor and value if carries $n sword * 5) keyword, actor, comparison and value if level $n >= 10 * *---------------------------------------------------------------------- */ int cmd_eval( sh_int vnum, char *line, int check, CHAR_DATA *mob, CHAR_DATA *ch, const void *arg1, const void *arg2, CHAR_DATA *rch ) { CHAR_DATA *lval_char = mob; CHAR_DATA *vch = (CHAR_DATA *) arg2; OBJ_DATA *obj1 = (OBJ_DATA *) arg1; OBJ_DATA *obj2 = (OBJ_DATA *) arg2; OBJ_DATA *lval_obj = NULL; char *original, buf[MAX_INPUT_LENGTH], code; int lval = 0, oper = 0, rval = -1; original = line; line = one_argument( line, buf ); if ( buf[0] == '\0' || mob == NULL ) return FALSE; /* * If this mobile has no target, let's assume our victim is the one */ if ( mob->mprog_target == NULL ) mob->mprog_target = ch; switch ( check ) { /* * Case 1: keyword and value */ case CHK_RAND: return( atoi( buf ) < number_percent() ); case CHK_MOBHERE: if ( is_number( buf ) ) return( get_mob_vnum_room( mob, atoi(buf) ) ); else return( (bool) (get_char_room( mob, buf) != NULL) ); case CHK_OBJHERE: if ( is_number( buf ) ) return( get_obj_vnum_room( mob, atoi(buf) ) ); else return( (bool) (get_obj_here( mob, buf) != NULL) ); case CHK_MOBEXISTS: return( (bool) (get_char_world( mob, buf) != NULL) ); case CHK_OBJEXISTS: return( (bool) (get_obj_world( mob, buf) != NULL) ); /* * Case 2 begins here: We sneakily use rval to indicate need * for numeric eval... */ case CHK_PEOPLE: rval = count_people_room( mob, 0 ); break; case CHK_PLAYERS: rval = count_people_room( mob, 1 ); break; case CHK_MOBS: rval = count_people_room( mob, 2 ); break; case CHK_CLONES: rval = count_people_room( mob, 3 ); break; case CHK_ORDER: rval = get_order( mob ); break; case CHK_HOUR: rval = time_info.hour; break; default:; } /* * Case 2 continued: evaluate expression */ if ( rval >= 0 ) { if ( (oper = keyword_lookup( fn_evals, buf )) < 0 ) { sprintf( buf, "Cmd_eval: prog %d syntax error(2) '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } one_argument( line, buf ); lval = rval; rval = atoi( buf ); return( num_eval( lval, oper, rval ) ); } /* * Case 3,4,5: Grab actors from $* codes */ if ( buf[0] != '$' || buf[1] == '\0' ) { sprintf( buf, "Cmd_eval: prog %d syntax error(3) '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } else code = buf[1]; switch( code ) { case 'i': lval_char = mob; break; case 'n': lval_char = ch; break; case 't': lval_char = vch; break; case 'r': lval_char = rch == NULL ? get_random_char( mob ) : rch ; break; case 'o': lval_obj = obj1; break; case 'p': lval_obj = obj2; break; case 'q': lval_char = mob->mprog_target; break; default: sprintf( buf, "Cmd_eval: prog %d syntax error(4) '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } /* * From now on, we need an actor, so if none was found, bail out */ if ( lval_char == NULL && lval_obj == NULL ) return FALSE; /* * Case 3: Keyword, comparison and value */ switch( check ) { case CHK_ISPC: return( lval_char != NULL && !IS_NPC( lval_char ) ); case CHK_ISNPC: return( lval_char != NULL && IS_NPC( lval_char ) ); case CHK_ISGOOD: return( lval_char != NULL && IS_GOOD( lval_char ) ); case CHK_ISEVIL: return( lval_char != NULL && IS_EVIL( lval_char ) ); case CHK_ISNEUTRAL: return( lval_char != NULL && IS_NEUTRAL( lval_char ) ); case CHK_ISIMMORT: return( lval_char != NULL && IS_IMMORTAL( lval_char ) ); case CHK_ISCHARM: /* A relic from MERC 2.2 MOBprograms */ return( lval_char != NULL && IS_AFFECTED( lval_char, AFF_CHARM ) ); case CHK_ISFOLLOW: return( lval_char != NULL && lval_char->master != NULL && lval_char->master->in_room == lval_char->in_room ); case CHK_ISACTIVE: return( lval_char != NULL && lval_char->position > POS_SLEEPING ); case CHK_ISDELAY: return( lval_char != NULL && lval_char->mprog_delay > 0 ); case CHK_ISVISIBLE: switch( code ) { default : case 'i': case 'n': case 't': case 'r': case 'q': return( lval_char != NULL && can_see( mob, lval_char ) ); case 'o': case 'p': return( lval_obj != NULL && can_see_obj( mob, lval_obj ) ); } case CHK_HASTARGET: return( lval_char != NULL && lval_char->mprog_target != NULL && lval_char->in_room == lval_char->mprog_target->in_room ); case CHK_ISTARGET: return( lval_char != NULL && mob->mprog_target == lval_char ); default:; } /* * Case 4: Keyword, actor and value */ line = one_argument( line, buf ); switch( check ) { case CHK_AFFECTED: return( lval_char != NULL && IS_SET(lval_char->affected_by, flag_lookup(buf, affect_flags)) ); case CHK_ACT: return( lval_char != NULL && IS_SET(lval_char->act, flag_lookup(buf, act_flags)) ); case CHK_IMM: return( lval_char != NULL && IS_SET(lval_char->imm_flags, flag_lookup(buf, imm_flags)) ); case CHK_OFF: return( lval_char != NULL && IS_SET(lval_char->off_flags, flag_lookup(buf, off_flags)) ); case CHK_CARRIES: if ( is_number( buf ) ) return( lval_char != NULL && has_item( lval_char, atoi(buf), -1, FALSE ) ); else return( lval_char != NULL && (get_obj_carry( lval_char, buf ) != NULL) ); case CHK_WEARS: if ( is_number( buf ) ) return( lval_char != NULL && has_item( lval_char, atoi(buf), -1, TRUE ) ); else return( lval_char != NULL && (get_obj_wear( lval_char, buf ) != NULL) ); case CHK_HAS: return( lval_char != NULL && has_item( lval_char, -1, item_lookup(buf), FALSE ) ); case CHK_USES: return( lval_char != NULL && has_item( lval_char, -1, item_lookup(buf), TRUE ) ); case CHK_NAME: switch( code ) { default : case 'i': case 'n': case 't': case 'r': case 'q': return( lval_char != NULL && is_name( buf, lval_char->name ) ); case 'o': case 'p': return( lval_obj != NULL && is_name( buf, lval_obj->name ) ); } case CHK_POS: return( lval_char != NULL && lval_char->position == position_lookup( buf ) ); case CHK_CLAN: return( lval_char != NULL && lval_char->clan == clan_lookup( buf ) ); case CHK_RACE: return( lval_char != NULL && lval_char->race == race_lookup( buf ) ); case CHK_OBJTYPE: return( lval_obj != NULL && lval_obj->item_type == item_lookup( buf ) ); default:; } /* * Case 5: Keyword, actor, comparison and value */ if ( (oper = keyword_lookup( fn_evals, buf )) < 0 ) { sprintf( buf, "Cmd_eval: prog %d syntax error(5): '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } one_argument( line, buf ); rval = atoi( buf ); switch( check ) { case CHK_VNUM: switch( code ) { default : case 'i': case 'n': case 't': case 'r': case 'q': if( lval_char != NULL && IS_NPC( lval_char ) ) lval = lval_char->pIndexData->vnum; break; case 'o': case 'p': if ( lval_obj != NULL ) lval = lval_obj->pIndexData->vnum; } break; case CHK_HPCNT: if ( lval_char != NULL ) lval = (lval_char->hit * 100)/(UMAX(1,lval_char->max_hit)); break; case CHK_ROOM: if ( lval_char != NULL && lval_char->in_room != NULL ) lval = lval_char->in_room->vnum; break; case CHK_SEX: if ( lval_char != NULL ) lval = lval_char->sex; break; case CHK_LEVEL: if ( lval_char != NULL ) lval = lval_char->level; break; case CHK_ALIGN: if ( lval_char != NULL ) lval = lval_char->alignment; break; case CHK_MONEY: /* Money is converted to silver... */ if ( lval_char != NULL ) lval = lval_char->gold + (lval_char->silver * 100); break; case CHK_OBJVAL0: if ( lval_obj != NULL ) lval = lval_obj->value[0]; break; case CHK_OBJVAL1: if ( lval_obj != NULL ) lval = lval_obj->value[1]; break; case CHK_OBJVAL2: if ( lval_obj != NULL ) lval = lval_obj->value[2]; break; case CHK_OBJVAL3: if ( lval_obj != NULL ) lval = lval_obj->value[3]; break; case CHK_OBJVAL4: if ( lval_obj != NULL ) lval = lval_obj->value[4]; break; case CHK_GRPSIZE: if( lval_char != NULL ) lval = count_people_room( lval_char, 4 ); break; default: return FALSE; } return( num_eval( lval, oper, rval ) ); }
/* * Snarf an obj section. new style */ void load_objects ( FILE *fp ) { ItemData *pObjIndex; if ( !area_last ) { /* OLC */ log_hd ( LOG_ERROR, "Load_objects: no #AREA seen yet." ); exit ( 1 ); } while ( true ) { int vnum; char letter; int iHash; letter = fread_letter ( fp ); if ( letter != '#' ) { log_hd ( LOG_ERROR, "Load_objects: # not found." ); exit ( 1 ); } vnum = fread_number ( fp ); if ( vnum == 0 ) { break; } fBootDb = FALSE; if ( get_obj_index ( vnum ) != NULL ) { log_hd ( LOG_ERROR, Format ( "Load_objects: vnum %d duplicated.", vnum ) ); exit ( 1 ); } fBootDb = TRUE; ALLOC_DATA ( pObjIndex, ItemData, 1 ); pObjIndex->vnum = vnum; pObjIndex->area = area_last; /* OLC */ pObjIndex->new_format = TRUE; pObjIndex->reset_num = 0; newobjs++; pObjIndex->name = fread_string ( fp ); pObjIndex->short_descr = fread_string ( fp ); pObjIndex->description = fread_string ( fp ); CHECK_POS ( pObjIndex->item_type, item_lookup ( fread_word ( fp ) ), "item_type" ); pObjIndex->extra_flags = fread_flag ( fp ); pObjIndex->wear_flags = fread_flag ( fp ); pObjIndex->material_flags = fread_flag ( fp ); switch ( pObjIndex->item_type ) { case ITEM_WEAPON: pObjIndex->value[0] = weapon_type ( 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_CONTAINER: 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 ); CHECK_POS ( pObjIndex->value[2], liq_lookup ( fread_word ( fp ) ), "liq_lookup" ); pObjIndex->value[3] = fread_number ( fp ); pObjIndex->value[4] = fread_number ( fp ); break; case ITEM_WAND: case ITEM_STAFF: 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 ) ); 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->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 = 0; break; default: pObjIndex->condition = 100; break; } while ( true ) { char letter; letter = fread_letter ( fp ); if ( letter == 'A' ) { Affect *paf; ALLOC_DATA ( paf, Affect, 1 ); paf->where = TO_OBJECT; paf->type = -1; paf->level = pObjIndex->level; paf->duration = -1; paf->location = fread_number ( fp ); paf->modifier = fread_number ( fp ); paf->bitvector = 0; paf->next = pObjIndex->affected; pObjIndex->affected = paf; top_affect++; } else if ( letter == 'F' ) { Affect *paf; ALLOC_DATA ( paf, Affect, 1 ); letter = fread_letter ( fp ); switch ( letter ) { case 'A': paf->where = TO_AFFECTS; break; case 'I': paf->where = TO_IMMUNE; break; case 'R': paf->where = TO_RESIST; break; case 'V': paf->where = TO_VULN; break; default: log_hd ( LOG_ERROR, "Load_objects: Bad where on flag set." ); exit ( 1 ); } paf->type = -1; paf->level = pObjIndex->level; paf->duration = -1; paf->location = fread_number ( fp ); paf->modifier = fread_number ( fp ); paf->bitvector = fread_flag ( fp ); paf->next = pObjIndex->affected; pObjIndex->affected = paf; top_affect++; } else if ( letter == 'E' ) { DescriptionData *ed; ALLOC_DATA ( ed, DescriptionData, 1 ); ed->keyword = fread_string ( fp ); ed->description = fread_string ( fp ); ed->next = pObjIndex->extra_descr; pObjIndex->extra_descr = ed; top_ed++; } else if ( letter == 'R' ) { pObjIndex->requirements[SIZ_REQ] = fread_number ( fp ); pObjIndex->requirements[STR_REQ] = fread_number ( fp ); pObjIndex->requirements[DEX_REQ] = fread_number ( fp ); pObjIndex->requirements[CON_REQ] = fread_number ( fp ); pObjIndex->requirements[INT_REQ] = fread_number ( fp ); pObjIndex->requirements[WIS_REQ] = fread_number ( fp ); } else if ( letter == 'L' ) { pObjIndex->repop_percent = fread_number ( fp ); } else { ungetc ( letter, fp ); break; } } iHash = vnum % MAX_KEY_HASH; pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; top_obj_index++; top_vnum_obj = top_vnum_obj < vnum ? vnum : top_vnum_obj; /* OLC */ assign_area_vnum ( vnum ); /* OLC */ } return; }