Esempio n. 1
0
def validate_monsters(mhdata):
    errors = []

    # Check that all monsters have hitzones
    for entry in mhdata.monster_map.values():
        ensure_warn('hitzones' in entry,
                    f"Monster {entry.name('en')} missing hitzones")

    # Check that large monsters have weakness and normal is included
    for entry in mhdata.monster_map.values():
        if entry['size'] == 'small':
            continue

        name = entry.name('en')

        if 'weaknesses' not in entry:
            print(
                f"Warning: Large monster {name} does not contain a weakness entry"
            )
            continue

        if 'normal' not in entry['weaknesses']:
            errors.append(
                f"Invalid weaknesses in {name}, normal is a required state")

    return errors
Esempio n. 2
0
def validate_monster_rewards(mhdata):
    """Validates monster rewards for sane values. 
    Certain fields (like carve) sum to 100, 
    Others (like quest rewards) must be at least 100%"""

    # Those other than these are validated for 100% drop rate EXACT.
    # Quest rewards sometimes contain a guaranteed reward.
    # We should probably separate, but most databases don't separate them.
    # Investigate further
    uncapped_conditions = ("Quest Reward / Investigation (Bronze)")

    errors = set()

    for monster_id, entry in mhdata.monster_map.items():
        if 'rewards' not in entry:
            continue

        monster_name = entry.name('en')  # used for error display

        # accumulates percentages by rank
        reward_percentages = {rank: [] for rank in supported_ranks}

        valid = True
        for reward in entry['rewards']:
            condition = reward['condition_en']
            rank = reward['rank']

            # ensure condition exists
            if condition not in mhdata.monster_reward_conditions_map.names(
                    'en'):
                errors.add(
                    f"Invalid condition {condition} in monster {monster_name}")
                valid = False

            if rank not in supported_ranks:
                errors.add(
                    f"Unsupported rank {rank} in {monster_name} rewards")
                valid = False

        if not valid:
            continue

        # Ensure percentage is correct (at or greater than 100)
        rank_reward_key_fn = lambda r: (r['rank'], r['condition_en'])
        sorted_rewards = sorted(entry['rewards'], key=rank_reward_key_fn)
        for (rank,
             condition), items in itertools.groupby(sorted_rewards,
                                                    rank_reward_key_fn):
            percentage_sum = sum((int(r['percentage']) for r in items), 0)

            key_str = f"(rank {rank} condition {condition})"
            error_start = f"Rewards %'s for monster {monster_name} {key_str}"
            if condition not in uncapped_conditions:
                ensure_warn(percentage_sum == 100,
                            f"{error_start} does not sum to 100")
            else:
                ensure_warn(percentage_sum >= 100,
                            f"{error_start} does not sum to at least 100")

    return errors
Esempio n. 3
0
def validate_monster_rewards(mhdata):
    """Validates monster rewards for sane values. 
    Certain fields (like carve) sum to 100, 
    Others (like quest rewards) must be at least 100%"""

    # Those other than these are validated for 100% drop rate EXACT.
    # Quest rewards sometimes contain a guaranteed reward.
    # We should probably separate, but most databases don't separate them.
    # Investigate further
    uncapped_conditions = ("Quest Reward (Bronze)")

    errors = set()
    
    for monster_id, entry in mhdata.monster_map.items():
        if 'rewards' not in entry:
            continue

        monster_name = entry.name('en') # used for error display

        valid = True
        for reward in entry['rewards']:
            condition = reward['condition_en']
            rank = reward['rank']

            # ensure condition exists
            if condition not in mhdata.monster_reward_conditions_map.names('en'):
                errors.add(f"Invalid condition {condition} in monster {monster_name}")
                valid = False

            if reward['item_en'] not in mhdata.item_map.names('en'):
                errors.add(f"Monster reward item {reward['item_en']} doesn't exist")
                valid = False

            if rank not in cfg.supported_ranks:
                errors.add(f"Unsupported rank {rank} in {monster_name} rewards")
                valid = False

        if not valid:
            continue
        
        # Ensure percentage is correct (at or greater than 100)
        rank_reward_key_fn = lambda r: (r['rank'], r['condition_en'])
        sorted_rewards = sorted(entry['rewards'], key=rank_reward_key_fn)
        for (rank, condition), items in itertools.groupby(sorted_rewards, rank_reward_key_fn):
            items = list(items)

            # Check if any item is considered unknown. If any are, all must be unknown.
            num_unknown_percent = len([i for i in items if i['percentage'] is None])
            if num_unknown_percent == len(items):
                continue
            elif num_unknown_percent > 0:
                errors.add(f"Error with {monster_name} rewards" +
                    f" - entries for ({rank}, {condition}) must all be blank or must all have a percentage.")
                continue

            percentage_sum = sum((int(r['percentage']) for r in items), 0)

            key_str = f"(rank {rank} condition {condition})"
            error_start = f"Rewards %'s for monster {monster_name} {key_str}"
            if condition not in uncapped_conditions:
                ensure_warn(
                    percentage_sum == 100, 
                    f"{error_start} does not sum to 100")
            else:
                ensure_warn(
                    percentage_sum >= 100, 
                    f"{error_start} does not sum to at least 100")

    return errors
Esempio n. 4
0
def validate_monster_rewards(mhdata):
    """Validates monster rewards for sane values. 
    Certain fields (like carve) sum to 100, 
    Others (like quest rewards) must be at least 100%"""

    errors = set()

    for monster_id, entry in mhdata.monster_map.items():
        if 'rewards' not in entry:
            continue

        monster_name = entry.name('en')  # used for error display

        valid = True
        for reward in entry['rewards']:
            condition = reward['condition_en']
            rank = reward['rank']

            # ensure condition exists
            if condition not in mhdata.monster_reward_conditions_map.names(
                    'en'):
                errors.add(
                    f"Invalid condition {condition} in monster {monster_name}")
                valid = False

            if reward['item_en'] not in mhdata.item_map.names('en'):
                errors.add(
                    f"Monster reward item {reward['item_en']} doesn't exist")
                valid = False

            if rank not in cfg.supported_ranks:
                errors.add(
                    f"Unsupported rank {rank} in {monster_name} rewards")
                valid = False

        if not valid:
            continue

        # Ensure percentage is correct (at or greater than 100)
        rank_reward_key_fn = lambda r: (r['rank'], r['condition_en'])
        sorted_rewards = sorted(entry['rewards'], key=rank_reward_key_fn)
        for (rank,
             condition), items in itertools.groupby(sorted_rewards,
                                                    rank_reward_key_fn):
            items = list(items)

            # Check if any item is considered unknown. If any are, all must be unknown.
            num_unknown_percent = len(
                [i for i in items if i['percentage'] is None])
            if num_unknown_percent == len(items):
                continue
            elif num_unknown_percent > 0:
                errors.add(
                    f"Error with {monster_name} rewards" +
                    f" - entries for ({rank}, {condition}) must all be blank or must all have a percentage."
                )
                continue

            percentages = [int(r['percentage']) for r in items]
            if percentages == [100]:
                percentage_sum = 100
            else:
                percentage_sum = sum((p for p in percentages if p != 100), 0)

            key_str = f"(rank {rank} condition {condition})"
            error_start = f"Rewards %'s for monster {monster_name} {key_str}"
            ensure_warn(percentage_sum == 100,
                        f"{error_start} does not sum to 100")

    return errors