/* DUMBASS CONVERTER, converts zone files */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include "kernel.h" #include "gen.h" #include "exitnames.h" #define ZONSEGMENT 0 #define DATSEGMENT 1 #define MOBSEGMENT 2 #define OBJSEGMENT 3 #define LOCSEGMENT 4 typedef struct _funccalls { char funcname[120]; char created_in[120]; struct _funccalls *next; } FuncCall; int this_segment = ZONSEGMENT; int linenr=1; int write_zone_start=0; int write_zone_end = 0; zone_record this_zone; FuncCall *function_list = NULL; /* Tokens that chance shape in the new format */ char *conversionTable[] = { "desc[0]", "Desc0", "desc[1]", "Desc1", "desc[2]", "Desc2", "desc[3]", "Desc3", "Startcode", "Trap", "EndCode", "EndTrap", "Pname", "Name", "Description", "Desc\t", "BValue", "BaseValue", "Extern", "UseTrap", "Oflags", "OFlags", "Pflags", "PFlags", "SFlags", "SFlags", "Mflags", "MFlags", "Lflags", "LFlags", "Altname", "AltName", "Strength", "Strength", "Damage", "Damage", "Aggression", "Aggression", "Speed", "Speed", "Armor", "Armor", "Weight", "Weight", "Linked", "Linked", "Location", "Location", "Wimpy", "Wimpy", "Visibility", "Visibility", TABLE_END, TABLE_END }; /* Segments in the old format */ char *segmentIds[] = { "%zone", "%globaldata", "%mobiles", "%objects", "%locations", TABLE_END }; char *StartTokens[] = { "Zone", "", "Mobile", "Object", "Location", }; char *EndTokens[] = { "EndZone", "", "EndMobile", "EndObject", "EndLocation" }; char *flags[] = { "OFlags", "Sflags", "Pflags", "MFlags", "Lflags", TABLE_END }; char *exitIds[] = { "n", "North\t", "s", "South\t", "e", "East\t", "w", "West\t", "u", "Up\t", "d", "Down\t", "ne", "NorthEast", "se", "SouthEast", "nw", "NorthWest", "sw", "SouthWest", TABLE_END, TABLE_END }; int lookup(char *token,char **table) { int i=0; if (strlen(token) < 3) return 0; for (i=0; table[i] != TABLE_END; i++) { if (strncasecmp(token,table[i],strlen(token)) == 0) return 1; } return 0; } void addFunctionCall(char *object, char *function) { FuncCall *p; p = (FuncCall *)malloc(sizeof(FuncCall)); strcpy(p->created_in,object); strcpy(p->funcname,function); p->next = function_list; function_list = p; } char *findObjectByFunction(char *func) { FuncCall *p = function_list; while (p != NULL && strcmp(p->funcname,func) != 0) p = p->next; if (p == NULL) { if (strchr(func,'@') != NULL) printf("Warning: reference to an external function not defined in this zone: %s\n",func); return "undefined\n"; } return p->created_in; } void clearFuncList() { FuncCall *p = function_list; while (p != NULL) { function_list = p->next; free(p); p = function_list; } } /* convert a flag definition to the new style * oldstyle: Flags { <flags> } * newstyle: Flags = <flag> [, <flags>] */ char *make_flag_line(char *line, char *buffer,char *head) { char token[120]; char *s = token; char *p = line; int first=1; int comment=0; int aftercomment = 0; int flagc = 0; while (*p != '{' && *p != '\0') p++; if (*p == '\0') { printf("Opening bracket not found in line %d\n",linenr); return ""; } p++; while (isspace(*p) && *p !='\0' && *p != '}') p++; strcpy(buffer,head); while (*p != '\0' && *p != '}') { while (!isspace(*p) && *p != '}') { *s = *p; p++; s++; } *s = '\0'; if (strstr(token,"/*") != NULL) comment = 1; if (!comment) flagc++; if (strstr(token,"*/") != NULL) { comment = 0; aftercomment = 1; } if (first) { strcat(buffer,token); first = 0; } else { if (aftercomment) { strcat(buffer," "); aftercomment = 0; } else strcat(buffer,", "); strcat(buffer,token); } while (isspace(*p) && *p != '}' && *p != '\0') p++; s= token; } if (flagc != 0) strcat(buffer,"\n"); else strcpy(buffer,""); return buffer; } char *find_translation(char *token) { int i; static char s[120]; if (strlen(token) <= 2) return token; for (i=0; segmentIds[i] != TABLE_END; i+= 1) { if (strncasecmp(segmentIds[i],token,strlen(token)) == 0) { if (this_segment == ZONSEGMENT && i == DATSEGMENT) { sprintf(s,"Data\n@"); write_zone_start = 1; } else if (this_segment == DATSEGMENT && i != DATSEGMENT) { sprintf(s,"@\nEndData"); write_zone_end = 1; } else if (this_segment == ZONSEGMENT && i != ZONSEGMENT) { write_zone_start = write_zone_end = 1; strcpy(s,""); } else strcpy(s,""); this_segment = i; return s; } } if (strcasecmp(token,"Name") == 0) { if (this_segment != ZONSEGMENT) return StartTokens[this_segment]; else return "###@"; } else if (strcasecmp(token,"End") == 0) { return EndTokens[this_segment]; } for (i = 0; conversionTable[i] != TABLE_END; i+=2) { if (strncasecmp(conversionTable[i],token,strlen(token)) == 0) return conversionTable[i+1]; } return token; } char *convert_line(char *line,char *buffer) { char linebuf[1100]; char buildbuf[1000]; char first_token[255]; char this_name[100]; char *p = first_token; int i=0; while(!isspace(line[i]) && line[i] != '=' && line[i] != '{') { *p = line[i++]; p++; } *p = '\0'; if (lookup(first_token,flags)) { sprintf(buildbuf,"%s\t\t= ",find_translation(first_token)); (void)make_flag_line(line,linebuf,buildbuf); } else { if (strcasecmp(first_token,"name") == 0) { char *t = index(line,'='); t++; while (isspace(*t)) t++; strcpy(this_name,t); } p = find_translation(first_token); if (strcasecmp(p,"Trap") == 0) { char *t = index(line,'='); t++; while (isspace(*t)) t++; addFunctionCall(this_name,t); sprintf(linebuf,"%s\t\t= all\n@\n",p); } else if (strcasecmp(p,"EndTrap") == 0) sprintf(linebuf,"@\n%s\n",p); else if (strcasecmp(p,"UseTrap") == 0) { char *t = index(line,'='); t++; while (isspace(*t)) t++; sprintf(linebuf,"%s\t\t= all:%s",p,findObjectByFunction(t)); } else if (strcasecmp(p,"Location") == 0) { char *ats = NULL; char *s; char locname[128]; char cflags[20]; if (this_segment == OBJSEGMENT) { p = rindex(line,':'); s = index(line,'='); ats = index(line,'@'); if (p == NULL || s == NULL) { printf("An object in this zone has an invalid format.\n" "Check out this line: %d\n>%s",linenr,line); return NULL; } else { s++; while(isspace(*s)) s++; *p = '\0'; sprintf(cflags,"%s:",s); s = cflags; p++; } } else { s = ""; p = index(line,'='); p++; while (isspace(*p)) p++; ats = index(p,'@'); } while (p[strlen(p) -1] == ' ' || p[strlen(p) -1] == '\t' || p[strlen(p) -1] == '\n') p[strlen(p) -1] = '\0'; if (isdigit(*p) || lookup(p,Exits)) { char *ext = rindex(p,'@'); if (ext == NULL) sprintf(locname,"%s_%s",this_zone.zonename,p); else sprintf(locname,"%s_%s",ext+1,p); } else { sprintf(locname,"%s",p); if (ats == NULL) { strcat(locname,"@"); strcat(locname,this_zone.zonename); } } sprintf(linebuf,"Location\t= %s%s\n",s,locname); } /* else if (strcasecmp(p,"ZoneName") == 0) return ""; */ else if (this_segment == ZONSEGMENT && strcasecmp(p,"Quest") == 0) { p = index(line,'='); if (p == NULL) return ""; p++; while(isspace(*p)) p++; strcpy(this_zone.quest,p); return ""; } else if (this_segment == ZONSEGMENT && strcasecmp(p,"Author") == 0) { p = index(line,'='); if (p == NULL) return ""; p++; while(isspace(*p)) p++; strcpy(this_zone.author,p); return ""; } else if (strcasecmp(p,"Altname") == 0) { p = index(line,'='); if (p == NULL) return ""; p++; while(isspace(*p)) p++; if (*p != '"') { p[strlen(p)-1] = '\0'; sprintf(linebuf,"Altname\t= \"%s\"\n",p); } else sprintf(linebuf,"Altname\t= %s\n",p); } else if (this_segment == ZONSEGMENT && strcasecmp(p,"Name") == 0) { p = index(line,'='); if (p == NULL) return ""; p++; while(isspace(*p)) p++; strcpy(this_zone.zonename,p); return ""; } else if (strcasecmp(p,"Name") == 0) { p = index(line,'='); if (p == NULL) return ""; p++; while(isspace(*p)) p++; if (*p != '"') { p[strlen(p)-1] = '\0'; sprintf(linebuf,"Name\t= \"%s\"\n",p); } else sprintf(linebuf,"Name\t= %s",p); } else if (write_zone_start) { if (index(this_zone.author,'\n') != NULL) this_zone.author[strlen(this_zone.author)-1] = '\0'; sprintf(buildbuf,"Zone\t\t= %s\n" "Author\t\t= %s%s%s\n", this_zone.zonename, index(this_zone.author,'"') == NULL ? "\"" : "", this_zone.author, index(this_zone.author,'"') == NULL ? "\"" : ""); if (this_zone.quest[0] != '\0') { strcat(buildbuf,"Quest\t\t= "); strcat(buildbuf,this_zone.quest); } sprintf(linebuf,"%s%s%s",buildbuf,p,line+i); write_zone_start = 0; } else if (strcmp(p,"###@") != 0) sprintf(linebuf,"%s%s",p,line+i); if (write_zone_end) { sprintf(buildbuf,"EndZone\t\t= %s\n\n",this_zone.zonename); strcat(linebuf,buildbuf); write_zone_end = 0; } } strcpy(buffer,linebuf); return buffer; } void convert_locs(FILE *inf,FILE *outf,char *lineb) { char line[1024]; char buffer[1025]; char symbol[120]; char locname[120]; char *s,*p; int i,raw = 0; if (index(lineb,';') == NULL) fgets(line,1023,inf); else strcpy(line,lineb); while (!feof(inf)) { while (index(line,';') == NULL && !feof(inf)) { fputs(line,outf); fgets(line,1023,inf); } p = line; s = symbol; if (feof(inf)) return; while (!isspace(*p) && *p != ';') { *s = *p; p++; s++; } *s = '\0'; while (isspace(*p) && *p != ';') p++; if (!isdigit(symbol[0]) && !lookup(symbol,Exits)) strcpy(locname,symbol); else sprintf(locname,"%s_%s",this_zone.zonename,symbol); fprintf(outf,"Location\t= \"%s\"\n",locname); while (*p != ';') { while (isspace(*p)) p++; if (*p == ';') break; s = symbol; while (*p != ':') { *s = *p; p++; s++; } *s = '\0'; for (i=0; exitIds[i] != TABLE_END;i+=2) { if (strcasecmp(exitIds[i],symbol) == 0) break; } if (exitIds[i] == TABLE_END) { printf("Unable to convert an exit for a location.\n" "Check out line: %d\n>%s\n",linenr,line); while (*p != ';' && !isspace(*p)) p++; continue; } p++; s = symbol; while (!isspace(*p) && *p != ';') { *s = *p; p++; s++; } *s = '\0'; if (isdigit(symbol[0]) || lookup(symbol,Exits)) { s = index(symbol,'@'); if (s != NULL) fprintf(outf,"%s\t= %s_%s\n",exitIds[i+1],s+1,symbol); else fprintf(outf,"%s\t= %s_%s\n",exitIds[i+1],this_zone.zonename,symbol); } else if (index(symbol,'@') == NULL && symbol[0] != '#') fprintf(outf,"%s\t= %s@%s\n",exitIds[i+1],symbol,this_zone.zonename); else fprintf(outf,"%s\t= %s\n",exitIds[i+1],symbol); } if (inf == NULL || feof(inf)) { printf("Unexpected end of file after reading the exits.\n" "line: %s\n",line); exit(1); } fgets(line,1023,inf); while (index(line,'^') == NULL) { s = symbol; p = line; while (!isspace(*p) && *p != '=' && *p != '{') { *s = *p; s++; p++; } *s = '\0'; if (strncasecmp(symbol,"Lflags",strlen(symbol)) == 0 && !raw) { make_flag_line(line,buffer,"LFlags\t\t= "); fprintf(outf,"%s",buffer); } else if (strcasecmp(symbol,"StartCode") == 0) { char *t = index(line,'='); t++; while(isspace(*t)) t++; fprintf(outf,"Trap\t\t= all\n@\n"); addFunctionCall(locname,t); raw = 1; } else if (strcasecmp(symbol,"EndCode") == 0) { fprintf(outf,"@\nEndTrap\n"); raw = 0; } else if (strcasecmp(symbol,"Extern") == 0) { char *t = index(line,'='); t++; while(isspace(*t)) t++; fprintf(outf,"UseTrap\t= all:%s\n",findObjectByFunction(t)); } else { fputs(line,outf); } fgets(line,1023,inf); } s = index(line,'^'); *s = '"'; fprintf(outf,"Title\t\t= \"%s",line); fprintf(outf,"Desc\t\t= ^\n"); fgets(line,1023,inf); while (line[0] != '^' && !feof(inf)) { fputs(line,outf); fgets(line,1023,inf); } fprintf(outf,"^\nEndLocation\t= \"%s\"\n\n", locname); fgets(line,1023,inf); } } int convert_file(char *infn, char *outfn) { FILE *inf, *outf; char line[1024]; char buffer[1100]; char *s; if ((inf = fopen(infn,"r")) == NULL) { printf("Can't find file %s\n",infn); return 1; } if ((outf = fopen(outfn,"w")) == NULL) { fclose(inf); printf("Can't open target file %s\n",outfn); return 1; } fgets(line,1023,inf); while (!feof(inf)) { if (this_segment == LOCSEGMENT) { convert_locs(inf,outf,line); } else if (strstr(line,"cflags.h") == NULL) { s = convert_line(line,buffer); if (s != NULL) fputs(s,outf); fgets(line,1023,inf); linenr++; } else { fgets(line,1023,inf); linenr++; } } fclose(inf); fclose(outf); return 0; } int main(int argc, char **argv) { char infilename[128]; char outfilename[128]; char *p,*s; int i; if (argc < 2) { printf("Usage: %s [<zone>] [+<zonelistfile>]\n",argv[0]); return 0; } for (i = 1; i < argc; i++) { this_segment = ZONSEGMENT; linenr = 1; if (argv[i][0] == '+') { FILE *listfile; char *v = argv[i]; char file[120]; if ((listfile = fopen(++v,"r")) != NULL) { fgets(file,119,listfile); while (!feof(listfile)) { this_segment = ZONSEGMENT; linenr = 1; if ((p = strstr(file,".zone")) != NULL) *p = '\0'; s = rindex(file,'/'); if (s == NULL) s = file; else s++; strcpy(this_zone.zonefile,file); this_zone.zonename = (char *)malloc(40); this_zone.author = (char *)malloc(40); this_zone.quest = (char *)malloc(40); strcpy(this_zone.zonename,s); strcpy(this_zone.author,"Unknown\n"); this_zone.quest[0] = '\0'; sprintf(infilename,"%s.zone",file); sprintf(outfilename,"%s.area",s); printf("Converting %s (from: %s to: %s)\n",this_zone.zonename,infilename,outfilename); if (convert_file(infilename,outfilename) != 0) return 1; clearFuncList(); fgets(file,119,listfile); } fclose(listfile); } } else { if ((p = strstr(argv[i],".zone")) != NULL) *p = '\0'; s = rindex(argv[i],'/'); if (s == NULL) s = argv[i]; else s++; strcpy(this_zone.zonefile,argv[i]); this_zone.zonename = (char *)malloc(40); this_zone.author = (char *)malloc(40); this_zone.quest = (char *)malloc(40); strcpy(this_zone.zonename,s); strcpy(this_zone.author,"Unknown\n"); this_zone.quest[0] = '\0'; sprintf(infilename,"%s.zone",argv[i]); sprintf(outfilename,"%s.area",s); printf("Converting %s\n",this_zone.zonename); if (convert_file(infilename,outfilename) != 0) return 1; clearFuncList(); } } printf("Ready.\n"); return 0; }