diff --git a/bin/weapon_level.py b/bin/weapon_level.py new file mode 100755 index 0000000..23283d9 --- /dev/null +++ b/bin/weapon_level.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python2 + +import sys + +import _pathfix + +from mhapi.db import MHDB, MHDBX +from mhapi.model import get_costs + + +def find_cost_level(db, c): + monsters = { "HR": set(), "LR": set() } + materials = { "HR": set(), "LR": set() } + stars = dict(Village=None, Guild=None, Permit=None, Arena=None) + for item in c["components"].keys(): + if item.startswith("HR ") or item.startswith("LR "): + if not item.endswith(" Materials"): + print "Error: bad item format '%s'" % item + rank = item[:2] + item = item[len("HR "):-len(" Materials")] + monster = db.get_monster_by_name(item) + if monster: + monsters[rank].add(monster) + #print "Monster", rank, monster.name, monster.id + else: + materials[rank].add(item) + #print "Material", rank, item + else: + data = db.get_item_by_name(item) + current_stars = find_item_level(db, data.id) + # keep track of most 'expensive' item + for k, v in current_stars.iteritems(): + if v is None: + continue + if stars[k] is None or v > stars[k]: + stars[k] = v + return stars + + +def find_item_level(db, item_id): + stars = dict(Village=None, Guild=None, Permit=None, Arena=None) + + quests = db.get_item_quests(item_id) + + gathering = db.get_item_gathering(item_id) + gather_locations = set() + for gather in gathering: + gather_locations.add((gather["location_id"], gather["rank"])) + for location_id, rank in list(gather_locations): + gather_quests = db.get_location_quests(location_id, rank) + quests.extend(gather_quests) + + monsters = db.get_item_monsters(item_id) + monster_ranks = set() + for monster in monsters: + monster_ranks.add((monster["monster_id"], monster["rank"])) + for monster_id, rank in list(monster_ranks): + monster_quests = db.get_monster_quests(monster_id, rank) + quests.extend(monster_quests) + + # find least expensive quest for getting the item + for quest in quests: + if quest.stars == 0: + # ignore training quests + if "Training" not in quest.name: + print "Error: non training quest has 0 stars", \ + quest.id, quest.name + continue + if quest.hub in stars: + current = stars[quest.hub] + if current is None or quest.stars < current: + stars[quest.hub] = quest.stars + else: + print "Error: unknown hub", quest.hub + + return stars + + +def main(): + weapon_name = sys.argv[1] + db = MHDB(game="gen", include_item_components=True) + weapon = db.get_weapon_by_name(weapon_name) + if weapon is None: + print "Weapon '%s' not found" % weapon_name + sys.exit(1) + + costs = get_costs(db, weapon) + stars = dict(Village=None, Guild=None, Permit=None, Arena=None) + # find least 'expensive' path + for c in costs: + current_stars = find_cost_level(db, c) + for k, v in current_stars.iteritems(): + if v is None: + continue + if stars[k] is None or v < stars[k]: + stars[k] = v + for k, v in stars.iteritems(): + print k, v + + +if __name__ == '__main__': + main() diff --git a/mhapi/db.py b/mhapi/db.py index dcbe447..2866ead 100644 --- a/mhapi/db.py +++ b/mhapi/db.py @@ -38,7 +38,7 @@ class MHDB(object): """ # buy and sell are empty, uses weapon.create_cost and upgrade_cost _weapon_select = """ - SELECT items._id, items.type, items.name, items.name_jp, + SELECT items._id, items.type, items.name, items.rarity, weapons.* FROM weapons LEFT JOIN items ON weapons._id = items._id @@ -265,10 +265,17 @@ class MHDB(object): WHERE quest_id=? """, (quest_id,)) + def get_monster_quests(self, monster_id, rank): + return self._query_all("monster_quests", """ + SELECT DISTINCT quests.* FROM quests, monster_to_quest + WHERE monster_to_quest.quest_id = quests._id + AND monster_to_quest.monster_id=? AND rank=? + """, (monster_id, rank), model_cls=model.Quest) + def get_item_quests(self, item_id): """ Get a list of quests that provide the specified item in quest - reqards. Returns a list of quest objects, which encapsulate the + rewards. Returns a list of quest objects, which encapsulate the quest details and the list of rewards. """ cursor = self.conn.execute(""" @@ -310,6 +317,12 @@ class MHDB(object): SELECT * FROM locations """, model_cls=model.Location) + def get_location_quests(self, location_id, rank): + return self._query_all("location_quests", """ + SELECT DISTINCT * FROM quests + WHERE location_id=? AND rank=? + """, (location_id, rank), model_cls=model.Quest) + def get_monster_damage(self, monster_id): return self._query_all("monster_damage", """ SELECT * FROM monster_damage @@ -320,8 +333,6 @@ class MHDB(object): # Note: weapons only available via JP DLC have no localized # name, filter them out. q = MHDB._weapon_select - if self.game == "4u": - q += "\nWHERE items.name != items.name_jp", return self._query_all("weapons", q, model_cls=model.Weapon) def get_weapons_by_query(self, wtype=None, element=None, @@ -334,11 +345,7 @@ class MHDB(object): @final should be string '1' or '0' """ q = MHDB._weapon_select - if self.game == "4u": - # filter out non-localized japanese DLC - where = ["items.name != items.name_jp"] - else: - where = [] + where = [] args = [] if wtype is not None: where.append("wtype = ?")