/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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; }