diff options
author | Paweł Redman <pawel.redman@gmail.com> | 2016-12-20 12:41:28 +0100 |
---|---|---|
committer | Paweł Redman <pawel.redman@gmail.com> | 2016-12-20 12:41:28 +0100 |
commit | e36571c70ca3abb639ef64bf6f5c924ca19e4ffa (patch) | |
tree | 3d28e63c8710477c3314f2bb9ba44bf3942b463a /src | |
parent | 30330c305545e1b93acd2ec7b72df7673bde9181 (diff) |
Implement map postprocessing fully.
Postprocessing removes info_* and team_* entities from all maps but the master (the first one in the command line) and (optionally) prefixes all targets and targetnames with a prefix (set by mapcat_prefix in the master worldspawn).
Diffstat (limited to 'src')
-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; } |