/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* ABERED (AberMUD Dirt3 editor) *
* *
* This file is concerned with loading and writing the locations from/to *
* dirt zone files. At a later stage aber4 files may be included, and *
* since there are several, I will use BUDAPEST file formats. *
* *
* Copyright (C) 1993 James Willie. All rights reseved. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <ctype.h>
#include "types.h"
#include "macros.h"
#include "extern.h"
#include "prototyp.h"
static char dir[NEXITS] = { 'n', 'e', 's', 'w', 'u', 'd' };
extern int line;
/*
** Find, load a complete location from file f, creating the location
** and returning a pointer to it
*/
PLOC get_dirt_loc(f)
FILE *f;
{
int c, i, exit_type = X_NORMAL, dir = -1, k;
char buf[128];
char *p;
PLOC l = NULL;
Bool word = FALSE, direc = FALSE, finished = FALSE;
if (f == NULL)
return NULL;
/* malloc and initialise */
l = NEW(LOC);
if (l == NULL)
{
printf("Can't create location, Out of memory error.\n");
exit(1);
}
for(i = 0; i < NEXITS; i++)
{
l->exit_type[i] = X_NONE;
l->exits[i] = NULL;
}
for(i = 0; i < NUM_LFLAGS; i++)
l->lflags[i] = FALSE;
/* Although this is not strictly required, enables broken files to be read */
c = getc(f);
while (isspace(c))
{
if (c == '\n')
line++;
c = getc(f);
}
ungetc(c,f);
if (c == '%')
return NULL;
/* Get location name */
if (get_word(buf,f) < 0)
return NULL;
l->name = COPY(buf);
/* Get exits */
i = 0;
dir = -1;
finished = FALSE;
while (!finished && ((c = getc(f)) != EOF))
{
if (c == '\n')
line++;
if (c == ';')
{
c = ' ';
finished = TRUE;
}
if(word)
{
if (isspace(c))
{
word = FALSE;
if ((direc) || (dir < 0) || (dir > NEXITS))
{
printf("Error on line %d: Location %s, don't understand direction\n",
line, l->name);
}
else
{
buf[i] = '\0';
l->ename[dir] = COPY(buf);
l->exit_type[dir] = exit_type;
}
dir = -1;
direc = FALSE;
i = 0;
}
else if (direc)
{
if (c == ':')
{
exit_type = X_NORMAL;
direc = FALSE;
}
}
else
{
if (c == '^')
exit_type = X_OBJECT;
else
buf[i++] = (char)c;
}
}
else
{
if (!isspace(c))
{
direc = TRUE;
dir = dir2num((char)c);
word = TRUE;
}
}
} /* While loop */
if (c == EOF)
{
printf("Error on line %d: Found an unexpected End of File.\n", line);
exit(1);
}
NEWLINE(f);
line++;
/* lflags */
i = 0;
while(isalpha(c = getc(f)))
{
buf[i++] = (char)c;
}
if (c == EOF)
{
printf("Error on line %d: Location %s, Lflags expected, found EOF.\n",
line, l->name);
return NULL;
}
if (strncasecmp(buf,"LFLAGS",i-1) != 0)
{
printf("Error on line %d: Did not find Lflags entry for %s.\n",
line, l->name);
return NULL;
}
while(c != '{')
{
if (c == EOF)
{
printf("Error on line %d: Location %s, Lflags expected, found EOF.\n",
line, l->name);
return NULL;
}
if (c == '\n')
line++;
c = getc(f);
}
for (c = getc(f); c != '}'; c = getc(f))
{
if (c == '\n')
line++;
if (!isalpha(c))
continue;
for (p = buf; isalpha(c); c = getc(f))
*p++ = (char)c;
ungetc(c,f);
*p = 0;
k = lookup(l_flags,buf);
if ((k >= 0) && (k < NUM_LFLAGS))
l->lflags[k] = TRUE;
else
printf("Error line %d: Unknown Lflag [%s] in location %s.\n",
line, buf, l->name);
}
NEWLINE(f);
if ((l->pname = get_text(f,'^')) == NULL)
{
printf("Error line %d: Location ignored.\n",line);
return NULL;
}
NEWLINE(f);
line += text_lines + 2;
if ((l->desc = get_text(f,'^')) == NULL)
{
printf("Error line %d: Location ignored.\n",line);
return NULL;
}
NEWLINE(f);
line += text_lines + 1;
return l;
}
/*
** Return the index into dir[] or -1
*/
int dir2num(s)
char s;
{
int i = 0;
for (i = 0; i < NEXITS; i++)
if (dir[i] == s)
return i;
return -1;
}
/*
** Write out the location in dirt format
** Try to avoid use Xprintf() as it takes up room
*/
void write_dirt_loc(l,f)
PLOC l;
FILE *f;
{
int i;
if (f == NULL)
f = stdout;
fprintf(f,"%s", l->name);
for(i = 0; i < NEXITS; i++)
{
if (l->exit_type[i] != X_NONE)
{
fprintf(f, " %c:", dir[i]);
if (l->exits[i] == NULL)
{
if (l->exit_type[i] == X_OBJECT)
{
fprintf(stderr,"\nObject not properly defined:%s [Exit in room %s]",
l->ename[i], l->name);
fputc('^',f);
}
else
fprintf(stderr,"\nLocation not properly defined:%s [Exit in room %s]",
l->ename[i], l->name);
fprintf(f, "%s", l->ename[i]);
}
else
{
if (l->exit_type[i] == X_OBJECT)
fputc('^',f);
fprintf(f, "%s", ((PLOC)l->exits[i])->name);
}
}
}
fprintf(f, " ;\nLflags {");
for(i = 0; i < NUM_LFLAGS; i++)
{
if (l->lflags[i] == TRUE)
{
fprintf(f, " %s", l_flags[i]);
}
}
fprintf(f, " }\n%s^\n", l->pname);
write_string(l->desc,f);
fprintf(f, "^\n\n");
return;
}
/*
** load_dirt_locs() Continues to read from f, until it finds no locations,
** either due to EOF(normal) or screwed up input file
*/
PLOC load_dirt_locs(f)
FILE *f;
{
PLOC l1, l2;
#ifdef DEBUG
int x = line;
#endif
if (f == NULL)
return NULL;
l1 = get_dirt_loc(f);
l2 = l1;
while(l2 != NULL)
{
numloc++;
#ifdef DEBUG
printf("Location %s: Lines %d to %d\n", l2->name, x, line);
x = line+1;
#endif
l2->next = get_dirt_loc(f);
l2 = l2->next;
}
return l1;
}