예제 #1
0
    def populate_monster_properties_from_wiki_data(self):
        """Populate item data from a OSRS Wiki Infobox Item template."""
        logging.debug("populate_monster_properties_from_wiki_data: Populating wiki data...")

        # STAGE ONE: Determine then set the wiki_name and wiki_url

        # Manually set OSRS Wiki name
        if self.wikitext_found_using not in ["id"]:
            # Monster found in wiki by ID, cache name is the best option
            wiki_page_name = self.monster_name
        else:
            # Monster found using direct cache name lookup on wiki page names,
            # So use wiki page name in the monster_wikitext array
            wiki_page_name = self.monster_wikitext[0]

        wiki_versioned_name = None
        wiki_name = None

        # Get the versioned, or non-versioned, name from the infobox
        if self.infobox_version_number is not None:
            key = "version" + str(self.infobox_version_number)
            wiki_versioned_name = self.extract_infobox_value(self.template, key)
        else:
            wiki_versioned_name = self.extract_infobox_value(self.template, "version")

        # Set the wiki_name property
        if wiki_versioned_name is not None:
            if wiki_versioned_name.startswith("("):
                wiki_name = wiki_page_name + " " + wiki_versioned_name
            else:
                wiki_name = wiki_page_name + " (" + wiki_versioned_name + ")"
        else:
            wiki_name = wiki_page_name

        self.monster_dict["wiki_name"] = wiki_name

        # Set the wiki_url property
        if wiki_versioned_name is not None:
            wiki_url = wiki_page_name + "#" + wiki_versioned_name
        else:
            wiki_url = wiki_page_name

        wiki_url = wiki_url.replace(" ", "_")
        self.monster_dict["wiki_url"] = "https://oldschool.runescape.wiki/w/" + wiki_url

        # STAGE TWO: Extract, process and set monster properties from the infobox template

        # MEMBERS: Determine the members status of a monster
        members = None
        if self.infobox_version_number is not None:
            key = "members" + str(self.infobox_version_number)
            members = self.extract_infobox_value(self.template, key)
        if members is None:
            members = self.extract_infobox_value(self.template, "members")
        if members is not None:
            self.monster_dict["members"] = infobox_cleaner.clean_boolean(members)
        else:
            self.monster_dict["members"] = False

        # RELEASE_DATE: Determine the release date of a monster
        release_date = None
        if self.infobox_version_number is not None:
            key = "release" + str(self.infobox_version_number)
            release_date = self.extract_infobox_value(self.template, key)
        if release_date is None:
            release_date = self.extract_infobox_value(self.template, "release")
        if release_date is not None:
            self.monster_dict["release_date"] = infobox_cleaner.clean_release_date(release_date)
        else:
            self.monster_dict["release_date"] = None
            self.monster_dict["incomplete"] = True

        # HITPOINTS: Determine the hitpoints of a monster
        hitpoints = None
        if self.infobox_version_number is not None:
            key = "hitpoints" + str(self.infobox_version_number)
            hitpoints = self.extract_infobox_value(self.template, key)
        if hitpoints is None:
            hitpoints = self.extract_infobox_value(self.template, "hitpoints")
        if hitpoints is not None:
            self.monster_dict["hitpoints"] = infobox_cleaner.clean_integer(hitpoints)
        else:
            self.monster_dict["hitpoints"] = 0
            self.monster_dict["incomplete"] = True

        # MAX HIT: Determine the max hit of a monster
        max_hit = None
        if self.infobox_version_number is not None:
            key = "max hit" + str(self.infobox_version_number)
            max_hit = self.extract_infobox_value(self.template, key)
        if max_hit is None:
            max_hit = self.extract_infobox_value(self.template, "max hit")
        if max_hit is not None:
            self.monster_dict["max_hit"] = infobox_cleaner.clean_integer(max_hit)
        else:
            self.monster_dict["max_hit"] = 0
            self.monster_dict["incomplete"] = True

        # ATTACK TYPE: Determine the attack type of a monster
        attack_type = None
        if self.infobox_version_number is not None:
            key = "attack style" + str(self.infobox_version_number)
            attack_type = self.extract_infobox_value(self.template, key)
        if attack_type is None:
            attack_type = self.extract_infobox_value(self.template, "attack style")
        if attack_type is not None:
            self.monster_dict["attack_type"] = infobox_cleaner.clean_attack_type(attack_type)
        else:
            self.monster_dict["attack_type"] = list()
            self.monster_dict["incomplete"] = True

        # ATTACK SPEED: Determine the attack speed of a monster
        attack_speed = None
        if self.infobox_version_number is not None:
            key = "attack speed" + str(self.infobox_version_number)
            attack_speed = self.extract_infobox_value(self.template, key)
        if attack_speed is None:
            attack_speed = self.extract_infobox_value(self.template, "attack speed")
        if attack_speed is not None:
            self.monster_dict["attack_speed"] = infobox_cleaner.clean_integer(attack_speed)
        else:
            self.monster_dict["attack_speed"] = None
            self.monster_dict["incomplete"] = True

        # AGGRESSIVE: Determine the aggressive property of a monster
        aggressive = None
        if self.infobox_version_number is not None:
            key = "aggressive" + str(self.infobox_version_number)
            aggressive = self.extract_infobox_value(self.template, key)
        if aggressive is None:
            aggressive = self.extract_infobox_value(self.template, "aggressive")
        if aggressive is not None:
            self.monster_dict["aggressive"] = infobox_cleaner.clean_boolean(aggressive)
        else:
            self.monster_dict["aggressive"] = False
            self.monster_dict["incomplete"] = True

        # POISONOUS: Determine the poisonous property of a monster
        poisonous = None
        if self.infobox_version_number is not None:
            key = "poisonous" + str(self.infobox_version_number)
            poisonous = self.extract_infobox_value(self.template, key)
        if poisonous is None:
            poisonous = self.extract_infobox_value(self.template, "poisonous")
        if poisonous is not None:
            self.monster_dict["poisonous"] = infobox_cleaner.clean_boolean(poisonous)
        else:
            self.monster_dict["poisonous"] = False
            self.monster_dict["incomplete"] = True

        # IMMUNE POISON: Determine the immunity to poison property of a monster
        immune_poison = None
        if self.infobox_version_number is not None:
            key = "immunepoison" + str(self.infobox_version_number)
            immune_poison = self.extract_infobox_value(self.template, key)
        if immune_poison is None:
            immune_poison = self.extract_infobox_value(self.template, "immunepoison")
        if immune_poison is not None:
            self.monster_dict["immune_poison"] = infobox_cleaner.clean_boolean(immune_poison)
        else:
            self.monster_dict["immune_poison"] = False
            self.monster_dict["incomplete"] = True

        # IMMUNE VENOM: Determine the immunity to venom property of a monster
        immune_venom = None
        if self.infobox_version_number is not None:
            key = "immunevenom" + str(self.infobox_version_number)
            immune_venom = self.extract_infobox_value(self.template, key)
        if immune_venom is None:
            immune_venom = self.extract_infobox_value(self.template, "immunevenom")
        if immune_venom is not None:
            self.monster_dict["immune_venom"] = infobox_cleaner.clean_boolean(immune_venom)
        else:
            self.monster_dict["immune_venom"] = False
            self.monster_dict["incomplete"] = True

        # WEAKNESS: Determine any weaknesses of the monster
        weakness = None
        if self.infobox_version_number is not None:
            key = "weakness" + str(self.infobox_version_number)
            weakness = self.extract_infobox_value(self.template, key)
        if weakness is None:
            weakness = self.extract_infobox_value(self.template, "weakness")
        if weakness is not None:
            weakness = infobox_cleaner.clean_weaknesses(weakness)
            self.monster_dict["weakness"] = weakness
        else:
            self.monster_dict["weakness"] = list()
            self.monster_dict["incomplete"] = True

        # CATEGORY: Determine category of the monster
        category = None
        if self.infobox_version_number is not None:
            key = "cat" + str(self.infobox_version_number)
            category = self.extract_infobox_value(self.template, key)
        if category is None:
            category = self.extract_infobox_value(self.template, "cat")
        if category is not None:
            category = infobox_cleaner.clean_category(category)
            self.monster_dict["category"] = category
        else:
            self.monster_dict["category"] = list()
            self.monster_dict["incomplete"] = True

        # SLAYER LEVEL: Determine the slayer level required
        slayer_level = None
        if self.infobox_version_number is not None:
            key = "slaylvl" + str(self.infobox_version_number)
            slayer_level = self.extract_infobox_value(self.template, key)
        if slayer_level is None:
            slayer_level = self.extract_infobox_value(self.template, "slaylvl")
        if slayer_level is not None:
            self.monster_dict["slayer_level"] = infobox_cleaner.clean_integer(slayer_level)
        else:
            self.monster_dict["slayer_level"] = None
            self.monster_dict["incomplete"] = True

        # SLAYER XP: Determine XP given from slayer monster kill
        slayer_xp = None
        if self.infobox_version_number is not None:
            key = "slayxp" + str(self.infobox_version_number)
            slayer_xp = self.extract_infobox_value(self.template, key)
        if slayer_xp is None:
            slayer_xp = self.extract_infobox_value(self.template, "slayxp")
        if slayer_xp is not None:
            self.monster_dict["slayer_xp"] = infobox_cleaner.clean_float(slayer_xp)
        else:
            self.monster_dict["slayer_xp"] = None
            self.monster_dict["incomplete"] = True

        # Quick check for slayer XP versus slayer level
        # Fix None for slayer level, when a level is not required
        if self.monster_dict["slayer_xp"] is not None:
            # print("Here", self.monster_dict["slayer_xp"])
            if self.monster_dict["slayer_level"] is None:
                self.monster_dict["slayer_level"] = 1

        # SLAYER MONSTER: Determine if the monster can be a slayer task
        if self.monster_dict["slayer_level"] or self.monster_dict["slayer_xp"]:
            self.monster_dict["slayer_monster"] = True
        else:
            self.monster_dict["slayer_monster"] = False

        # SLAYER MASTERS: Determine the slayer masters
        if self.monster_dict["slayer_monster"]:
            slayer_masters = None
            if self.infobox_version_number is not None:
                key = "assignedby" + str(self.infobox_version_number)
                slayer_masters = self.extract_infobox_value(self.template, key)
            if slayer_masters is None:
                slayer_masters = self.extract_infobox_value(self.template, "assignedby")
            if slayer_masters is not None:
                slayer_masters = slayer_masters.strip()
                slayer_masters = slayer_masters.split(",")
                slayer_masters = [x.strip() for x in slayer_masters]
                if "steve" in slayer_masters:
                    slayer_masters.remove("steve")
                    if "nieve" not in slayer_masters:
                        slayer_masters.append("nieve")
                self.monster_dict["slayer_masters"] = slayer_masters
                if self.monster_dict["slayer_masters"][0] == "No":
                    self.monster_dict["slayer_masters"] = None
            else:
                self.monster_dict["slayer_masters"] = None
                self.monster_dict["incomplete"] = True

        # Set the slayer_masters property to an empty list if not populated
        try:
            if not self.monster_dict["slayer_masters"]:
                self.monster_dict["slayer_masters"] = list()
        except KeyError:
            self.monster_dict["slayer_masters"] = list()

        # EXAMINE: Determine the monster examine text
        examine = None
        if self.infobox_version_number is not None:
            key = "examine" + str(self.infobox_version_number)
            examine = self.extract_infobox_value(self.template, key)
        if examine is None:
            examine = self.extract_infobox_value(self.template, "examine")
        if examine is not None:
            self.monster_dict["examine"] = infobox_cleaner.clean_monster_examine(examine)
        else:
            self.monster_dict["examine"] = None
            self.monster_dict["incomplete"] = True

        # MONSTER COMBAT BONUSES: Determine stats of the monster

        # Initialize a dictionary that maps database_name -> infobox_name
        # The database_name is used in this project
        # The infobox_name is used by the OSRS Wiki
        combat_bonuses = {"attack_level": "att",
                          "strength_level": "str",
                          "defence_level": "def",
                          "magic_level": "mage",
                          "ranged_level": "range",
                          "attack_stab": "astab",
                          "attack_slash": "aslash",
                          "attack_crush": "acrush",
                          "attack_magic": "amagic",
                          "attack_ranged": "arange",
                          "defence_stab": "dstab",
                          "defence_slash": "dslash",
                          "defence_crush": "dcrush",
                          "defence_magic": "dmagic",
                          "defence_ranged": "drange",
                          "attack_accuracy": "attbns",
                          "melee_strength": "strbns",
                          "ranged_strength": "rngbns",
                          "magic_damage": "mbns"
                          }

        # Loop each of the combat bonuses and populate
        for database_name, property_name in combat_bonuses.items():
            value = None
            if self.infobox_version_number is not None:
                key = property_name + str(self.infobox_version_number)
                value = self.extract_infobox_value(self.template, key)
            if value is None:
                value = self.extract_infobox_value(self.template, property_name)
            if value is not None:
                self.monster_dict[database_name] = infobox_cleaner.clean_stats_value(value)
            else:
                self.monster_dict[database_name] = 0
                self.monster_dict["incomplete"] = True

        # We finished processing, set incomplete to false if not true
        if not self.monster_dict.get("incomplete"):
            self.monster_dict["incomplete"] = False
예제 #2
0
    def populate_item_properties_from_wiki_data(self):
        """Populate item data from a OSRS Wiki Infobox Item template."""
        if not self.has_infobox:
            # Cannot populate if there is no infobox!
            self.populate_non_wiki_item()
            logging.error(
                "populate_item_properties_from_wiki_data: No infobox for wiki item."
            )
            return False

        # STAGE ONE: Determine then set the wiki_name, wiki_url
        # and wiki_exchnage properties

        # Manually set OSRS Wiki name
        if self.wikitext_found_using not in ["id", "linked_id"]:
            # Item found in wiki by ID, cache name is the best option
            wiki_page_name = self.item_name
        elif self.wikitext_found_using == "normalized":
            # Item found in wiki by normalized name, normalize name is used
            wiki_page_name = self.normalized_name
        else:
            # Item found using direct cache name lookup on wiki page names,
            # So use wiki page name in the item_wikitext array
            wiki_page_name = self.item_wikitext[0]

        wiki_versioned_name = None
        wiki_name = None

        # Get the versioned, or non-versioned, name from the infobox
        if self.infobox_version_number is not None:
            key = "version" + str(self.infobox_version_number)
            wiki_versioned_name = self.extract_infobox_value(
                self.template, key)
        else:
            wiki_versioned_name = self.extract_infobox_value(
                self.template, "version")

        # Set the wiki_name property
        if wiki_versioned_name is not None:
            if wiki_versioned_name.startswith("("):
                wiki_name = wiki_page_name + " " + wiki_versioned_name
            else:
                wiki_name = wiki_page_name + " (" + wiki_versioned_name + ")"
        else:
            wiki_name = wiki_page_name

        self.item_dict["wiki_name"] = wiki_name

        # Set the wiki_url property
        if wiki_versioned_name is not None:
            wiki_url = wiki_page_name + "#" + wiki_versioned_name
        else:
            wiki_url = wiki_page_name

        wiki_url = wiki_url.replace(" ", "_")
        self.item_dict[
            "wiki_url"] = "https://oldschool.runescape.wiki/w/" + wiki_url

        # Try find the OSRS Wiki Exchange name/URL
        exchange_base_url = "https://oldschool.runescape.wiki/w/Exchange:"
        if self.item_dict["tradeable_on_ge"]:
            gemwname = None
            if self.infobox_version_number is not None:
                key = "gemwname" + str(self.infobox_version_number)
                gemwname = self.extract_infobox_value(self.template, key)
            if gemwname is None:
                gemwname = self.extract_infobox_value(self.template,
                                                      "gemwname")
            if gemwname is not None:
                wiki_exchange = gemwname.replace(" ", "_")
            else:
                wiki_exchange = self.item_dict["name"].replace(" ", "_")
            self.item_dict["wiki_exchange"] = exchange_base_url + wiki_exchange
        else:
            self.item_dict["wiki_exchange"] = None

        # Check if item is not actually able to be alched
        if wiki_name:
            if wiki_name in self.unalchable_items:
                self.item_dict["lowalch"] = None
                self.item_dict["highalch"] = None
            elif wiki_versioned_name in self.unalchable_items:
                self.item_dict["lowalch"] = None
                self.item_dict["highalch"] = None

        # STAGE TWO: Extract, process and set item properties from the infobox template

        # WEIGHT: Determine the weight of an item
        weight = None
        if self.infobox_version_number is not None:
            key = "weight" + str(self.infobox_version_number)
            weight = self.extract_infobox_value(self.template, key)
        if weight is None:
            weight = self.extract_infobox_value(self.template, "weight")
        if weight is not None:
            self.item_dict["weight"] = infobox_cleaner.clean_weight(
                weight, self.item_id)
        else:
            self.item_dict["weight"] = None
            self.item_dict["incomplete"] = True

        # QUEST: Determine if item is associated with a quest
        quest = None
        if self.infobox_version_number is not None:
            key = "quest" + str(self.infobox_version_number)
            quest = self.extract_infobox_value(self.template, key)
        if quest is None:
            quest = self.extract_infobox_value(self.template, "quest")
        if quest is not None:
            self.item_dict["quest_item"] = infobox_cleaner.clean_quest(quest)
        else:
            # Being here means the extraction for "quest" failed
            key = "questrequired" + str(self.infobox_version_number)
            quest = self.extract_infobox_value(self.template, key)
            if quest is None:
                quest = self.extract_infobox_value(self.template,
                                                   "questrequired")
            if quest is not None:
                self.item_dict["quest_item"] = infobox_cleaner.clean_quest(
                    quest)
            else:
                self.item_dict["quest_item"] = False

        # Determine the release date of an item
        release_date = None
        if self.infobox_version_number is not None:
            key = "release" + str(self.infobox_version_number)
            release_date = self.extract_infobox_value(self.template, key)
        if release_date is None:
            release_date = self.extract_infobox_value(self.template, "release")
        if release_date is not None:
            self.item_dict[
                "release_date"] = infobox_cleaner.clean_release_date(
                    release_date)
        else:
            self.item_dict["release_date"] = None
            self.item_dict["incomplete"] = True

        # Determine if an item is tradeable
        tradeable = None
        if self.infobox_version_number is not None:
            key = "tradeable" + str(self.infobox_version_number)
            tradeable = self.extract_infobox_value(self.template, key)
        if tradeable is None:
            tradeable = self.extract_infobox_value(self.template, "tradeable")
        if tradeable is not None:
            self.item_dict["tradeable"] = infobox_cleaner.clean_boolean(
                tradeable)
        else:
            self.item_dict["tradeable"] = False
            self.item_dict["incomplete"] = True

        # Determine the examine text of an item
        examine = None
        if self.infobox_version_number is not None:
            key = "examine" + str(self.infobox_version_number)
            examine = self.extract_infobox_value(self.template, key)
        if examine is None:
            examine = self.extract_infobox_value(self.template, "examine")
        if examine is not None:
            self.item_dict["examine"] = infobox_cleaner.clean_examine(
                examine, self.item_dict["name"])
        else:
            # Being here means the extraction for "examine" failed
            key = "itemexamine" + str(self.infobox_version_number)
            examine = self.extract_infobox_value(self.template, key)
            if examine is None:
                examine = self.extract_infobox_value(self.template,
                                                     "itemexamine")
            if examine is not None:
                self.item_dict["examine"] = infobox_cleaner.clean_examine(
                    examine, self.item_dict["name"])
            else:
                self.item_dict["examine"] = None
                self.item_dict["incomplete"] = True

        # Set item buy limit, if it is tradeable on the GE
        if not self.item_dict["tradeable_on_ge"]:
            self.item_dict["buy_limit"] = None
        else:
            buy_limit = None
            try:
                buy_limit = self.buy_limits_data[self.item_id_str]
            except KeyError:
                print(
                    "populate_item_properties_from_wiki_data: Error setting buy limit..."
                )
                print(f"{self.item_id} has no buy limit available. Exiting.")
                exit()
            self.item_dict["buy_limit"] = buy_limit

        # We finished processing, set incomplete to false if not true
        if not self.item_dict.get("incomplete"):
            self.item_dict["incomplete"] = False

        return True