8 def __init__(self, name, kind):
13 self.upgrades = {"attrs":None, "mods":None}
15 def is_compatible(self, other):
16 return self.kind==other.kind
18 def compare_mods(self, other):
20 for n, v in self.mods.items():
21 ov = other.mods.get(n, 0)
27 for on, ov in other.mods.items():
28 v = self.mods.get(on, 0)
36 def compare_attrs(self, other):
39 def check_upgrade(self, other):
40 if self.droplevel<=other.droplevel:
42 if not self.is_compatible(other):
45 mods = self.compare_mods(other)
46 attrs = self.compare_attrs(other)
48 if not other.upgrades["mods"]:
49 if mods>0 or (mods==0 and attrs>0):
50 other.upgrades["mods"] = self
51 if not other.upgrades["attrs"]:
52 if attrs>0 or (attrs==0 and mods>0):
53 other.upgrades["attrs"] = self
56 def __init__(self, name, kind):
57 super(Armor, self).__init__(name, kind)
61 self.energy_shield = 0
63 def is_compatible(self, other):
64 if (self.armor!=0)!=(other.armor!=0):
66 if (self.evasion!=0)!=(other.evasion!=0):
68 if (self.energy_shield!=0)!=(other.energy_shield!=0):
71 return super(Armor, self).is_compatible(other)
73 def compare_attrs(self, other):
74 if self.armor<other.armor:
76 if self.evasion<other.evasion:
78 if self.energy_shield<other.energy_shield:
81 if self.armor>other.armor:
83 if self.evasion>other.evasion:
85 if self.energy_shield>other.energy_shield:
91 def __init__(self, name, kind):
92 super(Weapon, self).__init__(name, kind)
97 def compare_attrs(self, other):
98 if self.dps<other.dps:
100 if self.dps>other.dps:
105 class ItemDataParser(html.parser.HTMLParser):
107 super(ItemDataParser, self).__init__()
109 self.in_items_table = False
113 self.current_item = None
114 self.in_heading = False
116 self.current_heading = None
121 def handle_starttag(self, tag, attrs):
124 if n=="class" and v=="itemDataTable":
125 self.in_items_table = True
129 if n=="class" and v.endswith("_mod"):
133 self.current_item = None
139 self.in_heading = True
141 def handle_endtag(self, tag):
143 self.in_items_table = False
147 if self.current_item and self.mod_row:
148 for it in self.items:
149 self.current_item.check_upgrade(it)
151 self.in_heading = False
153 def handle_data(self, data):
159 self.current_heading = data
160 self.headings.append(self.current_heading)
161 elif self.in_items_table and self.in_cell:
164 self.mod_names.append(data)
168 value = int(data.split(" to ", 1)[1])
171 name = self.mod_names[self.mod_index]
172 if name!="From Armour Movement Speed +%":
173 self.current_item.mods[name] = value
177 self.current_item = self.create_item(data, self.current_heading)
178 self.items.append(self.current_item)
180 self.current_item.droplevel = int(data)
182 self.handle_value(self.column, data)
184 def create_item(self, name, kind):
187 def handle_value(self, column, data):
190 class ArmorDataParser(ItemDataParser):
191 def create_item(self, name, kind):
192 return Armor(name, kind)
194 def handle_value(self, column, data):
196 self.current_item.armor = int(data)
198 self.current_item.evasion = int(data)
200 self.current_item.energy_shield = int(data)
202 class WeaponDataParser(ItemDataParser):
203 def create_item(self, name, kind):
204 return Weapon(name, kind)
206 def handle_value(self, column, data):
208 self.current_item.speed = float(data)
210 self.current_item.dps = float(data)
212 def get_upgrade_level(item, steps):
214 for p in item.upgrades.keys():
216 for i in range(steps):
217 upgrade = upgrade.upgrades.get(p)
220 level = max(level, upgrade.droplevel)
223 def write_best_category(out, prefix, items, steps):
224 best = ["best", "second"]
226 out.write('category "{}.{}_at_level"\n'.format(prefix, best[steps-1]))
227 out.write("{\n\tor\n\t{\n")
229 upgrade_level = get_upgrade_level(it, steps)
230 out.write("\t\tand\n\t\t{\n")
232 out.write('\t\t\tbase_type "{}";\n'.format(it.name))
233 out.write("\t\t\titem_level {} {};\n".format(it.droplevel, upgrade_level-1))
235 out.write('\t\t\tbase_type "{}";\n'.format(it.name))
236 out.write("\t\t\tmin_item_level {};\n".format(it.droplevel))
237 out.write("\t\t};\n")
238 out.write("\t};\n};\n")
241 r = requests.get("https://www.pathofexile.com/item-data/armour")
242 p = ArmorDataParser()
243 p.feed(codecs.decode(r.content, r.encoding))
245 types = {"robe": lambda i: (not i.armor and not i.evasion and i.energy_shield),
246 "cloth": lambda i: (not i.armor and i.evasion and i.energy_shield),
247 "leather": lambda i: (not i.armor and i.evasion and not i.energy_shield),
248 "scale": lambda i: (i.armor and i.evasion and not i.energy_shield),
249 "plate": lambda i: (i.armor and not i.evasion and not i.energy_shield),
250 "chain": lambda i: (i.armor and not i.evasion and i.energy_shield)}
252 out = open("armor.txt", "w")
254 for t, f in types.items():
255 items = [i for i in p.items if f(i)]
257 for i in range(1, 3):
258 write_best_category(out, "armor.{}".format(t), items, i)
260 out.write('category "armor.{}"\n'.format(t))
261 out.write("{\n\tor\n\t{\n")
263 out.write('\t\tbase_type "{}";\n'.format(it.name))
264 out.write("\t};\n};\n")
266 out.write('category "armor"\n{\n\tor\n\t{\n')
268 out.write('\t\tclass "{}";\n'.format(h))
269 out.write("\t};\n};\n")
271 r = requests.get("https://www.pathofexile.com/item-data/weapon")
272 p = WeaponDataParser()
273 p.feed(codecs.decode(r.content, r.encoding))
275 out = open("weapons.txt", "w")
278 items = [i for i in p.items if i.kind==h]
280 for i in range(1, 3):
281 write_best_category(out, "weapon.{}".format(h.lower().replace(' ', '_')), items, i)
283 out.write('category "weapon"\n{\n\tor\n\t{\n')
285 out.write('\t\tclass "{}";\n'.format(h))
286 out.write("\t};\n};\n")
288 if __name__=="__main__":