-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpatch_gen.py
executable file
·111 lines (95 loc) · 3.41 KB
/
patch_gen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python3
"""
patch_gen.py
Given two teeworlds maps
create a twmap script that describes
the difference between the two
so it can be applied like a patch
"""
import sys
import os
import numpy
import re
import twmap
def diff_layers(layer1, layer2):
if layer1.width() != layer2.width():
print('Error: Layers of different width are not supported')
sys.exit(1)
if layer1.height() != layer2.height():
print('Error: Layers of different height are not supported')
sys.exit(1)
a = layer1.tiles
b = layer2.tiles
axes = numpy.where(a != b)[:2]
axes = numpy.transpose(axes)
axes = numpy.unique(axes, axis=0)
axes_ = (axes[:,0], axes[:,1])
coordinates = axes
values = b[axes_]
return coordinates, values
def gen_py_layer_diff(coordinates, values, layer, name):
"""
Given a array of tile diffs
this generates python patches
"""
patches = []
layer_slug = re.sub(r'[^a-zA-Z_]', '', name)
patches.append(f"{layer_slug} = in_map.{layer}.tiles")
for y, x, tile, flags in numpy.concatenate((coordinates, values), axis=1):
patches.append(f"{layer_slug}[{y}][{x}] = [{tile}, {flags}]")
# print(diff
patches.append(f"in_map.{layer}.tiles = {layer_slug}")
return patches
def gen_py_patch(base_map_file, diff_map_file):
"""
Given two map file paths
this generats a python patch script
that can be applied to the first map
to get the second map
"""
base_map = twmap.Map(base_map_file)
diff_map = twmap.Map(diff_map_file)
mapname = os.path.splitext(os.path.basename(base_map_file))[0]
mapname = re.sub(r'[^a-zA-Z_]', '', mapname)
diffname = os.path.splitext(os.path.basename(diff_map_file))[0]
diffname = re.sub(r'[^a-zA-Z_]', '', diffname)
if diffname.startswith(f"{mapname}_"):
diffname = diffname[(len(mapname) + 1):]
elif diffname.startswith(mapname):
diffname = diffname[len(mapname):]
patches = []
patches.append('#!/usr/bin/env python3')
patches.append('import twmap')
patches.append(f"in_map = twmap.Map('{mapname}.map')")
group_index = -1
for group in base_map.groups:
group_index += 1
layer_index = -1
for layer in group.layers:
layer_index += 1
print(f"name={layer.name} g={group_index} l={layer_index}")
if layer.kind() not in ['Tiles', 'Game']:
# TODO: support quads etc
print(f"Warning: skipping {layer.kind()}")
continue
print(f"diffing layer")
coordinates, values = diff_layers(
base_map.groups[group_index].layers[layer_index],
diff_map.groups[group_index].layers[layer_index])
print("generating patches")
patches += gen_py_layer_diff(
coordinates,
values,
f"groups[{group_index}].layers[{layer_index}]",
f"{group.name}_{layer.name}")
patches.append(f"in_map.save('{mapname}.map')")
patchfile = f"{mapname}_{diffname}_patch.py"
with open(patchfile, 'w') as patch:
patch.write("\n".join(patches) + "\n")
os.chmod(patchfile, 0o744)
if len(sys.argv) != 3:
print("usage: patch_gen.py BASE_MAP DIFF_MAP")
sys.exit(0)
base_map_file = sys.argv[1]
diff_map_file = sys.argv[2]
gen_py_patch(base_map_file, diff_map_file)