/*
* Alf Salte (Alf) June 1990
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "kernel.h"
#include <stdarg.h>
#define get_oref(z,F) ((XOBJ *)get_ref('O',z,F))
#define get_lref(z,F) get_ref('L', z, F)
#define get_mref(z,F) ((XMOB *)get_ref('M', z, F))
#include "cflags.h"
#include "mflagnames.h"
#include "pflagnames.h"
#include "sflagnames.h"
#include "lflagnames.h"
#include "oflagnames.h"
#include "aflagnames.h"
#include "eflagnames.h"
#include "exitnames.h"
#include "lflags.h"
#define UNKNOWN ((XOBJ *)(-1))
#define BAD ((XOBJ *)(-2))
#define GOOD ((XOBJ *)(-3))
#define REFERRED ((XOBJ *)(-4))
#define DEFINED ((XOBJ *)(-5))
#define IS_LINK 0
#define IS_CONTAINED 1
#define IS_CHECK 2
#undef DEBUG
typedef struct _XZON {
char *name;
char *fname;
int zone; /* This zone's number */
int latitude;
int rainfall;
int loc; /* The loc number of room ZONE0 */
int n_loc; /* Number of locations in this zone */
int mob; /* The mob number of first mobile in zone */
int n_mob; /* Number of mobiles in this zone */
struct _XLOC *locs;
struct _XOBJ *objs;
struct _XMOB *mobs;
struct _XLOC *rlocs;
struct _XMOB *rmobs;
} XZON;
typedef struct _XMOB {
struct _XOBJ *aux;
struct _XZON *zone;
struct _XMOB *next;
char *name;
char *pname;
int mob;
struct _XLOC *loc;
int str;
int armor;
int damage;
int agg;
int speed;
int vis;
int wimpy;
PFLAGS pflags;
SFLAGS sflags;
MFLAGS mflags;
EFLAGS eflags;
int attitude;
int att_param;
char *desc;
char *exam;
} XMOB;
typedef struct _XOBJ {
struct _XOBJ *aux;
struct _XZON *zone;
struct _XOBJ *next;
char *name;
struct _XOBJ *the_next;
struct _XOBJ *linked;
char *pname;
char *aname;
int obj;
int cflag;
struct _XLOC *loc;
unsigned char damage;
unsigned char armor;
OFLAGS oflags;
AFLAGS aflags;
int state;
int mstate;
int bvalue;
int osize;
int oweight;
char *desc[4];
char *examine;
int vis;
} XOBJ;
typedef struct _XLOC {
struct _XOBJ *aux;
struct _XZON *zone;
struct _XLOC *next;
char *name;
char *pname;
int loc;
int altitude;
LFLAGS lflags;
char exit_types[NEXITS];
struct _XLOC *exits[NEXITS];
char *description;
} XLOC;
char *strchr ();
char *main_file;
char *log_file;
char *zone_file;
char *mobh_file;
char *mob_file;
char *objh_file;
char *obj_file;
char *reset_list;
char *loch_file;
char *loc_file;
FILE *LogFile;
int n_logs;
char dir[512];
XZON zones[400];
XMOB mobs[10000];
XOBJ objs[10000];
XLOC locns[10000];
char texts[2000000];
char *textsp = texts;
int num_z = 0;
int num_m = 0;
int num_o = 0;
int num_l = 0;
int num_linked = 0;
int num_unlinked = 0;
XOBJ *obj_list = NULL;
XOBJ *obj_list_l = NULL; /* last */
#define T_NAME 0
#define T_PNAME 1
#define T_LOC 2
#define T_DESC 3
#define T_END 4
#define TMOB_STR 5
#define TMOB_DAM 6
#define TMOB_ARMOR 7
#define TMOB_AGG 8
#define TMOB_SFLAGS 9
#define TMOB_PFLAGS 10
#define TMOB_MFLAGS 11
#define TMOB_SPEED 12
#define TMOB_EXAM 13
#define TMOB_VIS 14
#define TMOB_WIMPY 15
#define TMOB_EFLAGS 16
#define TOBJ_ANAME 5
#define TOBJ_OFLAGS 6
#define TOBJ_ARMOR 7
#define TOBJ_DAMAGE 8
#define TOBJ_MAX_STATE 9
#define TOBJ_STATE 10
#define TOBJ_BVALUE 11
#define TOBJ_SIZE 12
#define TOBJ_WEIGHT 13
#define TOBJ_EXAM 14
#define TOBJ_LINKED 15
#define TOBJ_VIS 16
#define TOBJ_AFLAGS 17
char *Mob_tab[] =
{
"Name", "Pname", "Location", "Description", "End",
"Strength", "Damage", "Armor", "Aggression", "SFlags",
"PFlags", "MFlags", "Speed", "Examine", "Visibility",
"Wimpy", "EFlags", TABLE_END
};
char *Obj_tab[] =
{
"Name", "Pname", "Location", "Description", "End",
"AltName", "Oflags", "Armor", "Damage",
"MaxState", "State", "BValue", "Size",
"Weight", "Examine", "Linked", "Visibility", "AFlags",
TABLE_END
};
char *Cflags[] =
{
"In room", "In container", "Carried by", "Worn by",
"Wielded by", "Both worn and wielded by"
};
void xexit (code)
int code;
{
exit (code);
}
void log (char t, XOBJ * O, XZON * Z, char *f,...);
/*
* ** Open file for read/write or die trying
*/
static FILE *
Do_fopen (char *name, char *mode)
{
char *m;
FILE *file;
Boolean b;
b = False;
if (*(m = mode) == 'p') {
b = True;
++m;
}
if (*name == '-' && !name[1])
return *mode == 'w' ? stdout : stdin;
file = (b ? popen (name, m) : fopen (name, m));
if (!file) {
perror (name);
(void) fprintf (stderr, "Unable to open file for %s(%s)\n",
(*m == 'w' ? "write" : "read"), mode);
xexit (1);
}
return file;
}
char *
xfgets (char *b, int s, FILE * f)
{
int k;
int c = 0;
char *t;
for (t = b, k = s; --k >= 0 && (c = fgetc (f)) != EOF && c != '\n';)
*t++ = c;
if (c == EOF && t == b)
return NULL;
*t = 0;
return b;
}
char *
alloc_text (int s)
{
char *p;
textsp = (p = textsp) + s;
return p;
}
char *
save_text (char *t)
{
int s;
char *u;
s = strlen (t) + 1;
u = alloc_text (s);
bcopy (t, u, s);
return u;
}
char *
get_fname (FILE * a, char *d)
{
char *p;
register char *q;
int c, k;
while ((c = getc (a)) == ' ' || c == '\t') ;
q = (p = textsp);
if (c != '/') {
k = strlen (d);
bcopy (d, q, k);
q += k;
}
do {
*q++ = c;
c = getc (a);
}
while (!isspace (c));
while (c != '\n')
c = getc (a);
*q++ = 0;
textsp = q;
return p;
}
char *
get_text (FILE * a)
{
char *p;
register char *q;
int c, d;
q = (p = textsp);
while ((c = getc (a)) == ' ' || c == '\t') ;
if (ispunct (c)) {
d = c;
} else {
d = 0;
ungetc (c, a);
}
if ((c = getc (a)) != '\n')
ungetc (c, a);
while ((c = getc (a)) != d) {
if (d == 0 && isspace (c))
break;
*q++ = c;
}
if (d == 0)
ungetc (c, a);
*q++ = 0;
textsp = q;
return p;
}
char *
get_exam (FILE * a)
{
char *p;
register char *q;
int c, d;
q = (p = textsp);
c = getc (a);
while (isspace (c))
c = getc (a);
d = c;
if ((c = getc (a)) != '\n')
ungetc (c, a);
while ((c = getc (a)) != d && c != EOF)
*q++ = c;
if (q[-1] != '\n')
*q++ = '\n';
*q++ = 0;
textsp = q;
return p;
}
char *
get_description (FILE * a)
{
char *p;
register char *q;
int c;
q = (p = textsp);
while (True) {
while ((c = getc (a)) != '^') {
do {
*q++ = c;
}
while ((c = getc (a)) != '\n');
*q++ = '\n';
}
if ((c = getc (a)) == '\n')
break;
*q++ = '^';
*q++ = c;
while ((*q++ = c = getc (a)) != '\n') ;
}
*q++ = 0;
textsp = q;
return p;
}
FILE *
xopen (char *f, char *m)
{
FILE *x;
if ((x = fopen (f, m)) == 0) {
perror (f);
xexit (1);
}
return x;
}
int
read_main (char *mf)
{
char b[128];
char n[128];
FILE *f;
XZON *p;
int z;
int k;
char *s;
char *t;
char *u;
f = xopen (mf, "r");
main_file = mf;
for (s = dir, t = main_file, u = NULL; *t != 0; ++s, ++t) {
if ((*s = *t) == '/')
u = s;
}
if (u == NULL)
*(u = s = dir) = 0;
else
*++u = 0;
log_file = get_fname (f, dir);
zone_file = get_fname (f, dir);
mobh_file = get_fname (f, dir);
mob_file = get_fname (f, dir);
objh_file = get_fname (f, dir);
obj_file = get_fname (f, dir);
reset_list = get_fname (f, dir);
loch_file = get_fname (f, dir);
loc_file = get_fname (f, dir);
if ((LogFile = fopen (log_file, "w")) == NULL) {
perror (log_file);
exit (1);
}
n_logs = 0;
for (z = 0, p = zones; xfgets (b, sizeof (b), f) != NULL;) {
for (s = b; isalpha (*s); ++s) ;
if ((k = s - b) == 0)
continue;
t = alloc_text (k + 1);
bcopy (b, t, k);
t[k] = 0;
p->name = t;
while (*s == ' ' || *s == '\t')
++s;
if (isalpha (*s) || *s == '/' || *s == '.') {
for (t = s; isalpha (*s) || *s == '/' || *s == '.'; ++s) ;
*s = 0;
if (*t != '/') {
sprintf (n, "%s%s", dir, t);
t = n;
}
} else {
sprintf (n, "%s%s.zone", dir, t);
t = n;
}
k = strlen (t);
s = alloc_text (k + 1);
bcopy (t, s, k);
s[k] = 0;
p->fname = s;
p->loc = 0;
p->latitude = 0;
p->rainfall = 0;
p->locs = (XLOC *) 0;
p->mobs = (XMOB *) 0;
p->objs = (XOBJ *) 0;
p->zone = z;
++z;
++p;
}
fclose (f);
return num_z = z;
}
FILE *
zopen (char *fn, char *zn, Boolean * m, char *b, int bs)
{
FILE *f;
char *s;
char *t;
char buff[128];
sprintf (buff, "/lib/cpp -P -traditional -I../include %s", fn);
f = popen (buff, "r");
if (f == NULL) {
fprintf (stderr, "\nError when opening file %s for zone %s\n",
fn, zn);
perror (fn);
xexit (1);
}
*m = False;
do {
if (xfgets (b, bs, f) == NULL) {
pclose (f);
return NULL;
}
}
while (b[0] != '%');
if (strncasecmp (&b[1], "zone:", 5) == 0) {
*m = True;
for (;;) {
for (s = &b[6]; *s == ' ' || *s == '\t'; ++s) ;
for (t = s; isalpha (*t); ++t) ;
*t = 0;
if (strcasecmp (s, zn) == 0) {
while (xfgets (b, bs, f)) {
if (b[0] == '%')
return f;
}
pclose (f);
return NULL;
}
do {
if (xfgets (b, bs, f) == NULL) {
pclose (f);
return NULL;
}
}
while (strncasecmp (b, "%zone:", 6) != 0);
}
}
return f;
}
int
lookup (char *s, char **t)
{
char **u;
int l;
int x;
l = strlen (s);
for (u = t, x = 0; *u != TABLE_END; u++, x++) {
if (*u == NULL)
continue;
if (strncasecmp (s, *u, l) == 0)
return x;
}
return -1;
}
XMOB *
find_mob (XZON * z, char *name)
{
XMOB *m, *q = NULL;
char *s;
for (m = z->mobs; m != NULL; m = m->next) {
if (strcasecmp (m->name, name) == 0)
return m;
}
for (m = z->rmobs; m != NULL; m = m->next) {
if (strcasecmp (m->name, name) == 0)
return m;
q = m;
}
m = &mobs[num_m++];
bzero ((char *) m, sizeof (XMOB));
m->next = NULL;
if (q == NULL)
z->rmobs = m;
else
q->next = m;
m->name = s = save_text (name);
lowercase (s);
*s = toupper (*s);
if (strncmp (m->name, "The ", 4) == 0) {
s += 4;
*s = toupper (*s);
}
m->zone = z;
m->mob = -1;
m->aux = REFERRED;
return m;
}
XOBJ *
find_obj (XZON * z, char *name)
{
XOBJ *o, *q = NULL;
char *s;
for (o = z->objs; o != NULL; o = o->next) {
if (strcasecmp (o->name, name) == 0)
return o;
q = o;
}
o = &objs[num_o++];
bzero ((char *) o, sizeof (XOBJ));
o->next = NULL;
if (q == NULL)
z->objs = o;
else
q->next = o;
o->name = s = save_text (name);
lowercase (s);
o->zone = z;
o->obj = -1;
o->aux = REFERRED;
return o;
}
XLOC *
find_loc (XZON * z, char *name)
{
XLOC *l, *q = NULL;
for (l = z->locs; l != NULL; l = l->next) {
if (strcasecmp (l->name, name) == 0)
return l;
}
for (l = z->rlocs; l != NULL; l = l->next) {
if (strcasecmp (l->name, name) == 0)
return l;
q = l;
}
l = &locns[num_l++];
bzero ((char *) l, sizeof (XLOC));
l->next = NULL;
if (q == NULL)
z->rlocs = l;
else
q->next = l;
l->name = save_text (name);
l->zone = z;
l->loc = -1;
l->aux = REFERRED;
return l;
}
XLOC *
get_ref (char t, XZON * zo, FILE * F)
{
char n[128];
char zone[128];
char *s;
XZON *z;
int c;
int x;
for (s = n, c = getc (F); isalnum (c) || c == '_'; c = getc (F)) {
*s++ = c;
}
*s = 0;
z = zo;
if (c == '@') {
for (s = zone, c = getc (F); isalpha (c); c = getc (F)) {
*s++ = c;
}
*s = 0;
for (z = zones, x = 0; x < num_z; ++z, ++x) {
if (strcasecmp (z->name, zone) == 0)
break;
}
if (x == num_z) {
ungetc (c, F);
return 0; /* Couldn't find entry */
}
}
ungetc (c, F);
switch (t) {
case 'L':
return (XLOC *) find_loc (z, n);
break;
case 'O':
return (XLOC *) find_obj (z, n);
break;
case 'M':
return (XLOC *) find_mob (z, n);
break;
}
return 0;
}
int
get_int (FILE * F)
{
int i;
int c;
Boolean neg;
c = getc (F);
while (c == ' ' || c == '\t')
c = getc (F);
i = 0;
if ((neg = c == '-')) {
c = getc (F);
}
while (isdigit (c)) {
i = i * 10 + (c - '0');
c = getc (F);
}
ungetc (c, F);
if (neg)
i = -i;
return i;
}
void
get_flags (XZON * z, XMOB * m, char ty, int *f, int s, char **t, FILE * F)
{
char n[128];
int c;
char *p;
int k;
c = getc (F);
while (c != '{')
c = getc (F);
bzero (f, s);
for (c = getc (F); c != '}'; c = getc (F)) {
if (!isalpha (c)) {
continue;
}
for (p = n; isalpha (c); c = getc (F)) {
*p++ = c;
}
ungetc (c, F);
*p = 0;
if ((k = lookup (n, t)) == -1) {
fprintf (stderr,
"\nError in %s@%s, %cFLAGS: unknown flag %s.\n",
m->name, z->name, ty, n);
xexit (1);
}
f[s - k / 32 - 1] |= (1 << (k % 32));
}
}
void
mkdef_mob (XZON * z, XMOB * m)
{
XMOB *p;
if (m->aux != REFERRED) {
fprintf (stderr, "\nMobile %s@%s is defined twice!\n", m->name, z->name);
xexit (1);
}
if ((p = z->rmobs) == m) {
z->rmobs = m->next;
} else {
while (p->next != m)
p = p->next;
p->next = m->next;
}
m->aux = DEFINED;
m->mob = -1;
m->pname = m->name;
m->next = NULL;
if ((p = z->mobs) == NULL)
z->mobs = m;
else {
while (p->next != NULL)
p = p->next;
p->next = m;
}
}
Boolean
read_mob (FILE * F, XZON * z, char *b, int bs)
{
XMOB *m;
char s[128];
char n[128];
int c;
int d;
char *t;
char *v;
int k;
int i;
m = NULL;
for (;;) {
do {
c = getc (F);
}
while (isspace (c));
for (t = s; isalnum (c) || c == '_'; c = getc (F))
*t++ = c;
*t = 0;
if (t == s) {
if (c == EOF) {
return False;
}
if (c != '%')
continue;
ungetc (c, F);
break;
}
i = -1;
while (c == ' ' || c == '\t' || c == '=')
c = getc (F);
ungetc (c, F);
k = lookup (s, Mob_tab);
if (k != T_NAME && m == NULL) {
fprintf (stderr,
"\nError in zone mob:%s: Entry %s is out of sequence.\n",
z->name, s);
xexit (1);
}
switch (k) {
case T_NAME:
d = 0;
c = getc (F);
for (t = n; isalnum (c) || c == '_'; c = getc (F)) {
*t++ = c;
}
*t = 0;
ungetc (c, F);
m = find_mob (z, n);
mkdef_mob (z, m);
m->mob = -1;
m->pname = m->name;
m->loc = 0;
m->str = 0;
m->armor = 0;
m->damage = 10;
m->vis = 0;
m->agg = 0;
m->speed = -1;
m->wimpy = 0;
m->pflags.u = 0;
m->pflags.h = 0;
m->pflags.l = 0;
m->mflags.h = 0;
m->mflags.l = 0;
m->sflags.h = 0;
m->sflags.l = 0;
m->eflags.h = 0;
m->eflags.l = 0;
m->attitude = 0;
m->att_param = 0;
m->desc = NULL;
m->exam = NULL;
#ifdef DEBUG
printf( "\rMobile %s@%s.%-30s", m->name, z->name, "" );
#endif
break;
case T_PNAME:
m->pname = v = get_text (F);
lowercase (v);
*v = toupper (*v);
if (strncmp (m->pname, "The ", 4) == 0) {
v += 4;
*v = toupper (*v);
}
break;
case T_LOC:
m->loc = get_lref (z, F);
break;
case T_DESC:
m->desc = get_text (F);
break;
case T_END:
d = 0;
c = getc (F);
for (t = n; isalnum (c) || c == '_'; c = getc (F)) {
*t++ = c;
}
*t = 0;
ungetc (c, F);
if (strcasecmp (n, m->name) != 0) {
log ('M', (XOBJ *) m, z, "Wrong arg to end: %s.", n);
m->aux = BAD;
}
m = NULL;
break;
case TMOB_STR:
m->str = get_int (F);
break;
case TMOB_ARMOR:
m->armor = get_int (F);
break;
case TMOB_DAM:
m->damage = get_int (F);
break;
case TMOB_WIMPY:
m->wimpy = get_int (F);
break;
case TMOB_VIS:
m->vis = get_int (F);
break;
case TMOB_AGG:
m->agg = get_int (F);
break;
case TMOB_SPEED:
m->speed = get_int (F);
break;
case TMOB_EXAM:
m->exam = get_exam (F);
break;
case TMOB_SFLAGS:
get_flags (z, m, 'S', (int *) &(m->sflags),
sizeof (SFLAGS) / sizeof (int), Sflags, F);
break;
case TMOB_PFLAGS:
get_flags (z, m, 'P', (int *) &(m->pflags),
sizeof (PFLAGS) / sizeof (int), Pflags, F);
break;
case TMOB_MFLAGS:
get_flags (z, m, 'M', (int *) &(m->mflags),
sizeof (MFLAGS) / sizeof (int), Mflags, F);
break;
case TMOB_EFLAGS:
get_flags (z, m, 'E', (int *) &(m->eflags),
sizeof (EFLAGS) / sizeof (int), Eflags, F);
break;
case -1:
fprintf (stderr,
"\nError in zone mob:%s: %s is not a legal entry.\n",
z->name, s);
xexit (1);
default:
fprintf (stderr,
"\nError in zone mob:%s: %s isn't implemented yet.\n",
z->name, s);
xexit (1);
}
while ((c = getc (F)) != '\n') {
if (c == EOF)
return False;
}
}
xfgets (b, bs, F);
return True;
}
Boolean
read_obj (FILE * F, XZON * z, char *b, int bs)
{
XOBJ *o;
char s[128];
char n[128];
int c;
int d;
char *t;
int k;
int i;
int cf;
char cft = 0;
o = NULL;
for (;;) {
do {
c = getc (F);
}
while (isspace (c));
for (t = s; isalnum (c) || c == '_'; c = getc (F))
*t++ = c;
*t = 0;
if (t == s) {
if (c == EOF) {
return False;
}
if (c != '%')
continue;
ungetc (c, F);
break;
}
i = -1;
if (c == '[') {
c = getc (F);
for (i = 0; isdigit (c); i = i * 10 + (c - '0'), c = getc (F)) ;
if (c != ']') {
fprintf (stderr,
"\nError in zone obj:%s: not number in [..]\n",
z->name);
}
c = getc (F);
}
while (c == ' ' || c == '\t' || c == '=')
c = getc (F);
ungetc (c, F);
k = lookup (s, Obj_tab);
if (k != T_NAME && o == NULL) {
fprintf (stderr,
"\nError in zone obj:%s: Entry %s is out of sequence.\n",
z->name, s);
xexit (1);
}
switch (k) {
case T_NAME:
d = 0;
c = getc (F);
for (t = n; isalnum (c) || c == '_'; c = getc (F)) {
*t++ = c;
}
*t = 0;
ungetc (c, F);
o = find_obj (z, n);
if (o->aux != REFERRED) {
fprintf (stderr, "\nObject %s@%s is defined twice!\n",
n, z->name);
xexit (1);
}
o->aux = DEFINED;
o->obj = -1;
o->pname = o->name;
o->linked = NULL;
o->aname = NULL;
o->cflag = -1;
o->loc = 0;
o->damage = 0;
o->armor = 0;
o->oflags.h = 0;
o->oflags.l = 0;
o->aflags = 0;
o->state = -1;
o->mstate = 0;
o->bvalue = 0;
o->osize = 0;
o->oweight = 0;
o->desc[0] = NULL;
o->desc[1] = NULL;
o->desc[2] = NULL;
o->desc[3] = NULL;
o->examine = NULL;
o->vis = 0;
break;
case T_PNAME:
o->pname = get_text (F);
lowercase (o->pname);
break;
case T_LOC:
fscanf (F, "%d\t:", &cf);
switch (cf) {
case IN_ROOM:
cft = 'L';
break;
case IN_CONTAINER:
cft = 'O';
break;
case CARRIED_BY:
case WIELDED_BY:
case WORN_BY:
case BOTH_BY:
cft = 'M';
break;
default:
fprintf (stderr,
"\nError in obj:%s@%s: Illegal carry flag %d.\n",
o->name, z->name, cf);
xexit (1);
}
o->cflag = cf;
o->loc = get_ref (cft, z, F);
break;
case T_DESC:
if (i < 0 || i >= 4) {
fprintf (stderr,
"\nError in obj:%s@%s: Illegal index in Desc %d.\n",
o->name, z->name, i);
}
o->desc[i] = get_text (F);
break;
case T_END:
d = 0;
c = getc (F);
for (t = n; isalnum (c) || c == '_'; c = getc (F)) {
*t++ = c;
}
*t = 0;
ungetc (c, F);
if (strcasecmp (n, o->name) != 0) {
log ('O', o, z, "Wrong arg to end: %s.", n);
o->aux = BAD;
}
o = NULL;
break;
case TOBJ_ANAME:
o->aname = get_text (F);
break;
case TOBJ_OFLAGS:
get_flags (z, (XMOB *) o, 'O',
(int *) &(o->oflags), sizeof (OFLAGS) / sizeof (int), Oflags, F);
break;
case TOBJ_AFLAGS:
get_flags (z, (XMOB *) o, 'A',
(int *) &(o->aflags), sizeof (AFLAGS) / sizeof (int), Aflags, F);
break;
case TOBJ_ARMOR:
o->armor = get_int (F);
break;
case TOBJ_DAMAGE:
o->damage = get_int (F);
break;
case TOBJ_MAX_STATE:
o->mstate = get_int (F);
break;
case TOBJ_STATE:
o->state = get_int (F);
break;
case TOBJ_BVALUE:
o->bvalue = get_int (F);
break;
case TOBJ_SIZE:
o->osize = get_int (F);
break;
case TOBJ_WEIGHT:
o->oweight = get_int (F);
break;
case TOBJ_LINKED:
if ((o->linked = get_oref (z, F)) == NULL)
o->linked = (XOBJ *) (-1);
break;
case TOBJ_EXAM:
o->examine = get_exam (F);
break;
case TOBJ_VIS:
o->vis = get_int (F);
break;
case -1:
fprintf (stderr,
"\nError in zone obj:%s: %s is not a legal entry.\n",
z->name, s);
xexit (1);
default:
fprintf (stderr,
"\nError in zone obj:%s: %s isn't implemented yet.\n",
z->name, s);
xexit (1);
}
while ((c = getc (F)) != '\n') {
if (c == EOF)
return False;
}
}
xfgets (b, bs, F);
return True;
}
void
mkdef_loc (XZON * z, XLOC * l)
{
XLOC *p;
if (l->aux != REFERRED) {
fprintf (stderr, "\nRoom %s@%s is defined twice!\n", l->name, z->name);
xexit (1);
}
if ((p = z->rlocs) == l) {
z->rlocs = l->next;
} else {
while (p->next != l)
p = p->next;
p->next = l->next;
}
l->aux = DEFINED;
l->loc = 0;
l->next = NULL;
if ((p = z->locs) == NULL)
z->locs = l;
else {
while (p->next != NULL)
p = p->next;
p->next = l;
}
}
Boolean
read_loc (FILE * F, XZON * z, char *b, int bs)
{
XLOC *l;
char s[128];
char n[128];
int c;
int g;
char *t;
int k;
l = NULL;
for (;;) {
do {
c = getc (F);
}
while (isspace (c));
for (t = s; isalnum (c) || c == '_'; c = getc (F))
*t++ = c;
*t = 0;
if (t == s) {
if (c == EOF) {
return False;
}
if (c == '%') {
ungetc (c, F);
break;
}
continue;
}
#ifdef DEBUG
printf( "\rLocation %s@%s.%-30s", s, z->name, "" );
#endif
l = find_loc (z, s);
mkdef_loc (z, l);
l->altitude = 0;
while (c != ';') {
while (isspace (c))
c = getc (F);
for (t = n; isalpha (c) || isspace(c); c = getc (F)) {
*t++ = c;
}
*t = 0;
if (t == n) {
if (c == ';')
break;
if (t == n && c != ';') {
fprintf (stderr, "\n Expected ';' in room %s@%s.\n",
s, z->name);
xexit (1);
}
}
if (c != ':') {
fprintf (stderr, "\n Expected ':' in room %s@%s.\n",
s, z->name);
xexit (1);
}
if ((k = lookup (n, Exits)) == -1) {
fprintf (stderr, "\n Illegal exit %s in room %s@%s.\n",
n, s, z->name);
xexit (1);
}
if (l->exit_types[k] != 0) {
log ('L', (XOBJ *) l, z,
"Multiple defineds of exit %s.", Exits[k]);
}
for (c = getc (F); isspace (c); c = getc (F)) ;
switch (c) {
case '#':
l->exit_types[k] = '#';
l->exits[k] = (XLOC *) get_int (F);
break;
case '^':
l->exit_types[k] = '^';
l->exits[k] = (XLOC *) get_oref (z, F);
break;
default:
l->exit_types[k] = ' ';
ungetc (c, F);
l->exits[k] = get_lref (z, F);
}
c = getc (F);
}
while (getc (F) != '\n') ;
c = getc (F);
while (isspace (c))
c = getc (F);
for (t = n; isalpha (c); c = getc (F)) {
*t++ = c;
}
*t = 0;
if ((g = t - n) == 0 || strncasecmp (n, "Lflags", g) != 0) {
if(g != 0 && strncasecmp (n, "Altitude", g) == 0) {
while (isspace (c))
c = getc (F);
l->altitude = get_int(F);
while (getc (F) != '\n') ;
c = getc (F);
while (isspace (c))
c = getc (F);
for (t = n; isalpha (c); c = getc (F)) {
*t++ = c;
}
*t = 0;
if((g = t - n) == 0 || strncasecmp (n, "Lflags", g) != 0) {
fprintf (stderr, "\nError in %s@%s, Lflags entry required.\n",
s, z->name);
xexit (1);
}
}
else {
fprintf (stderr, "\nError in %s@%s, Lflags entry required.\n",
s, z->name);
xexit (1);
}
}
ungetc (c, F);
get_flags (z, (XMOB *) l, 'L',
(int *) &(l->lflags), sizeof (LFLAGS) / sizeof (int), Lflags, F);
while (getc (F) != '\n') ;
c = getc (F);
t = n;
while (c != '^') {
*t++ = c;
c = getc (F);
}
*t = 0;
while (getc (F) != '\n') ;
l->pname = save_text (n);
l->description = get_description (F);
}
return True;
}
void read_zones (XZON * zo, int nz, Boolean silent) {
int z;
XZON *zon;
FILE *F;
Boolean multiple;
char buff[128];
if (!silent) printf ("\n");
for (z = 0, zon = zo; z < nz; ++z, ++zon, pclose (F)) {
if (!silent)
printf("\r%d:%s from %s ", z, zon->name, zon->fname);
fflush (stdout);
if ((F = zopen (zon->fname,
zon->name, &multiple, buff, sizeof (buff))) == NULL) {
fprintf (stderr, "\nZone not found: %s in file %s.\n",
zon->name, zon->fname);
xexit (1);
}
if (!strncasecmp(buff, "%rainfall:", 10 )) {
char c;
zon->rainfall = atoi(&buff[10]);
while ((c = getc (F)) != '\n') {
if (c == EOF)
continue;
}
xfgets(buff, sizeof(buff), F);
}
if (!strncasecmp(buff, "%latitude:", 10 )) {
char c;
zon->latitude = atoi( &buff[10] );
while ((c = getc (F)) != '\n') {
if (c == EOF)
continue;
}
xfgets( buff, sizeof(buff), F );
}
if (!strncasecmp(buff, "%mobiles", 8)) {
if (!read_mob (F, zon, buff, sizeof (buff)))
continue;
}
if (!strncasecmp(buff, "%objects", 8)) {
if (!read_obj (F, zon, buff, sizeof (buff)))
continue;
}
if (!strncasecmp(buff, "%locations", 10)) {
read_loc (F, zon, buff, sizeof (buff));
continue;
}
else if (!strncasecmp(buff, "%zone:", 6)) {
if (!multiple) {
fprintf (stderr, "\nError in zone file, %s unexpected.\n", buff);
xexit (1);
}
continue;
}
else {
fprintf (stderr, "\n Error in zone file: unknown sequence %s.",
buff);
xexit (1);
}
}
}
Boolean
obj_ok (XOBJ * O, XOBJ * F, char t)
{
XOBJ *L;
XOBJ *G;
XLOC *R;
if (O == 0 || O == (XOBJ *) (-1) || O->aux == BAD) {
return False;
} else if (O->aux == F && t == IS_LINK) {
return True;
} else if (O->aux == F) {
log ('O', O, O->zone, "Recursive contents in object.");
O->aux = BAD;
return False;
} else if (O->loc == NULL) {
log ('O', O, O->zone, "Location does not exist.");
O->aux = BAD;
return False;
} else if (O->obj != -1) {
log ('O', O, O->zone, "O->obj == %d, should be -1");
O->aux = BAD;
return False;
} else if (O->aux != UNKNOWN) {
return True;
}
O->aux = F;
if (O->cflag == IN_CONTAINER && !obj_ok ((XOBJ *) (O->loc), F, IS_CONTAINED)) {
G = (XOBJ *) (O->loc);
log ('O', O, O->zone, "Container %s@%s[%s] is bad",
G->name, G->zone->name, G->pname);
O->aux = BAD;
return False;
}
if ((L = O->linked) != NULL) {
if (L == (XOBJ *) (-1)) {
log ('O', O, O->zone, "Linked object doesn't exist.");
O->aux = BAD;
return False;
} else if (L == O) {
log ('O', O, O->zone, "Linked object to itself.");
O->aux = BAD;
return False;
} else if (L->linked != O) {
log ('O', O, O->zone, "Linked object %s@%s[%s] isn't linked back.",
L->name, L->zone->name, L->pname);
O->aux = BAD;
return False;
} else if (L->aux == BAD) {
log ('O', O, O->zone, "Linked object %s@%s[%s] is bad.",
L->name, L->zone->name, L->pname);
O->aux = BAD;
return False;
} else if ((G = L->aux) != GOOD) {
if (G == UNKNOWN)
G = L;
if (!obj_ok (L, G, IS_LINK)) {
log ('O', O, O->zone, "Error with linked object %s@%s[%s].",
L->name, L->zone->name, L->pname);
L->aux = BAD;
O->aux = BAD;
return False;
}
}
if (O->state == -1) {
if ((O->state = L->state) == -1) {
O->state = L->state = 0;
}
} else if (L->state == -1) {
L->state = O->state;
} else if (L->state != O->state) {
log ('O', O, O->zone,
"Initial states on linked objects %s@%s[%s] are not the same.",
L->name, L->zone->name, L->pname);
L->aux = BAD;
O->aux = BAD;
return False;
}
} else if (O->state == -1) {
O->state = 0;
}
if ((R = O->loc) != NULL) {
switch (O->cflag) {
case IN_ROOM:
if (((int) (R->loc)) <= 0 || R->aux != GOOD)
R = NULL;
break;
case IN_CONTAINER:
break;
case CARRIED_BY:
case WORN_BY:
case WIELDED_BY:
case BOTH_BY:
if (((XMOB *) R)->mob < 0 || ((XMOB *) R)->aux != GOOD)
R = NULL;
break;
default:
R = NULL;
}
}
if (R == NULL) {
log ('O', O, O->zone, "Invalid location.");
O->aux = BAD;
return False;
}
/*
* if (O->linked == NULL) {
* if (not_linked_l == NULL) {
* not_linked = not_linked_l = O;
* } else {
* not_linked_l->the_next = O;
* not_linked_l = O;
* }
* ++num_unlinked;
* } else if (O < O->linked) {
* if (linked_objs_l == NULL) {
* linked_objs = linked_objs_l = O;
* } else {
* linked_objs_l->the_next = O;
* linked_objs_l = O;
* }
* ++num_linked;
* }
*/
if (obj_list == NULL) {
obj_list_l = obj_list = O;
} else {
obj_list_l->the_next = obj_list_l = O;
}
if (O->linked == NULL)
++num_unlinked;
else if (O < O->linked)
++num_linked;
O->aux = GOOD;
return True;
}
void
clean_up (XZON * zon, int nz, int *mm, int *oo, int *lo, int *ll)
{
XOBJ *O;
XOBJ *F;
XMOB *M;
XLOC *L;
XLOC *E;
XZON *Z;
int x;
int k;
int l;
int m;
int o;
int z;
for (M = mobs, x = 0; x < num_m; M++, x++) {
if (M->aux == BAD)
continue;
if (M->aux != DEFINED) {
M->aux = BAD;
log ('M', (XOBJ *) M, M->zone, "Mobile isn't properly defined..");
} else {
char *p = M->pname;
M->aux = UNKNOWN;
if (M->agg == -1) {
M->agg = 10; /*((k = abs(M->lev)) <= 200 ? 0 : k%100); */
}
if (M->speed == -1) {
M->speed = 5;
}
while (isalpha (*p) || *p == ' ')
p++;
if (*p != '\0')
log ('M', (XOBJ *) M, M->zone,
"Mobile in-game name must consist of letters only.");
}
}
for (L = locns, x = 0; x < num_l; L++, x++) {
if (L->aux != DEFINED) {
log ('L', (XOBJ *) L, L->zone, "Location isn't properly defined..");
L->aux = BAD;
} else {
L->aux = UNKNOWN;
L->loc = -2;
}
}
for (O = objs, x = 0; x < num_o; O++, x++) {
if (O->aux == BAD)
continue;
if (O->aux != DEFINED) {
log ('O', O, O->zone, "Object isn't properly defined..");
O->aux = BAD;
} else {
char *p = O->pname;
O->obj = -2;
O->the_next = NULL;
O->aux = UNKNOWN;
while (isalpha (*p) || *p == ' ')
p++;
if (*p != '\0')
log ('O', O, O->zone,
"Object in-game name must consist of letters only.");
}
}
for (Z = zon, z = 0, o = 0; z < nz; ++z, ++Z) {
Z->n_loc = 0;
for (O = Z->objs; O != NULL; O = O->next) {
if (O->aux == UNKNOWN) {
O->obj = -1;
O->zone = Z;
}
}
for (L = Z->locs; L != NULL; L = L->next) {
if (L->aux == UNKNOWN) {
L->loc = -1;
}
}
}
for (Z = zon, z = 0, l = 0; z < nz; ++z, ++Z) {
Z->loc = l;
for (L = Z->locs; L != NULL; L = L->next) {
if (L->aux == UNKNOWN && L->pname != NULL
&& L->description != NULL) {
L->loc = ++l;
L->aux = GOOD;
Z->n_loc++;
}
}
}
for (Z = zon, z = 0, m = 0; z < nz; ++z, ++Z) {
Z->mob = m;
for (M = Z->mobs; M != NULL; M = M->next) {
if (M->aux == UNKNOWN && M->loc != NULL && M->loc->aux == GOOD) {
M->mob = m++;
M->aux = GOOD;
Z->n_mob++;
}
}
}
for (Z = zon, z = 0, o = 0; z < nz; ++z, ++Z) {
for (O = Z->objs; O != NULL; O = O->next) {
if ((F = O->aux) == BAD || F == GOOD)
continue;
if (F == REFERRED || F == DEFINED) {
log ('O', O, O->zone, "Object isn't properly checked.");
O->aux = BAD;
continue;
}
if (F == UNKNOWN)
F = O;
if (!obj_ok (O, F, IS_CHECK)) {
log ('O', O, O->zone, "General error with object.");
O->aux = BAD;
} else {
O->aux = GOOD;
}
}
}
for (Z = zon, z = 0; z < nz; ++z, ++Z) {
for (L = Z->locs; L != NULL; L = L->next) {
if (L->aux != GOOD)
continue;
for (k = 0; k < NEXITS; k++) {
E = L->exits[k];
switch (L->exit_types[k]) {
case '^':
O = (XOBJ *) E;
if (O->cflag != IN_ROOM
|| O->loc != L
|| O->aux != GOOD
|| (F = O->linked) == NULL
|| F->cflag != IN_ROOM) {
L->exits[k] = NULL;
L->exit_types[k] = 0;
}
break;
case '#':
break;
case ' ':
if (E == NULL || E->aux != GOOD) {
L->exits[k] = NULL;
L->exit_types[k] = 0;
}
break;
case 0:
if (L->exits[k] != NULL) {
log ('L', (XOBJ *) L, L->zone,
"Garbage in exit %s, should be none.", Exits[k]);
L->exits[k] = NULL;
}
break;
default:
log ('L', (XOBJ *) L, L->zone,
"Garbage in exit %s, exit type = %c[%03o]",
Exits[k], L->exit_types[k], L->exit_types[k]);
L->exits[k] = NULL;
L->exit_types[k] = 0;
break;
}
}
}
}
for (O = obj_list, o = *lo = 0; O != NULL; O = O->the_next) {
if (O->aux != GOOD || (O->linked != NULL && O->linked->aux != GOOD)) {
printf ("\nPanic Object %s@%s were supposed to be good!\n",
O->name, O->zone->name);
xexit (1);
}
O->obj = o++;
if (O->linked != NULL)
(*lo)++;
}
*mm = m;
*oo = o;
*ll = l;
}
void
write_zone (XZON * ZON, int numz)
{
FILE *F;
int z;
XZON *Z;
F = Do_fopen (zone_file, "w");
fprintf (F, "%d\n", numz);
for (Z = ZON, z = 0; z < numz; ++z, ++Z) {
fprintf (F, "%s %d %d\n", Z->name, Z->latitude, Z->rainfall);
}
fclose (F);
}
void
write_mob (XZON * ZON, int numz, int m)
{
FILE *F;
FILE *H;
int z;
int i = 0;
XZON *Z;
XMOB *M;
char zn[32];
char n[64];
F = Do_fopen (mob_file, "w");
H = Do_fopen (mobh_file, "w");
fprintf (F, "%d\n", m);
/* Print out header */
(void) fprintf (H, "\
/*\n\
**\tMobiles file header generated from %s\n\
**\tDON'T MAKE CHANGES HERE -- THEY WILL GO AWAY!\n\
*/\n\n\
#ifndef _MOBILES_H\n\
#define _MOBILES_H\n\n",
main_file);
for (Z = ZON, z = 0; z < numz; ++z, ++Z) {
strcpy (zn, Z->name);
uppercase (zn);
fprintf (H, "#define MOBMIN_%s\t%d\n", zn, Z->mob);
fprintf (H, "#define MOBMAX_%s\t%d\n", zn, Z->mob + Z->n_mob);
for (M = Z->mobs; M != NULL; M = M->next, i++) {
if (M->aux != GOOD) {
log ('M', (XOBJ *) M, Z, "Mobile not found good.");
continue;
}
fprintf (F, "%s^\n", M->pname);
fprintf (F, "%d %d %d %d %d %d %d %d %d %d %d\n",
i, i, z, -(M->loc->loc), M->str,
M->damage, M->agg, M->armor, M->speed, M->vis, M->wimpy);
fprintf (F, "0x%08lx:0x%08lx 0x%08lx:0x%08lx:0x%08lx\n",
M->sflags.h, M->sflags.l, M->pflags.u, M->pflags.h,
M->pflags.l);
fprintf (F, "0x%08lx:0x%08lx 0x%08lx:0x%08lx\n",
M->mflags.h, M->mflags.l, M->eflags.l, M->eflags.h);
fprintf (F, "%s^\n", M->desc);
fprintf (F, "%s^\n\n", M->exam == NULL ? "" : M->exam);
strcpy (n, M->name);
uppercase (n);
fprintf (H, "#define MOB_%s_%s\t%d\n", zn, n, M->mob);
}
}
fprintf (H, "\n#endif\n");
fclose (F);
fclose (H);
}
void
write_xobj (FILE * F, FILE * H, FILE * X, XOBJ * O, int obj_num)
{
XLOC *L = NULL;
XOBJ *C = NULL;
XMOB *M = NULL;
XZON *Z = NULL;
int x;
char *s;
int obj_loc = 0;
char n[64];
char z[32];
L = O->loc;
switch (O->cflag) {
case IN_ROOM:
Z = L->zone;
obj_loc = -(L->loc);
break;
case IN_CONTAINER:
C = (XOBJ *) L;
Z = C->zone;
obj_loc = C->obj;
break;
case CARRIED_BY:
case WIELDED_BY:
case WORN_BY:
case BOTH_BY:
M = (XMOB *) L;
Z = M->zone;
obj_loc = M->mob;
break;
default:
printf ("\nPanic carry flag is %d!\n", O->cflag);
xexit (1);
}
fprintf (F, "%s %s %d %d %d %d %d %d %d %d %d %d %ld:%ld %ld %d %d %d %d\n",
O->pname, O->aname ? O->aname : "<null>",
O->zone->zone, obj_num, obj_num,
O->linked ? O->linked->obj : -1,
O->vis, O->cflag, obj_loc,
O->state, O->damage, O->armor,
O->oflags.l, O->oflags.h, O->aflags,
O->mstate, O->bvalue, O->osize, O->oweight);
for (x = 0; x < 4; ++x) {
if ((s = O->desc[x]) == NULL)
s = "";
fprintf (F, "%s^\n", s);
}
if ((s = O->examine) == NULL)
s = "";
fprintf (F, "%s^\n\n", s);
strcpy (n, O->name);
uppercase (n);
strcpy (z, O->zone->name);
uppercase (z);
fprintf (H, "#define OBJ_%s_%s\t%d\n", z, n, O->obj);
}
void
write_obj (XZON * ZON, int numz, int o, int l)
{
FILE *F;
FILE *H;
FILE *X = NULL;
int i;
XOBJ *O;
F = Do_fopen (obj_file, "w");
H = Do_fopen (objh_file, "w");
fprintf (F, "%d\n", o);
/* Print out header */
(void) fprintf (H, "\
/*\n\
**\tObject file header generated from %s\n\
**\tDON'T MAKE CHANGES HERE -- THEY WILL GO AWAY!\n\
*/\n\n\
#ifndef _OBJECTS_H\n\
#define _OBJECTS_H\n\n",
main_file);
for (O = obj_list, i = 0; O != NULL; O = O->the_next, i++)
write_xobj (F, H, X, O, i);
fclose (F);
fprintf (H, "\n#endif\n");
fclose (H);
}
static char *
c_ex (char *s, int x, int *Ex, Boolean * ex, Boolean neg)
{
char c;
if (ex[x]) {
ex[x] = False;
} else if ((Ex[x] == 0) == neg) {
ex[x] = True;
} else {
c = s[-1];
while (*s != 0) {
if (*s == '^' && s[1] == c)
return s + 2;
++s;
}
}
return s;
}
static char *
c_zo (char *s, Boolean neg)
{
XZON *Z;
char zname[64];
char *t, *q;
int z;
if (*s != '(')
return s;
for (t = zname, q = s; *++q != 0 && *q != ')';)
*t++ = *q;
if (*q == 0)
return s;
++q;
if (t == zname)
return q;
*t = 0;
for (z = 0, Z = zones; z < num_z; ++z, ++Z) {
if (strcasecmp (zname, Z->name) == 0)
continue;
neg = !neg;
break;
}
if (neg)
return q;
while (*q != 0 && (*q != '^' || q[1] != 'z'))
++q;
if (*q == 0)
return q;
q += 2;
if (*q == '(' && q[1] == ')')
q += 2;
return q;
}
void
write_loc (XZON * ZON, int numz, int l)
{
FILE *F;
FILE *H;
int z;
int x;
int y = 0;
int i = -1;
Boolean neg;
Boolean ex[NEXITS]; /* True if in condition ^<exit> */
int Ex[NEXITS]; /* The calculated exit number.. */
XZON *Z;
XLOC *L;
XLOC *E;
char *s;
char c;
char zn[32];
char n[64];
F = Do_fopen (loc_file, "w");
H = Do_fopen (loch_file, "w");
fprintf (F, "%d\n", l);
/* Print out header */
(void) fprintf (H, "\
/*\n\
**\tLocations file header generated from %s\n\
**\tDON'T MAKE CHANGES HERE -- THEY WILL GO AWAY!\n\
*/\n\n\
#ifndef _LOCATIONS_H\n\
#define _LOCATIONS_H\n\n",
main_file);
for (Z = ZON, z = 0; z < numz; ++z, ++Z) {
strcpy (zn, Z->name);
uppercase (zn);
fprintf (H, "#define LOCMIN_%s\t%d\n", zn, -(Z->loc));
fprintf (H, "#define LOCMAX_%s\t%d\n", zn, -(Z->loc + Z->n_loc));
for (L = Z->locs; L != NULL; L = L->next, i--) {
if (L->aux != GOOD) {
log ('L', (XOBJ *) L, Z, "Location not found good.");
continue;
}
fprintf (F, "%d %d", /*L->loc, */ i, z);
for (x = 0; x < NEXITS; x++) {
E = L->exits[x];
ex[x] = False;
switch (L->exit_types[x]) {
case '^':
y = DOOR + ((XOBJ *) L->exits[x])->obj;
break;
case '#':
y = (int) (L->exits[x]);
break;
case ' ':
y = -(L->exits[x]->loc);
break;
case 0:
y = 0;
break;
default:
printf ("\nPanic Room %d has illegal exit type %s: %c!\n",
L->loc, Exits[x], L->exit_types[x]);
xexit (1);
}
Ex[x] = y;
fprintf (F, " %d", y);
}
fprintf (F, "\n0x%08lx:0x%08lx\n%d\n%s^\n%s^\n",
L->lflags.h, L->lflags.l, L->altitude, L->name, L->pname);
s = L->description;
while (*s != 0) {
if ((c = *s++) != '^') {
putc (c, F);
continue;
}
neg = False;
if (*s == '!') {
neg = True;
++s;
}
switch (c = *s++) {
case 'n':
s = c_ex (s, 0, Ex, ex, neg);
continue;
case 'e':
s = c_ex (s, 1, Ex, ex, neg);
continue;
case 's':
s = c_ex (s, 2, Ex, ex, neg);
continue;
case 'w':
s = c_ex (s, 3, Ex, ex, neg);
continue;
case 'u':
s = c_ex (s, 4, Ex, ex, neg);
continue;
case 'd':
s = c_ex (s, 5, Ex, ex, neg);
continue;
case 'z':
s = c_zo (s, neg);
continue;
default:
putc (c, F);
continue;
}
}
fprintf (F, "^\n");
strcpy (n, L->name);
uppercase (n);
fprintf (H, "#define LOC_%s_%s\t%d\n", zn, n, -(L->loc));
}
}
fclose (F);
fprintf (H, "\n#endif\n");
fclose (H);
}
void
write_files (XZON * ZON, int numz, int l, int o, int lo, int m)
{
write_zone (ZON, numz);
write_mob (ZON, numz, m);
write_obj (ZON, numz, o, lo);
write_loc (ZON, numz, l);
}
void make_data (char *file, Boolean silent) {
int numz;
int numl;
int numo;
int numm;
int numlo;
numz = read_main(file);
read_zones (zones, numz, silent);
clean_up (zones, numz, &numm, &numo, &numlo, &numl);
write_files (zones, numz, numl, numo, numlo, numm);
if (!silent) {
printf("\nGenerate: text space is %d/%d\n", textsp - texts, sizeof(texts));
printf("Generate: %d zones, %d locs, %d objs (%d linked), %d mobs.\n",
numz, numl, numo, numlo, numm);
if (n_logs > 0) {
printf("Generate errors: %d, logfile %s.\n\n", n_logs, log_file);
fprintf(LogFile, "Total number of logs is %d.\n", n_logs);
}
else
printf("\nNo errors, log file %s is empty.\n\n", log_file);
}
fclose (LogFile);
}
void
log (char t, XOBJ * O, XZON * Z, char *f,...)
{
va_list pvar;
char *n;
char *z;
char *p;
char *q;
char b[1024];
va_start (pvar, f);
vsprintf (b, f, pvar);
z = Z->name;
++n_logs;
switch (t) {
case 'L':
n = ((XLOC *) O)->name;
p = ((XLOC *) O)->pname;
q = "Loc";
break;
case 'M':
n = ((XMOB *) O)->name;
p = ((XMOB *) O)->pname;
q = "Mob";
break;
case 'O':
n = O->name;
p = O->pname;
q = "Obj";
break;
default:
fprintf (stderr, "\nIllegal type %c.\n", t);
exit (1);
}
fprintf (LogFile, "%s: %s@%s[%s] %s\n", q, n, z, p, b);
}