/***************************************************************************
* 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-1996 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@efn.org) *
* Gabrielle Taylor *
* 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 *
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include "merc.h"
#include "utils.h"
#include "db.h"
#include "lookup.h"
#include "tables.h"
/* values for db2.c */
extern int flag_lookup
args((const char *name, const struct flag_type * flag_table));
struct social_type social_table[MAX_SOCIALS];
int social_count;
/* snarf a socials file */
void load_socials(FILE * fp)
{
for (;;) {
struct social_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"))
return; /* done */
#if defined(social_debug)
else
fprintf(stderr, "%s\n\r", 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++;
}
return;
}
/*
* Snarf a mob section. new style
*/
void load_mobiles(FILE * fp)
{
MOB_INDEX_DATA *pMobIndex;
if (!area_last) { /* OLC */
bug("Load_mobiles: no #AREA seen yet.", 0);
exit(1);
}
for (;;) {
long vnum;
char letter;
int iHash;
letter = fread_letter(fp);
if (letter != '#') {
bug("Load_mobiles: # not found.", 0);
exit(1);
}
vnum = fread_number(fp);
if (vnum == 0)
break;
fBootDb = FALSE;
if (get_mob_index(vnum) != NULL) {
bug("Load_mobiles: vnum %d duplicated.", vnum);
exit(1);
}
fBootDb = TRUE;
pMobIndex = alloc_perm(sizeof(*pMobIndex));
pMobIndex->vnum = vnum;
pMobIndex->area = area_last; /* OLC */
pMobIndex->new_format = TRUE;
newmobs++;
pMobIndex->player_name = fread_string(fp);
pMobIndex->short_descr = fread_string(fp);
pMobIndex->long_descr = fread_string(fp);
pMobIndex->description = fread_string(fp);
pMobIndex->race = race_lookup(fread_string(fp));
pMobIndex->long_descr[0] = UPPER(pMobIndex->long_descr[0]);
pMobIndex->description[0] = UPPER(pMobIndex->description[0]);
pMobIndex->act = fread_flag(fp) | ACT_IS_NPC
| pMobIndex->race->act;
pMobIndex->affected_by = fread_flag(fp)
| pMobIndex->race->aff;
pMobIndex->pShop = NULL;
pMobIndex->alignment = fread_number(fp);
pMobIndex->group = fread_number(fp);
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);
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);
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 */
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;
/* read flags and add in data from the race table */
pMobIndex->off_flags = fread_flag(fp)
| pMobIndex->race->off;
pMobIndex->imm_flags = fread_flag(fp)
| pMobIndex->race->imm;
pMobIndex->res_flags = fread_flag(fp)
| pMobIndex->race->res;
pMobIndex->vuln_flags = fread_flag(fp)
| pMobIndex->race->vuln;
/* vital statistics */
pMobIndex->start_pos = position_lookup(fread_word(fp));
pMobIndex->default_pos = position_lookup(fread_word(fp));
pMobIndex->sex = sex_lookup(fread_word(fp));
pMobIndex->wealth = fread_number(fp);
pMobIndex->form = fread_flag(fp)
| pMobIndex->race->form;
pMobIndex->parts = fread_flag(fp)
| pMobIndex->race->parts;
/* size */
pMobIndex->size = size_lookup(fread_word(fp));
pMobIndex->material = str_dup(fread_word(fp));
for (;;) {
letter = fread_letter(fp);
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->off_flags, 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 {
bug("Flag remove: flag not found.", 0);
exit(1);
}
} else if (letter == 'M') {
MPROG_LIST *pMprog;
char *word;
int trigger = 0;
pMprog = alloc_perm(sizeof(*pMprog));
word = fread_word(fp);
if (!(trigger = flag_lookup(word, mprog_flags))) {
bug("MOBprogs: invalid trigger.", 0);
exit(1);
}
SET_BIT(pMobIndex->mprog_flags, trigger);
pMprog->trig_type = trigger;
pMprog->vnum = fread_number(fp);
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++;
top_vnum_mob = top_vnum_mob < vnum ? vnum : top_vnum_mob; /* OLC */
assign_area_vnum(vnum); /* OLC */
kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL - 1)].number++;
}
return;
}
/*
* Snarf an obj section. new style
*/
void load_objects(FILE * fp)
{
OBJ_INDEX_DATA *pObjIndex;
if (!area_last) { /* OLC */
bug("Load_objects: no #AREA seen yet.", 0);
exit(1);
}
for (;;) {
long 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_BLOOD_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);
if (pObjIndex->value[2] == -1)
pObjIndex->value[2] = 0;
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));
/*
if (pObjIndex->value[3] == -1) {
pObjIndex->value[3] = skill_lookup("bolt");
}
*/
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);
if (pObjIndex->level < 1)
pObjIndex->level = 1;
pObjIndex->weight = fread_number(fp);
pObjIndex->cost = fread_number(fp);
pObjIndex->timer = fread_number(fp);
if ((pObjIndex->item_type == ITEM_ARMOR
|| pObjIndex->item_type == ITEM_WEAPON)
&& (pObjIndex->cost > pObjIndex->level * 25)
&& (pObjIndex->vnum < 6700 && pObjIndex->vnum > 6799))
pObjIndex->cost = pObjIndex->level * 25;
if (0) {
pObjIndex->cost = pObjIndex->level * 4;
switch (pObjIndex->item_type) {
case ITEM_WEAPON:
switch (pObjIndex->value[0]) {
case WEAPON_EXOTIC:
case WEAPON_WHIP:
case WEAPON_DAGGER:
pObjIndex->value[1] = pObjIndex->level / 4 + 1;
pObjIndex->value[2] = pObjIndex->level / 6 + 1;
/* Need to evaluate flags. pObjIndex->value[4]; */
pObjIndex->cost *=
((pObjIndex->value[1] / 2) +
(pObjIndex->value[2] / 2));
pObjIndex->weight = pObjIndex->level * 3;
break;
case WEAPON_SWORD:
case WEAPON_AXE:
pObjIndex->value[1] = pObjIndex->level / 8 + 1;
pObjIndex->value[2] = pObjIndex->level / 12 + 1;
/* Need to evaluate flags. pObjIndex->value[4]; */
pObjIndex->cost *=
((pObjIndex->value[1] / 2) +
(pObjIndex->value[2] / 2));
pObjIndex->weight = pObjIndex->level * 3;
break;
case WEAPON_SPEAR:
case WEAPON_POLEARM:
pObjIndex->value[1] = pObjIndex->level / 6 + 1;
pObjIndex->value[2] = pObjIndex->level / 11 + 1;
/* Need to evaluate flags. pObjIndex->value[4]; */
pObjIndex->cost *=
((pObjIndex->value[1] / 2) +
(pObjIndex->value[2] / 2));
pObjIndex->weight = pObjIndex->level * 3;
break;
case WEAPON_MACE:
case WEAPON_FLAIL:
pObjIndex->value[1] = pObjIndex->level / 7 + 1;
pObjIndex->value[2] = pObjIndex->level / 10 + 1;
/* Need to evaluate flags. pObjIndex->value[4]; */
pObjIndex->cost *=
((pObjIndex->value[1] / 2) +
(pObjIndex->value[2] / 2));
pObjIndex->weight = pObjIndex->level * 3;
break;
default:
pObjIndex->value[1] = pObjIndex->level / 4 + 1;
pObjIndex->value[2] = pObjIndex->level / 6 + 1;
/* Need to evaluate flags. pObjIndex->value[4]; */
pObjIndex->cost *=
((pObjIndex->value[1] / 2) +
(pObjIndex->value[2] / 2));
pObjIndex->weight = pObjIndex->level * 3;
break;
}
break;
case ITEM_CONTAINER:
pObjIndex->value[0] = pObjIndex->level / 5 + 1;
pObjIndex->value[3] = pObjIndex->level * 3;
pObjIndex->value[4] = 100;
pObjIndex->cost += pObjIndex->level;
break;
case ITEM_DRINK_CON:
case ITEM_BLOOD_CON:
pObjIndex->value[0] = pObjIndex->level;
pObjIndex->value[1] = pObjIndex->level;
pObjIndex->cost += pObjIndex->level;
break;
case ITEM_WAND:
case ITEM_STAFF:
pObjIndex->value[0] = pObjIndex->level;
pObjIndex->value[1] = pObjIndex->level / 10 + 1;
pObjIndex->value[2] = pObjIndex->level / 10 + 1;
pObjIndex->cost += pObjIndex->level * pObjIndex->value[2];
pObjIndex->weight = pObjIndex->level * 4 / 3;
break;
case ITEM_POTION:
case ITEM_PILL:
case ITEM_SCROLL:
pObjIndex->value[0] = pObjIndex->level;
if (pObjIndex->level < 51)
pObjIndex->value[3] = -1;
if (pObjIndex->level < 101)
pObjIndex->value[4] = -1;
break;
case ITEM_ARMOR:
pObjIndex->value[0] = pObjIndex->level / 3;
pObjIndex->value[1] = pObjIndex->level / 3;
pObjIndex->value[2] = pObjIndex->level / 3;
pObjIndex->cost += pObjIndex->level * pObjIndex->value[2];
pObjIndex->weight = pObjIndex->level * 4 / 3;
break;
case ITEM_LIGHT:
pObjIndex->value[2] = pObjIndex->level * 10;
pObjIndex->cost = pObjIndex->level * 5;
pObjIndex->weight = pObjIndex->level * 4 / 3;
break;
case ITEM_FOOD:
pObjIndex->value[0] = number_range(1, 24);
pObjIndex->value[1] = 0;
pObjIndex->cost = pObjIndex->value[0] * 5;
pObjIndex->weight = pObjIndex->value[0];
pObjIndex->level = 1;
break;
case ITEM_JEWELRY:
case ITEM_TREASURE:
case ITEM_GEM:
pObjIndex->cost = pObjIndex->level * 20;
pObjIndex->weight = pObjIndex->level;
pObjIndex->level = 1;
break;
default:
pObjIndex->cost = pObjIndex->level + 1;
pObjIndex->weight = pObjIndex->level * 4 / 3;
break;
}
}
/* 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;
}