-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmapDependencies.py
268 lines (244 loc) · 10.6 KB
/
mapDependencies.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#!/usr/bin/env python3
"""
Python 3.6.x
This program takes any number of map XML files
and prints out their dependencies in a new *.txt file.
Keep in mind that each dependency may have multiple parts,
e.g. a mob needs its mob file as well as string and sound,
and UI in the case of bosses with fullscreen HP bars.
The main dependencies file emitted by this script contains
all the info for each map in one place, while all the other
files emitted consolidate the resources needed for all the
maps inputted all together, sorted, with no duplicates.
Requires:
xmltodict (to install: ``pip install xmltodict``)
"""
import tkinter as tk
from tkinter import filedialog
import xmltodict
def isIntegral(s):
try:
int(s)
return True
except ValueError:
return False
root = tk.Tk()
root.withdraw()
filepaths = filedialog.askopenfilenames(filetypes=[("XML files", ".xml")],
title="Select the dumped " +
"<mapid>.img.xml files you'd " +
"like to check for dependencies:")
thisdir = ""
backset = set()
mobset = set()
npcset = set()
tilesetset = {}
objsetset = {}
bgmset = set()
mapmarkset = set()
for filepath in filepaths:
fp = open(filepath, "r", encoding="utf8")
img = xmltodict.parse(fp.read())
fp.close()
bgm = "N/A"
mapmark = "N/A"
back = []
mobs = []
npcs = []
tilesets = {}
objsets = {}
try:
for imgdir in img["imgdir"]["imgdir"]:
try:
if imgdir["@name"] == "info":
for infostring in imgdir["string"]:
if infostring["@name"] == "bgm":
bgm = infostring["@value"]
elif infostring["@name"] == "mapMark":
mapmark = infostring["@value"]
elif imgdir["@name"] == "back":
for backimgdir in imgdir["imgdir"]:
if backimgdir["string"]["@value"] not in back:
back.append(backimgdir["string"]["@value"])
elif imgdir["@name"] == "life":
try:
temp = imgdir["imgdir"][0]["string"]
for lifeimgdir in imgdir["imgdir"]:
lifetype = ""
lifeid = ""
for lifestring in lifeimgdir["string"]:
if lifestring["@name"] == "type":
lifetype = lifestring["@value"]
elif lifestring["@name"] == "id":
lifeid = lifestring["@value"]
if lifetype == "m":
if lifeid not in mobs:
mobs.append(lifeid)
elif lifetype == "n":
if lifeid not in npcs:
npcs.append(lifeid)
else:
raise ValueError(
"life type is neither \"m\" nor \"n\"")
except:
if "imgdir" in imgdir:
lifeimgdir = imgdir["imgdir"]
else:
continue
lifetype = ""
lifeid = ""
for lifestring in lifeimgdir["string"]:
if lifestring["@name"] == "type":
lifetype = lifestring["@value"]
elif lifestring["@name"] == "id":
lifeid = lifestring["@value"]
if lifetype == "m":
if lifeid not in mobs:
mobs.append(lifeid)
elif lifetype == "n":
if lifeid not in npcs:
npcs.append(lifeid)
else:
raise ValueError(
"life type is neither \"m\" nor \"n\"")
elif isIntegral(imgdir["@name"]):
currenttileset = ""
for intimgdir in imgdir["imgdir"]:
if intimgdir["@name"] == "info" and len(intimgdir) > 1:
try:
currenttileset = intimgdir["string"]["@value"]
except:
raise TypeError(
"More than one string value under" +
" info section of numbered node")
break
for intimgdir in imgdir["imgdir"]:
intimgdirlen = len(intimgdir)
if intimgdir["@name"] == "tile" and len(intimgdir) > 1:
for tileimgdir in intimgdir["imgdir"]:
if currenttileset in tilesets.keys():
t = tilesets[currenttileset]
if tileimgdir["string"]["@value"] not in t:
tilesets[currenttileset].append(
tileimgdir["string"]["@value"])
else:
newtileset = []
newtileset.append(
tileimgdir["string"]["@value"])
tilesets[currenttileset] = newtileset
elif intimgdir["@name"] == "obj" and intimgdirlen > 1:
for objimgdir in intimgdir["imgdir"]:
currentobjset = ""
l0 = ""
l1 = ""
l2 = ""
try:
for objstring in objimgdir["string"]:
if objstring["@name"] == "oS":
currentobjset = objstring["@value"]
elif objstring["@name"] == "l0":
l0 = objstring["@value"]
elif objstring["@name"] == "l1":
l1 = objstring["@value"]
elif objstring["@name"] == "l2":
l2 = objstring["@value"]
except TypeError:
print(objimgdir)
obj = l0 + "/" + l1 + "/" + l2
if currentobjset in objsets.keys():
objsets[currentobjset].append(obj)
else:
newobjset = []
newobjset.append(obj)
objsets[currentobjset] = newobjset
except TypeError:
continue
except Exception as e:
raise RuntimeError("Exception reading file " +
filepath + ": " + str(e))
back.sort()
mobs.sort()
npcs.sort()
for tileset in tilesets.keys():
tilesets[tileset].sort()
for objset in objsets.keys():
objsets[objset].sort()
backset.update(back)
mobset.update(mobs)
npcset.update(npcs)
for tileset in tilesets.keys():
if tileset in tilesetset:
tilesetset[tileset].update(tilesets[tileset])
else:
tilesetset[tileset] = set(tilesets[tileset])
for objset in objsets.keys():
if objset in objsetset:
objsetset[objset].update(objsets[objset])
else:
objsetset[objset] = set(objsets[objset])
bgmset.add(bgm)
mapmarkset.add(mapmark)
output = filepath.split("/")[-1]
output = output.split(".")[0] + ":\n"
output += " Background music: " + bgm + "\n\n"
output += " Map mark/icon: " + mapmark + "\n\n"
output += " Backgrounds:\n"
for bg in back:
output += " " + bg + "\n"
output += "\n Mobs:\n"
for mob in mobs:
output += " " + mob + "\n"
output += "\n NPCs:\n"
for npc in npcs:
output += " " + npc + "\n"
output += "\n Tile sets:\n"
for tileset in tilesets.keys():
output += " " + tileset + "\n"
for tile in tilesets[tileset]:
output += " " + tile + "\n"
output += "\n Object sets:\n"
for objset in objsets.keys():
output += " " + objset + "\n"
for obj in objsets[objset]:
output += " " + obj + "\n"
output += "\n\n"
filenamelen = len(filepath.split("/")[-1])
thisdir = filepath[:-1 * filenamelen]
with open(thisdir + "/dependencies.txt", "a", encoding="utf8") as o:
o.write(output)
with open(thisdir + "/backgrounds.txt", "w", encoding="utf8") as b:
for bg in sorted(backset):
b.write(bg)
b.write("\n")
with open(thisdir + "/mobs.txt", "w", encoding="utf8") as m:
for mob in sorted(mobset):
m.write(mob)
m.write("\n")
with open(thisdir + "/npcs.txt", "w", encoding="utf8") as n:
for npc in sorted(npcset):
n.write(npc)
n.write("\n")
with open(thisdir + "/tiles.txt", "w", encoding="utf8") as t:
for tileset in sorted(tilesetset.keys()):
t.write(tileset)
t.write("\n")
for tile in sorted(tilesetset[tileset]):
t.write(" ")
t.write(tile)
t.write("\n")
with open(thisdir + "/objects.txt", "w", encoding="utf8") as o:
for objset in sorted(objsetset.keys()):
o.write(objset)
o.write("\n")
for obj in sorted(objsetset[objset]):
o.write(" ")
o.write(obj)
o.write("\n")
with open(thisdir + "/bgm.txt", "w", encoding="utf8") as b:
for bgm in sorted(bgmset):
b.write(bgm)
b.write("\n")
with open(thisdir + "/mapmarks.txt", "w", encoding="utf8") as m:
for mapmark in sorted(mapmarkset):
m.write(mapmark)
m.write("\n")