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
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
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
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