diff options
| -rw-r--r-- | src/common.h | 1 | ||||
| -rw-r--r-- | src/main.c | 9 | ||||
| -rw-r--r-- | src/mapcat.c | 79 | 
3 files changed, 88 insertions, 1 deletions
diff --git a/src/common.h b/src/common.h index b005e2b..8acf3ba 100644 --- a/src/common.h +++ b/src/common.h @@ -132,5 +132,6 @@ void map_init(map_t *map);  void map_free(map_t *map);  int map_read(map_t *map, const char *path);  int map_write(const map_t *map, const char *path); +int map_postprocess(map_t *map, bool filter_team_ents);  int map_merge(map_t *master, map_t *slave);  void map_print_stats(const char *path, const map_t *map); @@ -108,7 +108,7 @@ int main(int argc, char **argv)  	map_init(&map); -	elist_for (input, inputs, list) { +	elist_for(input, inputs, list) {  		map_t part;  		map_init(&part); @@ -121,6 +121,13 @@ int main(int argc, char **argv)  		if (!quiet)  			map_print_stats(input->path, &part); +		// team_* and info_* ents are kept only in the first part +		if (map_postprocess(&part, (input != inputs))) { +			map_free(&map); +			map_free(&part); +			goto out; +		} +  		if (map_merge(&map, &part)) {  			error("error: couldn't merge %s into %s\n",  			      input->path, output); diff --git a/src/mapcat.c b/src/mapcat.c index b33a694..7968586 100644 --- a/src/mapcat.c +++ b/src/mapcat.c @@ -617,6 +617,83 @@ out:  	return rv;  } +int map_postprocess(map_t *map, bool filter_team_ents) +{ +	entity_t *entity; +	entity_key_t *key; +	char *prefix = NULL; + +	if (filter_team_ents) { +		entity_t *next; + +		for (entity = map->entities; entity; entity = next) { +			next = elist_next(entity, list); + +			if (strncmp(entity->classname, "team_", 5) && +			    strncmp(entity->classname, "info_", 5)) +				continue; + +			map->num_discarded_entities++; +			elist_unlink(&map->entities, entity, list); +			free_entity(entity); +		} +	} + +	if (map->worldspawn) { +		entity_key_t *next; + +		for (key = map->worldspawn->keys; key; key = next) { +			next = elist_next(key, list); + +			if (!strcmp(key->key, "mapcat_prefix")) { +				// shouldn't happen, but just in case +				// (to prevent memory leaks) +				if (prefix) +					free(prefix); + +				prefix = key->value; +				elist_unlink(&map->worldspawn->keys, key, list); +				free(key->key); +				// key->value is freed later (as prefix) +				free(key); +			} +		} +	} + +	if (prefix) { +		size_t prefix_len = strlen(prefix); + +		elist_for(entity, map->entities, list) +		elist_for(key, entity->keys, list) { +			char *new; +			size_t value_len; + +			if (strcmp(key->key, "target") && +			    strcmp(key->key, "targetname")) +				continue; + +			value_len = strlen(key->value); + +			new = malloc(value_len + prefix_len + 1); +			if (!new) { +				fprintf(stderr, "error: out of memory\n"); +				return 1; +			} + +			memcpy(new, prefix, prefix_len); +			memcpy(new + prefix_len, key->value, value_len); +			new[prefix_len + value_len] = 0; + +			free(key->value); +			key->value = new; +		} + +		free(prefix); +	} + +	return 0; +} +  //RETURN VALUE  //	always 0 (this function cannot fail (yet))  // slave is left in invalid state after this function returns, do not use it @@ -643,6 +720,8 @@ int map_merge(map_t *master, map_t *slave)  	master->num_discarded_entities += slave->num_discarded_entities;  	master->num_brushes += slave->num_brushes;  	master->num_discarded_brushes += slave->num_discarded_brushes; +	master->num_patches += slave->num_patches; +	master->num_discarded_patches += slave->num_discarded_patches;  	return 0;  }  | 
