/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ABERED (AberMUD Dirt3 editor) * * * * Handle the input and output of mobile data. Input is driven by io.c * * while output to stdout can come from mob.c, and to a file from io.c * * * * 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" #ifdef ANSI_C static void flg_read(int n, PMOB m, FILE *f); #else static void flg_read(n,m,f); #endif extern int line; char *Mob_tab[] = { "Name", "Pname", "Location", "Description", "End", "Strength", "Damage", "Aggression", "Armor", "Speed", "Pflags", "Sflags", "Mflags", "Examine", TABLE_END }; /* ** The guts of the input routine for mobiles. Reads things a line at a time ** deciding what each line is, and the reading the rest, putting it back ** as appropriate. It returns NULL to a driving program if a control % is ** found, or an error is found. */ PMOB read_dirt_mob(f) FILE *f; { PMOB m; char s[128], n[128]; int c, d, k, i, x; char *t; m = NULL; for (;;) { /* Skip blanks */ for(c = getc(f); isspace(c); c = getc(f)) { if (c == '\n') line++; } 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); return NULL; break; } i = -1; while (c == ' ' || c == '\t' || c == '=') c = getc(f); ungetc(c,f); k = lookup(Mob_tab, s); #ifdef DEBUG printf("%s[%4d]\n",s,k); #endif if (k != MOB_NAME && m == NULL) { printf("Error on line %d: Entry %s is out of sequence.\n", line, s); exit(1); } switch (k) { case MOB_NAME: d = 0; c = getc(f); for (t = n; isalnum(c) || c == '_'; c = getc(f)) *t++ = c; *t = 0; ungetc(c,f); if ((m = NEW(MOB)) == NULL) { printf("Can't create mobile, Out of memory error\n"); exit(1); } init_mob(m,n); break; case MOB_PNAME: if (c == '"') { c = getc(f); m->pname = get_text(f, '"'); line += text_lines; } else { get_word(n,f); free(m->pname); m->pname = COPY(n); } break; case MOB_LOC: for (t = n, c = getc(f); isalnum(c) || c == '_'; c = getc(f)) *t++ = c; *t = 0; ungetc(c, f); m->locname = COPY(n); m->loc = flbname(n); break; case MOB_DESC: /* Hopefully skip any leading new line chars etc. */ for(c = getc(f); (isspace(c) || (c == '"')); c = getc(f)) { if (c == '\n') line++; } ungetc(c,f); m->desc = get_text(f, '"'); line += text_lines; break; case MOB_END: d = 0; c = getc(f); for (t = n; isalnum(c) || c == '_'; c = getc(f)) *t++ = c; *t = 0; ungetc(c,f); if (!EQ(m->name,n)) { printf("Error on line %d: Wrong name on end for mob %s\n", line, m->name); } return m; break; case MOB_STR: m->hp = get_int(f, &x); gint_error(x, Mob_tab[x], m->name); break; case MOB_ARMOR: m->armor = get_int(f, &x); gint_error(x, Mob_tab[x], m->name); break; case MOB_DAM: m->damage = get_int(f, &x); gint_error(x, Mob_tab[x], m->name); break; case MOB_AGG: m->agg = get_int(f, &x); gint_error(x, Mob_tab[x], m->name); break; case MOB_SPEED: m->speed = get_int(f, &x); gint_error(x, Mob_tab[x], m->name); break; case MOB_EXAM: /* Get the next char, a " and then read till we find 1 \n, or a char */ getc(f); while(((c = getc(f)) != EOF) && isspace(c) && (c != '\n')) ; if (c == '\n') line++; else ungetc(c,f); m->exam = get_text(f, '"'); line += text_lines; break; case MOB_SFLAGS: flg_read(1,m,f); break; case MOB_PFLAGS: flg_read(3,m,f); break; case MOB_MFLAGS: flg_read(2,m,f); break; default: fprintf(stderr,"\nError on line %d: Unknown entry [%s]\n", line, s); exit(1); } while ((c = getc(f)) != '\n') { if (c == EOF) return FALSE; } line++; } return NULL; } /* ** Writes a single mobile in dirt format to file f */ void write_dirt_mob(m,f) PMOB m; FILE *f; { int i; Bool p = FALSE, s = FALSE, b = FALSE; if ((m == NULL) || (m == me)) { printf("That mobile has no statistics\n"); return; } fprintf(f,"Name = %s\n", m->name); fprintf(f,"Pname = \"%s\"\n", m->pname); fprintf(f,"Location = %s\n", (m->loc == NULL) ? m->locname : m->loc->name); fprintf(f,"Strength = %d\n", m->hp); fprintf(f,"Damage = %d\n", m->damage); fprintf(f,"Armor = %d\n", m->armor); fprintf(f,"Speed = %d\n", m->speed); fprintf(f,"Aggression = %d\n", m->agg); /* Decide if we need to write any of slfags, pflags or mflags */ for (i = 0; (i < NUM_PFLAGS) || (i < NUM_MFLAGS) || (i < NUM_SFLAGS); i++) { if ((i < NUM_PFLAGS) && (m->pflags[i] == TRUE)) p = TRUE; if ((i < NUM_MFLAGS) && (m->mflags[i] == TRUE)) b = TRUE; if ((i < NUM_SFLAGS) && (m->sflags[i] == TRUE)) s = TRUE; } if (p == TRUE) { fprintf(f,"Pflags {"); for (i = 0; i < NUM_PFLAGS; i++) if ((m->pflags[i] == TRUE) && (!EMPTY(p_flags[i]))) fprintf(f," %s", p_flags[i]); fprintf(f," }\n"); } if (b == TRUE) { fprintf(f,"Mflags {"); for (i = 0; i < NUM_MFLAGS; i++) if ((m->mflags[i] == TRUE) && (!EMPTY(m_flags[i]))) fprintf(f," %s", m_flags[i]); fprintf(f," }\n"); } if (s == TRUE) { fprintf(f,"Sflags {"); for (i = 0; i < NUM_SFLAGS; i++) if ((m->sflags[i] == TRUE) && (!EMPTY(s_flags[i]))) fprintf(f," %s", s_flags[i]); fprintf(f," }\n"); } if (!EMPTY(m->desc)) { fprintf(f, "Description = \""); if (strlen(m->desc) > 60) fprintf(f, "\n"); write_string(m->desc,f); fprintf(f, "\"\n"); } if (!EMPTY(m->exam)) { fprintf(f, "Examine = \"\n"); write_string(m->exam,f); fprintf(f, "\"\n"); } fprintf(f,"End = %s\n\n", m->name); return; } /* ** Drives read_dirt_mob() to read all the mobiles in certain section of a file */ PMOB read_dirt_mobiles(f) FILE *f; { PMOB m1 = NULL, m2 = NULL; #ifdef DEBUG int x = line; #endif m1 = read_dirt_mob(f); m2 = m1; while(m2 != NULL) { nummob++; #ifdef DEBUG printf("Mobile %s: Lines %d to %d\n", m2->name, x, line); x = line+1; #endif m2->next = read_dirt_mob(f); m2 = m2->next; } return m1; } /* ** Called by read_dirt_mob, to read a set of flags and set appropriate ** mflags, sflags or pflags. */ static void flg_read(n,m,f) int n; PMOB m; FILE *f; { int j, c, Num; char r[128]; char *t; char **tab; Bool *flg; switch(n) { case 1: tab = s_flags; Num = NUM_SFLAGS; flg = m->sflags; break; case 2: tab = m_flags; Num = NUM_MFLAGS; flg = m->mflags; break; case 3: tab = p_flags; Num = NUM_PFLAGS; flg = m->pflags; break; default: printf("Error, unknown flags\n"); return; } for (c = getc(f); c != '}'; c = getc(f)) { if (c == '\n') line++; if (!isalpha(c)) continue; for (t = r; isalpha(c); c = getc(f)) *t++ = (char)c; ungetc(c, f); *t = 0; j = lookup(tab,r); if ((j >= 0) && (j < Num)) { flg[j] = TRUE; } else printf("Error on line %d: Unknown flag on mobile %s:%s\n", line, m->name, r); } return; } void init_mob(m,n) PMOB m; char *n; { int j; m->name = COPY(n); m->pname = COPY(n); m->level = -1; m->locname = NULL; m->loc = NULL; m->hp = 0; m->armor = 0; m->damage = 10; m->agg = 0; m->speed = 5; for(j = 0; j < NUM_SFLAGS; j++) m->sflags[j] = FALSE; for(j = 0; j < NUM_MFLAGS; j++) m->mflags[j] = FALSE; for(j = 0; j < NUM_PFLAGS; j++) m->pflags[j] = FALSE; m->desc = NULL; m->exam = NULL; m->next = NULL; return; }