示例#1
0
    def parse(self, dbr, dbr_file, result):
        # If no tag exists, skip parsing:
        tag = dbr.get('itemNameTag', None)
        if not tag:
            raise StopIteration

        # Set the known item properties:
        result.update({
            'bitmap': dbr.get('bitmap', None),
            'itemLevel': dbr.get('itemLevel', None),
            'name': texts.get(tag),
            'tag': tag,
        })

        # Check if this item is part of a set:
        item_set_path = dbr.get('itemSetName', None)
        if item_set_path:
            # Read (don't parse to avoid recursion) the set to get the tag:
            item_set = DBRParser.read(item_set_path)

            # Only add the set if it has a tag:
            result['set'] = item_set.get(ItemSetParser.NAME, None)

        # Stop parsing here if requirement parsing isn't necessary
        if not self.should_parse_requirements(dbr, result):
            return

        # Cost prefix of this props is determined by its class
        cost_prefix = dbr['Class'].split('_')[1]
        cost_prefix = cost_prefix[:1].lower() + cost_prefix[1:]

        # Read cost file
        cost_properties = DBRParser.read(
            dbr.get('itemCostName', self.REQUIREMENT_FALLBACK))

        # Grab the props level (it's a variable in the equations)
        for requirement in self.REQUIREMENTS:
            # Create the equation key
            equation_key = cost_prefix + requirement + 'Equation'
            req = requirement.lower() + 'Requirement'

            # Existing requirements shouldn't be overriden:
            if equation_key in cost_properties and req not in result:
                equation = cost_properties[equation_key]

                # camelCased variables are required for the equations:
                itemLevel = dbr['itemLevel']  # noqa
                totalAttCount = len(result['properties'])  # noqa

                # Eval the equation:
                result[req] = math.ceil(numexpr.evaluate(equation).item())
示例#2
0
    def parse(self, dbr, dbr_file, result):
        # If no tag exists, skip parsing:
        tag = dbr.get('itemNameTag', None)
        if not tag:
            raise StopIteration

        # Set the known item properties:
        result.update({
            'bitmap': dbr.get('bitmap', None),
            'itemLevel': dbr.get('itemLevel', None),
            'name': texts.get(tag),
            'tag': tag,
        })

        # Check if this item is part of a set:
        item_set_path = dbr.get('itemSetName', None)
        if item_set_path:
            # Read (don't parse to avoid recursion) the set to get the tag:
            item_set = DBRParser.read(item_set_path)

            # Only add the set if it has a tag:
            result['set'] = item_set.get(ItemSetParser.NAME, None)

        # Stop parsing here if requirement parsing isn't necessary
        if not self.should_parse_requirements(dbr, result):
            return

        # Cost prefix of this props is determined by its class
        cost_prefix = dbr['Class'].split('_')[1]
        cost_prefix = cost_prefix[:1].lower() + cost_prefix[1:]

        # Read cost file
        cost_properties = DBRParser.read(dbr.get(
            'itemCostName', self.REQUIREMENT_FALLBACK))

        # Grab the props level (it's a variable in the equations)
        for requirement in self.REQUIREMENTS:
            # Create the equation key
            equation_key = cost_prefix + requirement + 'Equation'
            req = requirement.lower() + 'Requirement'

            # Existing requirements shouldn't be overriden:
            if equation_key in cost_properties and req not in result:
                equation = cost_properties[equation_key]

                # camelCased variables are required for the equations:
                itemLevel = dbr['itemLevel']  # noqa
                totalAttCount = len(result['properties'])  # noqa

                # Eval the equation:
                result[req] = math.ceil(numexpr.evaluate(equation).item())
示例#3
0
文件: base.py 项目: rehevkor5/tqdb
    def _parse_skill_grant(self, dbr, result):
        """
        Parse a granted skill.

        """
        # Skip files without both granted skill name and level:
        if self.SKILL_NAME not in dbr or self.SKILL_LEVEL not in dbr:
            return

        level = dbr[self.SKILL_LEVEL]
        skill = DBRParser.parse(dbr[self.SKILL_NAME])

        if 'name' not in skill:
            return

        # Store the skill, which will ensure a unique tag:
        skill_tag = storage.store_skill(skill)

        # Now add the granted skill to the item:
        result['properties'][self.SKILL_NAME] = {
            'tag': skill_tag,
            'level': level,
        }

        if self.CONTROLLER not in dbr:
            return

        # Grab the auto controller to see if this skill is activated:
        controller = DBRParser.read(dbr[self.CONTROLLER])

        # The property 'triggerType' can be converted to a useful text suffix
        # like 'Activated on attack':
        result['properties'][self.SKILL_NAME].update(
            {'trigger': texts.get(self.TRIGGERS[controller['triggerType']])})
示例#4
0
文件: base.py 项目: fonsleenaars/tqdb
    def _parse_skill_grant(self, dbr, result):
        """
        Parse a granted skill.

        """
        # Skip files without both granted skill name and level:
        if self.SKILL_NAME not in dbr or self.SKILL_LEVEL not in dbr:
            return

        level = dbr[self.SKILL_LEVEL]
        skill = DBRParser.parse(dbr[self.SKILL_NAME])

        if 'name' not in skill:
            return

        # Store the skill, which will ensure a unique tag:
        skill_tag = storage.store_skill(skill)

        # Now add the granted skill to the item:
        result['properties'][self.SKILL_NAME] = {
            'tag': skill_tag,
            'level': level,
        }

        if self.CONTROLLER not in dbr:
            return

        # Grab the auto controller to see if this skill is activated:
        controller = DBRParser.read(dbr[self.CONTROLLER])

        # The property 'triggerType' can be converted to a useful text suffix
        # like 'Activated on attack':
        result['properties'][self.SKILL_NAME].update({
            'trigger': texts.get(self.TRIGGERS[controller['triggerType']])
        })
示例#5
0
    def parse(self, dbr, dbr_file, result):
        """
        Parse the skill that spawns a pet.

        """
        # Only set time to live it's set (otherwise it's infinite)
        ttl_list = dbr.get(self.TTL, None)

        # Parse all the summons and set them as a list:
        result['summons'] = []
        for index, spawn_file in enumerate(dbr['spawnObjects']):
            spawn = DBRParser.parse(spawn_file)

            # Keep track of the original properties this summon had:
            original_properties = {}
            if 'properties' in spawn:
                if isinstance(spawn['properties'], list):
                    original_properties = spawn['properties'][0].copy()
                else:
                    original_properties = spawn['properties'].copy()

            # We need the raw values from the spawn DBR for hp/mp
            spawn['properties'] = {}
            spawn_dbr = DBRParser.read(spawn_file)

            if 'characterLife' in spawn_dbr:
                hp_list = spawn_dbr['characterLife']
                hp = (hp_list[index]
                      if index < len(hp_list) else hp_list[len(hp_list) - 1])
                TQDBParser.insert_value('characterLife',
                                        texts.get('LifeText').format(hp),
                                        spawn)
            if 'characterMana' in spawn_dbr:
                mp_list = spawn_dbr['characterMana']
                mp = (mp_list[index]
                      if index < len(mp_list) else mp_list[len(mp_list) - 1])
                TQDBParser.insert_value('characterMana',
                                        texts.get('ManaText').format(mp),
                                        spawn)
            if ttl_list:
                ttl = (ttl_list[index] if index < len(ttl_list) else
                       ttl_list[len(ttl_list) - 1])
                TQDBParser.insert_value(self.TTL,
                                        texts.get(self.TTL).format(ttl), spawn)

            # Iterate over the original properties and add some whitelisted
            # properties to the final result:
            for key, value in original_properties.items():
                if key.startswith('character'):
                    continue
                spawn['properties'][key] = value

            result['summons'].append(spawn)
示例#6
0
    def _parse_skill_grant(self, dbr, result):
        """
        Parse a granted skill.

        """
        # If it doesn't have a granted skill name and level, it grants no skills:
        if self.SKILL_NAME not in dbr or self.SKILL_LEVEL not in dbr:
            return

        level = dbr[self.SKILL_LEVEL]
        try:
            skill = DBRParser.parse(dbr[self.SKILL_NAME])
        except InvalidItemError as e:
            logging.debug(
                f"Skipping granted skill record in {dbr[self.SKILL_NAME]}. {e}"
            )
            return

        if 'name' not in skill:
            return

        # Store the skill, which will ensure a unique tag:
        skill_tag = storage.store_skill(skill)

        # Now add the granted skill to the item:
        result['properties'][self.SKILL_NAME] = {
            'tag': skill_tag,
            'level': level,
        }

        if self.CONTROLLER not in dbr:
            return

        # Grab the auto controller to see if this skill is activated:
        controller = DBRParser.read(dbr[self.CONTROLLER])

        # The property 'triggerType' can be converted to a useful text suffix
        # like 'Activated on attack':
        result['properties'][self.SKILL_NAME].update(
            {'trigger': texts.get(self.TRIGGERS[controller['triggerType']])})
示例#7
0
def parse_affixes():
    """
    Parse all the Titan Quest affixes.

    Affixes are the pre- and suffixes that are applied to weapons.
    These affixes add properties to the equipment, these properties,
    the affix names and the equipment they can be applied to is
    indexed and parsed in this function.

    """
    timer = time.clock()

    files = []
    for resource in resources.AFFIX_TABLES:
        table_files = resources.DB / resource
        files.extend(glob.glob(str(table_files), recursive=True))

    # The affix tables will determine what gear an affix can be applied to.
    affix_tables = {}
    for dbr in files:
        table = read(dbr)

        # Use the filename to determine what equipment this table is for:
        file_name = os.path.basename(dbr).split('_')
        table_type = get_affix_table_type(file_name[0])

        # For each affix in this table, create an entry:
        for field, affix_dbr in table.items():
            if not field.startswith('randomizerName') or not table_type:
                continue

            affix_dbr = str(affix_dbr)
            if affix_dbr not in affix_tables:
                affix_tables[affix_dbr] = [table_type]
            elif table_type not in affix_tables[affix_dbr]:
                affix_tables[affix_dbr].append(table_type)

    files = []
    for resource in resources.AFFIXES:
        affix_files = resources.DB / resource
        files.extend(glob.glob(str(affix_files), recursive=True))

    affixes = {'prefixes': {}, 'suffixes': {}}
    for dbr in files:
        affix = parse(dbr)

        # Skip affixes without properties (first one will be empty):
        if not affix['properties']:
            continue

        # Skip the incorrect 'of the Mammoth' prefix entry:
        if 'prefix' in dbr and affix['tag'] == 'tagPrefix145':
            continue

        # Assign the table types to this affix:
        if dbr not in affix_tables:
            # Affix can occur on all equipment:
            affix['equipment'] = 'none'
        else:
            affix['equipment'] = ','.join(affix_tables[dbr])

        # Add affixes to their respective pre- or suffix list.
        if 'Prefix' in affix['tag'] and 'suffix' not in dbr:
            affixType = 'prefixes'
        else:
            affixType = 'suffixes'

        affixTag = affix.pop('tag')

        # Either add the affix or add its properties as an alternative
        if affixTag in affixes[affixType]:
            # Skip duplicate affix properties:
            if is_duplicate_affix(affixes[affixType][affixTag], affix):
                continue
            affixes[affixType][affixTag]['properties'].append(
                affix['properties'])
        else:
            # Place the affix properties into a list that can be extended by
            # alternatives during this parsing.
            affix['properties'] = [affix['properties']]
            affixes[affixType][affixTag] = affix

    # Log and reset the timer:
    logging.info(f'Parsed affixes in {time.clock() - timer} seconds.')

    return affixes
示例#8
0
文件: main.py 项目: fonsleenaars/tqdb
def parse_affixes():
    """
    Parse all the Titan Quest affixes.

    Affixes are the pre- and suffixes that are applied to weapons.
    These affixes add properties to the equipment, these properties,
    the affix names and the equipment they can be applied to is
    indexed and parsed in this function.

    """
    timer = time.clock()

    files = []
    for resource in resources.AFFIX_TABLES:
        table_files = resources.DB / resource
        files.extend(glob.glob(str(table_files), recursive=True))

    # The affix tables will determine what gear an affix can be applied to.
    affix_tables = {}
    for dbr in files:
        table = read(dbr)

        # Use the filename to determine what equipment this table is for:
        file_name = os.path.basename(dbr).split('_')
        table_type = get_affix_table_type(file_name[0])

        # For each affix in this table, create an entry:
        for field, affix_dbr in table.items():
            if not field.startswith('randomizerName') or not table_type:
                continue

            affix_dbr = str(affix_dbr)
            if affix_dbr not in affix_tables:
                affix_tables[affix_dbr] = [table_type]
            elif table_type not in affix_tables[affix_dbr]:
                affix_tables[affix_dbr].append(table_type)

    files = []
    for resource in resources.AFFIXES:
        affix_files = resources.DB / resource
        files.extend(glob.glob(str(affix_files), recursive=True))

    affixes = {'prefixes': {}, 'suffixes': {}}
    for dbr in files:
        affix = parse(dbr)

        # Skip affixes without properties (first one will be empty):
        if not affix['properties']:
            continue

        # Skip the incorrect 'of the Mammoth' prefix entry:
        if 'prefix' in dbr and affix['tag'] == 'tagPrefix145':
            continue

        # Assign the table types to this affix:
        if dbr not in affix_tables:
            # Affix can occur on all equipment:
            affix['equipment'] = 'none'
        else:
            affix['equipment'] = ','.join(affix_tables[dbr])

        # Add affixes to their respective pre- or suffix list.
        if 'Prefix' in affix['tag'] and 'suffix' not in dbr:
            affixType = 'prefixes'
        else:
            affixType = 'suffixes'

        affixTag = affix.pop('tag')

        # Either add the affix or add its properties as an alternative
        if affixTag in affixes[affixType]:
            # Skip duplicate affix properties:
            if is_duplicate_affix(affixes[affixType][affixTag], affix):
                continue
            affixes[affixType][affixTag]['properties'].append(
                affix['properties'])
        else:
            # Place the affix properties into a list that can be extended by
            # alternatives during this parsing.
            affix['properties'] = [affix['properties']]
            affixes[affixType][affixTag] = affix

    # Log and reset the timer:
    logging.info(f'Parsed affixes in {time.clock() - timer} seconds.')

    return affixes
示例#9
0
    def parse(self, dbr, dbr_file, result):
        """
        Parse the skill that spawns a pet.

        """
        # Only set time to live it's set (otherwise it's infinite)
        ttl_list = dbr.get(self.TTL, None)

        # Parse all the summons and set them as a list:
        result['summons'] = []
        for index, spawn_file in enumerate(dbr['spawnObjects']):
            spawn = DBRParser.parse(spawn_file)

            # Keep track of the original properties this summon had:
            original_properties = {}
            if 'properties' in spawn:
                if isinstance(spawn['properties'], list):
                    original_properties = spawn['properties'][0].copy()
                else:
                    original_properties = spawn['properties'].copy()

            # We need the raw values from the spawn DBR for hp/mp
            spawn['properties'] = {}
            spawn_dbr = DBRParser.read(spawn_file)

            if 'characterLife' in spawn_dbr:
                hp_list = spawn_dbr['characterLife']
                hp = (
                    hp_list[index]
                    if index < len(hp_list)
                    else hp_list[len(hp_list) - 1])
                TQDBParser.insert_value(
                    'characterLife',
                    texts.get('LifeText').format(hp),
                    spawn)
            if 'characterMana' in spawn_dbr:
                mp_list = spawn_dbr['characterMana']
                mp = (
                    mp_list[index]
                    if index < len(mp_list)
                    else mp_list[len(mp_list) - 1])
                TQDBParser.insert_value(
                    'characterMana',
                    texts.get('ManaText').format(mp),
                    spawn)
            if ttl_list:
                ttl = (
                    ttl_list[index]
                    if index < len(ttl_list)
                    else ttl_list[len(ttl_list) - 1])
                TQDBParser.insert_value(
                    self.TTL,
                    texts.get(self.TTL).format(ttl),
                    spawn)

            # Iterate over the original properties and add some whitelisted
            # properties to the final result:
            for key, value in original_properties.items():
                if key.startswith('character'):
                    continue
                spawn['properties'][key] = value

            result['summons'].append(spawn)