|
# Script to split maps into component areas for PlanetStation |
|
|
|
from collections import defaultdict |
|
import dmm |
|
|
|
AREA_BLACKLIST = [ |
|
'/area/space', |
|
'/area/hallway', |
|
'/area/maintenance', |
|
'/area/holodeck', |
|
'/area/template_noop', |
|
'/area/shuttle', |
|
'/area/solar', |
|
'/area/ruin', |
|
] |
|
DEFAULT_TILE = ( |
|
'/turf/template_noop', |
|
'/area/template_noop', |
|
) |
|
|
|
def subtype(full, part): |
|
return full == part or full.startswith(part + '/') |
|
|
|
def generate(title, fname): |
|
source = dmm.DMM.from_file(fname) |
|
|
|
all_areas = defaultdict(set) |
|
for (x, y, z), key in source.grid.items(): |
|
tile = source.dictionary[key] |
|
area = tile[-1] |
|
try: |
|
area = area[:area.index('{')] |
|
except ValueError: |
|
pass |
|
assert subtype(area, '/area') |
|
|
|
if any(subtype(area, bad) for bad in AREA_BLACKLIST): |
|
continue |
|
|
|
all_areas[area, z].add((x, y)) |
|
|
|
print("Saving", title, "with", len(all_areas), "areas") |
|
for (area, z), coords in all_areas.items(): |
|
min_x = min(coord[0] for coord in coords) |
|
max_x = max(coord[0] for coord in coords) |
|
min_y = min(coord[1] for coord in coords) |
|
max_y = max(coord[1] for coord in coords) |
|
|
|
width = max_x - min_x + 1 |
|
height = max_y - min_y + 1 |
|
output = dmm.DMM(1, (width, height, 1)) |
|
output.dictionary[0] = DEFAULT_TILE |
|
for x in range(min_x, max_x + 1): |
|
for y in range(min_y, max_y + 1): |
|
if (x, y) in coords: |
|
tile = source.dictionary[source.grid[x, y, z]] |
|
else: |
|
tile = DEFAULT_TILE |
|
try: |
|
key = output.dictionary.inv[tile] |
|
except KeyError: |
|
key = output.dictionary.inv[tile] = output.generate_new_key() |
|
output.grid[x - min_x + 1, y - min_y + 1, 1] = key |
|
|
|
output.to_file(f"data/planetstation/{title}-{area[len('/area/'):].replace('/', '_')}-{z}.dmm") |
|
|
|
if __name__ == '__main__': |
|
import sys |
|
for each in sys.argv[1:]: |
|
generate(each[each.rfind('/') + 1:-4], each) |