From 2b871ff878516456579f287626c7efb35508cab9 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 16 Aug 2018 16:50:23 +0300 Subject: [PATCH] Consider mods when detecting item upgrades in the scraper --- scrape-item-data.py | 147 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 118 insertions(+), 29 deletions(-) diff --git a/scrape-item-data.py b/scrape-item-data.py index 3040063..3174a27 100755 --- a/scrape-item-data.py +++ b/scrape-item-data.py @@ -9,10 +9,48 @@ class Item: self.name = name self.kind = kind self.droplevel = 0 - self.upgrade = None - - def is_upgrade_for(self, other): - return self.kind==other.kind and self.droplevel>other.droplevel + self.mods = {} + self.upgrades = {"attrs":None, "mods":None} + + def is_compatible(self, other): + return self.kind==other.kind + + def compare_mods(self, other): + result = 0 + for n, v in self.mods.items(): + ov = other.mods.get(n, 0) + if vov: + result = 1 + + for on, ov in other.mods.items(): + v = self.mods.get(on, 0) + if vov: + result = 1 + + return result + + def compare_attrs(self, other): + return 0 + + def check_upgrade(self, other): + if self.droplevel<=other.droplevel: + return + if not self.is_compatible(other): + return + + mods = self.compare_mods(other) + attrs = self.compare_attrs(other) + + if not other.upgrades["mods"]: + if mods>0 or (mods==0 and attrs>0): + other.upgrades["mods"] = self + if not other.upgrades["attrs"]: + if attrs>0 or (attrs==0 and mods>0): + other.upgrades["attrs"] = self class Armor(Item): def __init__(self, name, kind): @@ -22,7 +60,7 @@ class Armor(Item): self.evasion = 0 self.energy_shield = 0 - def is_upgrade_for(self, other): + def is_compatible(self, other): if (self.armor!=0)!=(other.armor!=0): return False if (self.evasion!=0)!=(other.evasion!=0): @@ -30,7 +68,24 @@ class Armor(Item): if (self.energy_shield!=0)!=(other.energy_shield!=0): return False - return super(Armor, self).is_upgrade_for(other) + return super(Armor, self).is_compatible(other) + + def compare_attrs(self, other): + if self.armorother.armor: + return 1 + if self.evasion>other.evasion: + return 1 + if self.energy_shield>other.energy_shield: + return 1 + + return 0 class Weapon(Item): def __init__(self, name, kind): @@ -39,6 +94,14 @@ class Weapon(Item): self.speed = 0 self.dps = 0 + def compare_attrs(self, other): + if self.dpsother.dps: + return 1 + + return 0 + class ItemDataParser(html.parser.HTMLParser): def __init__(self): super(ItemDataParser, self).__init__() @@ -46,12 +109,14 @@ class ItemDataParser(html.parser.HTMLParser): self.in_items_table = False self.column = 0 self.in_cell = False - self.ignore_row = False self.items = {} self.current_item = None self.in_heading = False self.headings = [] self.current_heading = None + self.mod_row = False + self.mod_names = [] + self.mod_index = 0 def handle_starttag(self, tag, attrs): if tag=="table": @@ -59,12 +124,14 @@ class ItemDataParser(html.parser.HTMLParser): if n=="class" and v=="itemDataTable": self.in_items_table = True elif tag=="tr": - self.ignore_row = False + self.mod_row = False for n, v in attrs: if n=="class" and v.endswith("_mod"): - self.ignore_row = True + self.mod_row = True self.column = 0 - self.current_item = None + if not self.mod_row: + self.current_item = None + self.mod_names = [] elif tag=="td": self.column += 1 self.in_cell = True @@ -77,27 +144,42 @@ class ItemDataParser(html.parser.HTMLParser): elif tag=="td": self.in_cell = False elif tag=="tr": - if self.current_item: + if self.current_item and self.mod_row: for it in self.items.values(): - if not it.upgrade and self.current_item.is_upgrade_for(it): - it.upgrade = self.current_item - break + self.current_item.check_upgrade(it) elif tag=="h1": self.in_heading = False def handle_data(self, data): data = data.strip() + if not data: + return + if self.in_heading: self.current_heading = data self.headings.append(self.current_heading) - elif self.in_items_table and self.in_cell and data and not self.ignore_row: - if self.column==2: - self.current_item = self.create_item(data, self.current_heading) - self.items[data] = self.current_item - elif self.column==3: - self.current_item.droplevel = int(data) - elif self.column>=4: - self.handle_value(self.column, data) + elif self.in_items_table and self.in_cell: + if self.mod_row: + if self.column==1: + self.mod_names.append(data) + self.mod_index = 0 + elif self.column==2: + if " to " in data: + value = int(data.split(" to ", 1)[1]) + else: + value = int(data) + name = self.mod_names[self.mod_index] + if name!="From Armour Movement Speed +%": + self.current_item.mods[name] = value + self.mod_index += 1 + else: + if self.column==2: + self.current_item = self.create_item(data, self.current_heading) + self.items[data] = self.current_item + elif self.column==3: + self.current_item.droplevel = int(data) + elif self.column>=4: + self.handle_value(self.column, data) def create_item(self, name, kind): pass @@ -127,21 +209,28 @@ class WeaponDataParser(ItemDataParser): elif column==6: self.current_item.dps = float(data) +def get_upgrade_level(item, steps): + level = 0 + for p in item.upgrades.keys(): + upgrade = item + for i in range(steps): + upgrade = upgrade.upgrades.get(p) + if not upgrade: + return 0 + level = max(level, upgrade.droplevel) + return level + def write_best_category(out, prefix, items, steps): best = ["best", "second"] out.write('category "{}.{}_at_level"\n'.format(prefix, best[steps-1])) out.write("{\n\tor\n\t{\n") for it in items: - upgrade = it - for k in range(steps): - upgrade = upgrade.upgrade - if not upgrade: - break + upgrade_level = get_upgrade_level(it, steps) out.write("\t\tand\n\t\t{\n") - if upgrade: + if upgrade_level: out.write('\t\t\tbase_type "{}";\n'.format(it.name)) - out.write("\t\t\titem_level {} {};\n".format(it.droplevel, upgrade.droplevel-1)) + out.write("\t\t\titem_level {} {};\n".format(it.droplevel, upgrade_level-1)) else: out.write('\t\t\tbase_type "{}";\n'.format(it.name)) out.write("\t\t\tmin_item_level {};\n".format(it.droplevel)) -- 2.45.2