You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							164 lines
						
					
					
						
							5.0 KiB
						
					
					
				
			
		
		
	
	
							164 lines
						
					
					
						
							5.0 KiB
						
					
					
				#!/usr/bin/env python3
 | 
						|
 | 
						|
import sys
 | 
						|
import argparse
 | 
						|
import difflib
 | 
						|
 | 
						|
import _pathfix
 | 
						|
 | 
						|
from mhapi.db import MHDB
 | 
						|
from mhapi.model import get_decoration_values
 | 
						|
from mhapi.util import get_utf8_writer
 | 
						|
 | 
						|
 | 
						|
def parse_args(argv):
 | 
						|
    parser = argparse.ArgumentParser(description=
 | 
						|
        "Find armor with the specified skills and sort by"
 | 
						|
        " (max points, defense). Takes into account native points"
 | 
						|
        " and slots that fit decorations for the first skill."
 | 
						|
    )
 | 
						|
    parser.add_argument("-g", "--gunner", action="store_true",
 | 
						|
                        default=False,
 | 
						|
                        help="search for gunner instead of blademaster")
 | 
						|
    parser.add_argument("-d", "--min-defense", type=int,
 | 
						|
                        help="Only include armors with min defense")
 | 
						|
    parser.add_argument("-t", "--type",
 | 
						|
                        help="Head, Body, Arms, Waist, or Legs",
 | 
						|
                        type=str_title)
 | 
						|
    parser.add_argument("-r", "--resist",
 | 
						|
                        help="fire, water, thunder, ice, or dragon."
 | 
						|
                             " Show and use as secondary sort key instead of"
 | 
						|
                             " defense",
 | 
						|
                        type=str_lower)
 | 
						|
    parser.add_argument("skills", nargs="+",
 | 
						|
                        help="One or more armor skills to search for",
 | 
						|
                        type=canonical_skill_name)
 | 
						|
 | 
						|
    return parser.parse_args(argv)
 | 
						|
 | 
						|
 | 
						|
def find_armors(args):
 | 
						|
    db = MHDB()
 | 
						|
 | 
						|
    skills = {}
 | 
						|
    skill_ids = [] # preserve arg order
 | 
						|
    decorations = {}
 | 
						|
 | 
						|
    skill_tree_names = []
 | 
						|
    skill_tree_id_map = {}
 | 
						|
    skill_trees = db.get_skill_trees()
 | 
						|
    for tree in skill_trees:
 | 
						|
        skill_tree_names.append(tree.name)
 | 
						|
        skill_tree_id_map[tree.name] = tree.id
 | 
						|
 | 
						|
    for i, skill_name in enumerate(args.skills):
 | 
						|
        sid = skill_tree_id_map.get(skill_name)
 | 
						|
        if sid is None:
 | 
						|
            matches = difflib.get_close_matches(skill_name, skill_tree_names,
 | 
						|
                                                1, 0.5)
 | 
						|
            if matches:
 | 
						|
                print("Fuzzy Match:", matches[0])
 | 
						|
                sid = skill_tree_id_map.get(matches[0])
 | 
						|
                skill_name = matches[0]
 | 
						|
                args.skills[i] = skill_name
 | 
						|
        if sid is None:
 | 
						|
            raise ValueError("Skill '%s' not found" % skill_name)
 | 
						|
        skills[skill_name] = sid
 | 
						|
        skill_ids.append(sid)
 | 
						|
        #print skill_name, sid
 | 
						|
        ds = db.get_decorations_by_skills([sid])
 | 
						|
        for d in ds:
 | 
						|
            d.set_skills(db.get_item_skills(d.id))
 | 
						|
        decoration_values = get_decoration_values(sid, ds)[1]
 | 
						|
        decorations[sid] = (ds, decoration_values)
 | 
						|
        print("%s[%s]:" % (skill_name, sid), ", ".join(d.name for d in ds), \
 | 
						|
              decoration_values)
 | 
						|
 | 
						|
    htype = "Gunner" if args.gunner else "Blade"
 | 
						|
 | 
						|
    armors = db.get_armors_by_skills(skill_ids, htype)
 | 
						|
 | 
						|
    skill_totals = {}
 | 
						|
    for a in armors:
 | 
						|
        skills = db.get_item_skills(a.id)
 | 
						|
        if not skills:
 | 
						|
            print("Error getting skills for '%s' (%d)" % (a.name, a.id))
 | 
						|
            sys.exit(1)
 | 
						|
        a.set_skills(skills)
 | 
						|
        # calculate total using decorations for first skill only. This
 | 
						|
        # works great if all skill have same slot values; if not it's
 | 
						|
        # very messy to figure out what is 'best'
 | 
						|
        total = 0
 | 
						|
        first = True
 | 
						|
        for sid in skill_ids:
 | 
						|
            if first:
 | 
						|
                dv = decorations[sid][1]
 | 
						|
                first = False
 | 
						|
            else:
 | 
						|
                dv = []
 | 
						|
            total += a.skill(sid, dv)
 | 
						|
        skill_totals[a.id] = total
 | 
						|
 | 
						|
    def sort_key(a):
 | 
						|
        if args.resist:
 | 
						|
            return (skill_totals[a.id], a[args.resist + "_res"], a.defense)
 | 
						|
        else:
 | 
						|
            return (skill_totals[a.id], a.defense)
 | 
						|
 | 
						|
    armors.sort(key=sort_key, reverse=True)
 | 
						|
 | 
						|
    for a in armors:
 | 
						|
        if args.min_defense and a.defense < args.min_defense:
 | 
						|
            continue
 | 
						|
        if args.type and a.slot != args.type:
 | 
						|
            continue
 | 
						|
        total = skill_totals[a.id]
 | 
						|
        print(skill_totals[a.id], a.one_line_u(), end=' ')
 | 
						|
        if args.resist:
 | 
						|
            print(args.resist.title(), a[args.resist + "_res"])
 | 
						|
        else:
 | 
						|
            print()
 | 
						|
        print("  ", a.one_line_skills_u(args.skills))
 | 
						|
 | 
						|
 | 
						|
def str_lower(x):
 | 
						|
    return str(x).lower()
 | 
						|
 | 
						|
 | 
						|
def str_title(x):
 | 
						|
    return str(x).title()
 | 
						|
 | 
						|
 | 
						|
_SKILL_NAME_SPECIAL = dict(
 | 
						|
    steadyhand="SteadyHand",
 | 
						|
    freeelemnt="FreeElemnt",
 | 
						|
    punishdraw="PunishDraw",
 | 
						|
    fastcharge="FastCharge",
 | 
						|
    ko="KO",
 | 
						|
    lastingpwr="LastingPwr",
 | 
						|
    thunderatk="ThunderAtk",
 | 
						|
    thunderres="ThunderRes",
 | 
						|
    teamplayer="TeamPlayer",
 | 
						|
    teamleader="TeamLeader",
 | 
						|
    speedsetup="SpeedSetup",
 | 
						|
    critelemnt="CritElement",
 | 
						|
    critstatus="CritStatus",
 | 
						|
    lighteater="LightEater",
 | 
						|
    powereater="PowerEater"
 | 
						|
)
 | 
						|
 | 
						|
def canonical_skill_name(skill_name):
 | 
						|
    skill_name_lc = skill_name.lower()
 | 
						|
    skill_name_lc_nospace = "".join(skill_name_lc.split(" "))
 | 
						|
    if skill_name_lc_nospace in _SKILL_NAME_SPECIAL:
 | 
						|
        return _SKILL_NAME_SPECIAL[skill_name_lc_nospace]
 | 
						|
    else:
 | 
						|
        return skill_name_lc.title()
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    args = parse_args(None)
 | 
						|
 | 
						|
    sys.stdout = get_utf8_writer(sys.stdout)
 | 
						|
    find_armors(args)
 |