1#!/usr/bin/env python3 2 3import json 4import argparse 5import copy 6 7 8def hash_key(key): 9 if isinstance(key, list): 10 return "list_" + "".join(key) 11 else: 12 return key 13 14 15def parse_furnter(om_objs, palette, conflicts): 16 for map_key, map_val in om_objs.items(): 17 if isinstance(map_val, list) and len(map_val) == 1: 18 map_val = map_val[0] 19 pal_val = palette.get(map_key, "") 20 if not pal_val: 21 palette[map_key] = map_val 22 elif pal_val != map_val: 23 map_hash = hash_key(map_val) 24 pal_hash = hash_key(pal_val) 25 conflicts.setdefault(map_key, {}) 26 conflicts[map_key].setdefault( 27 map_hash, {"val": map_val, "count": 0}) 28 conflicts[map_key].setdefault( 29 pal_hash, {"val": pal_val, "count": 0}) 30 conflicts[map_key][map_hash]["count"] += 1 31 conflicts[map_key][pal_hash]["count"] += 1 32 33 34def decide_conflicts(palette, conflicts): 35 for con_key, conflict in conflicts.items(): 36 most_val = "" 37 most_count = -1 38 for _, data in conflict.items(): 39 if data["count"] > most_count: 40 most_count = data["count"] 41 most_val = data["val"] 42 palette[con_key] = most_val 43 44 45def resolve_conflicts(om_objs, palette, conflicts): 46 temp_objs = copy.deepcopy(om_objs) 47 for map_key in om_objs: 48 map_val = om_objs[map_key] 49 if isinstance(map_val, list) and len(map_val) == 1: 50 map_val = map_val[0] 51 pal_val = palette.get(map_key, "") 52 if pal_val == map_val: 53 del temp_objs[map_key] 54 return temp_objs 55 56 57args = argparse.ArgumentParser( 58 description="Read all the terrain and furniture definitions from a " 59 "mapgen .json file and move them into a palette file. " 60 "Symbols with multiple definitions put the most common " 61 "definition in the the palette and leave the others in " 62 "the mapgen file.") 63args.add_argument("mapgen_source", action="store", 64 help="specify json file to convert to palette.") 65args.add_argument("palette_name", action="store", 66 help="specify the name of the resulting palette.") 67args.add_argument("palette_path", action="store", 68 help="specify the folder for the palette.") 69argsDict = vars(args.parse_args()) 70 71mapgen = [] 72mapgen_source = argsDict.get("mapgen_source", "") 73palette_name = argsDict.get("palette_name", "") 74palette_source = \ 75 argsDict.get("palette_path", "") + "/" + palette_name + ".json" 76if mapgen_source.endswith(".json"): 77 try: 78 with open(mapgen_source) as mapgen_file: 79 mapgen += json.load(mapgen_file) 80 except FileNotFoundError: 81 exit("Failed: could not find {}".format(mapgen_source)) 82else: 83 exit("Failed: invalid mapgen file name {}".format(mapgen_source)) 84 85furn_pal = {} 86furn_conflicts = {} 87ter_pal = {} 88ter_conflicts = {} 89 90# first pass, go through and find all the existing terrains and furnitures and 91# any conflicts 92for om_tile in mapgen: 93 om_object = om_tile.get("object", {}) 94 om_furn = om_object.get("furniture", {}) 95 parse_furnter(om_furn, furn_pal, furn_conflicts) 96 om_ter = om_object.get("terrain", {}) 97 parse_furnter(om_ter, ter_pal, ter_conflicts) 98 99# if there are conflicts, pick the most common version for the palette 100if furn_conflicts: 101 decide_conflicts(furn_pal, furn_conflicts) 102if ter_conflicts: 103 decide_conflicts(ter_pal, ter_conflicts) 104 105# second pass, remove entries in the palette 106for om_tile in mapgen: 107 om_object = om_tile.get("object", {}) 108 om_object.setdefault("palettes", []) 109 om_object["palettes"].append(palette_name) 110 if om_object.get("furniture"): 111 if furn_conflicts: 112 om_furn = om_object.get("furniture", {}) 113 om_furn_final = resolve_conflicts(om_furn, furn_pal, 114 furn_conflicts) 115 if om_furn_final: 116 om_object["furniture"] = om_furn_final 117 else: 118 del om_object["furniture"] 119 else: 120 del om_object["furniture"] 121 122 if om_object.get("terrain"): 123 if ter_conflicts: 124 om_ter = om_object.get("terrain", {}) 125 om_ter_final = resolve_conflicts(om_ter, ter_pal, ter_conflicts) 126 if om_ter_final: 127 om_object["terrain"] = om_ter_final 128 else: 129 del om_object["terrain"] 130 else: 131 del om_object["terrain"] 132 133with open(mapgen_source, 'w') as mapgen_file: 134 mapgen_file.write(json.dumps(mapgen, indent=2)) 135 136palette_json = [ 137 { 138 "type": "palette", 139 "id": palette_name, 140 "furniture": furn_pal, 141 "terrain": ter_pal 142 } 143] 144 145with open(palette_source, 'w') as palette_file: 146 palette_file.write(json.dumps(palette_json, indent=2)) 147 148#print("furniture palette {}".format(json.dumps(furn_pal, indent=2))) 149#print("terrain palette {}".format(json.dumps(ter_pal, indent=2))) 150