changeset 78:5dfbf6b30846

Improved location handling
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 16 Dec 2006 08:30:35 +0000
parents f950e58e743c
children b821a8840c6b
files mkloc.c
diffstat 1 files changed, 129 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/mkloc.c	Sat Dec 16 08:30:20 2006 +0000
+++ b/mkloc.c	Sat Dec 16 08:30:35 2006 +0000
@@ -19,16 +19,18 @@
 	DIR_DOWN
 };
 
-enum {
-	LOCF_NONE = 0,
-	LOCF_MARK,
-};
+#define	LOCF_NONE	(0)
+#define LOCF_MARK1	(1)
+#define LOCF_MARK2	(2)
+#define LOCF_MARKINV	(3)
+#define LOCF_MARKMASK	(3)
+#define LOCF_INVALID	(128)
 
 
 typedef struct {
 	int x, y, ox, oy;
 	int dir, flags;
-	char * desc;
+	char *desc;
 } locinfo_t;
 
 
@@ -51,7 +53,8 @@
 	*destFile = NULL,
 	*locFile = NULL;
 
-int	optOffsetX = 0, optOffsetY = 0;
+int	optOffsetX = 0,
+	optOffsetY = 0;
 BOOL	optGetLoc = FALSE;
 
 
@@ -202,6 +205,67 @@
 }
 
 
+BOOL checkFlag(int flags, int mask, int flag)
+{
+	if (mask)
+		return (flags & mask) == flag;
+	else
+		return (flags & flag);
+}
+
+BOOL parseFlags(fileinfo_t *f, int *flags)
+{
+	BOOL endFlags;
+	
+	*flags = LOCF_NONE;
+	endFlags = FALSE;
+	while (!endFlags) {
+		switch (f->inLine[f->linePos]) {
+		case '+':
+			if (!checkFlag(*flags, LOCF_MARKMASK, 0) &&
+			!checkFlag(*flags, LOCF_MARKMASK, LOCF_MARK1)) {
+				THERR("Invalid flags setting on line #%d in '%s'\n",
+					f->lineNum, f->fileName);
+				return FALSE;
+			}
+			*flags |= LOCF_MARK1;
+			break;
+
+		case '%':
+			if (!checkFlag(*flags, LOCF_MARKMASK, 0) &&
+			!checkFlag(*flags, LOCF_MARKMASK, LOCF_MARK2)) {
+				THERR("Invalid flags setting on line #%d in '%s'\n",
+					f->lineNum, f->fileName);
+				return FALSE;
+			}
+			*flags |= LOCF_MARK2;
+			break;
+
+		case '-':
+			if (!checkFlag(*flags, LOCF_MARKMASK, 0) &&
+			!checkFlag(*flags, LOCF_MARKMASK, LOCF_MARKINV)) {
+				THERR("Invalid flags setting on line #%d in '%s'\n",
+					f->lineNum, f->fileName);
+				return FALSE;
+			}
+			*flags |= LOCF_MARKINV;
+			break;
+
+		case ' ':
+		case 0:
+		case 9:
+			endFlags = TRUE;
+			break;
+
+		default:
+			return FALSE;
+		}
+		f->linePos++;
+	}
+	
+	return TRUE;
+}
+
 BOOL parseLocationFile(char *fileName, locations_t *l, int offX, int offY)
 {
 	FILE *inFile;
@@ -261,16 +325,12 @@
 				return FALSE;
 			
 			/* Get flags */
-			tf = LOCF_NONE;
-			switch (inLine[f.linePos++]) {
-			case '+': tf = LOCF_MARK; break;
-			case ' ': case 9: break;
-			default:
-				THERR("Expected flag or whitespace after direction on line #%d in '%s'\n",
+			if (!parseFlags(&f, &tf)) {
+				THERR("Expected flag(s) or whitespace after direction on line #%d in '%s'\n",
 					f.lineNum, f.fileName);
 				return FALSE;
 			}
-			
+
 			th_findnext(inLine, &f.linePos);
 			
 			/* Get name */
@@ -321,14 +381,19 @@
 			if ((n = searchLocation(l, x, y, TRUE)) >= 0) {
 				locinfo_t *tloc = l->locations[n];
 				
-				switch (tloc->flags) {
-				case LOCF_MARK:
+				switch (tloc->flags & LOCF_MARKMASK) {
+				case LOCF_MARK1:
 					fputc('?', outFile);
 					break;
+				case LOCF_MARK2:
+					fputc('%', outFile);
+					break;
 				
-				case LOCF_NONE:
 				default:
-					fputc(d[(map->w * y) + x], outFile);
+					if (tloc->flags & LOCF_INVALID)
+						fputc('$', outFile);
+					else
+						fputc(d[(map->w * y) + x], outFile);
 					break;
 				}
 			} else
@@ -353,25 +418,33 @@
 {
 	int i;
 	
+	/* Output header */
 	fprintf(outFile,
 	"# Format of this file is one location per line:\n"
 	"# X\tY\textra\tLocation name\n"
 	);
-		
+	
+	/* Output each location entry */
 	for (i = 0; i < l->numLocations; i++) {
 		locinfo_t *tmp = l->locations[i];
 		
+		/* Add comment if location is deemed "invalid" */
+		if (tmp->flags & LOCF_INVALID)
+		fprintf(outFile, "\n# Possibly invalid location #%d: %s\n",
+			i, tmp->desc);
+		
 		fprintf(outFile, "%d\t%d\t%d",
 			tmp->ox, tmp->oy, tmp->dir);
-			
-		switch (tmp->flags) {
-		case LOCF_MARK:
-			fprintf(outFile, "+");
+		
+		switch (tmp->flags & LOCF_MARKMASK) {
+		case LOCF_MARK1:
+			fputc('+', outFile);
 			break;
-
-		case LOCF_NONE:
-		default:
-			/* Do nothing */
+		case LOCF_MARK2:
+			fputc('%', outFile);
+			break;
+		case LOCF_MARKINV:
+			fputc('-', outFile);
 			break;
 		}
 		
@@ -379,6 +452,7 @@
 	}
 }
 
+
 void adjustLocInfoCoords(mapblock_t *map, locations_t *l)
 {
 	int i;
@@ -442,7 +516,7 @@
 	}
 	
 	/* Read initial map */
-	THMSG(1, "Reading map '%s'\n", srcFile);
+	THMSG(2, "Reading map '%s'\n", srcFile);
 	worldMap = parseFile(srcFile);
 	if (!worldMap) {
 		THERR("World map could not be loaded!\n");
@@ -453,7 +527,7 @@
 
 	/* Read location info */
 	if (locFile) {
-		THMSG(1, "Reading location info '%s'\n", locFile);
+		THMSG(2, "Reading location info '%s'\n", locFile);
 		if (!parseLocationFile(locFile, &worldLocations, optOffsetX, optOffsetY)) {
 			THERR("Error reading location file!\n");
 			exit(1);
@@ -462,7 +536,7 @@
 	
 	/* What mode are we in? */
 	if (optGetLoc) {
-		int x, y, cloc = 0;
+		int x, y, n, numNewLoc = 0, numInvLoc = 0;
 		char *d = worldMap->d;
 		
 		THMSG(2, "Updating location information ..\n");
@@ -471,18 +545,40 @@
 		for (y = 0; y < worldMap->h; y++)
 		for (x = 0; x < worldMap->w; x++) {
 			if (*d == '?' || *d == '%') {
+				/* Check for new locations */
 				if (searchLocation(&worldLocations, x, y, TRUE) < 0) {
 					char tmps[512];
-					snprintf(tmps, sizeof(tmps), "UNK #%d", cloc);
-						
+					int tmpf;
+					
+					snprintf(tmps, sizeof(tmps),
+						"UNK #%d", numNewLoc);
+					numNewLoc++;
+					
+					if (*d == '%')
+						tmpf = LOCF_MARK2;
+					else
+						tmpf = LOCF_NONE;
+					
 					addLocation(&worldLocations,
-						x, y, DIR_NONE, tmps, LOCF_NONE);
+						x, y, DIR_NONE, tmps, tmpf);
+				}
+			} else {
+				/* Check for misplaced locations */
+				if ((n = searchLocation(&worldLocations, x, y, TRUE)) >= 0) {
+					locinfo_t *tloc = worldLocations.locations[n];
 					
-					cloc++;
+					if ((tloc->flags & LOCF_MARKMASK) == 0) {
+						/* Mark as possibly invalid */
+						tloc->flags |= LOCF_INVALID;
+						numInvLoc++;
+					}
 				}
 			}
 			d++;
 		}
+		
+		THMSG(1, "%d new locations, %d invalid locations.\n",
+			numNewLoc, numInvLoc);
 	}
 	
 	/* Open output file */