fix cross game compat, quest filter
This commit is contained in:
@@ -38,7 +38,7 @@ def parse_args(argv):
|
||||
|
||||
|
||||
def find_armors(args):
|
||||
db = MHDB(_pathfix.db_path)
|
||||
db = MHDB()
|
||||
|
||||
skills = {}
|
||||
skill_ids = [] # preserve arg order
|
||||
@@ -113,7 +113,7 @@ def find_armors(args):
|
||||
if args.type and a.slot != args.type:
|
||||
continue
|
||||
total = skill_totals[a.id]
|
||||
print a.id, skill_totals[a.id], a.one_line_u(),
|
||||
print skill_totals[a.id], a.one_line_u(),
|
||||
if args.resist:
|
||||
print args.resist.title(), a[args.resist + "_res"]
|
||||
else:
|
||||
|
||||
@@ -9,7 +9,7 @@ import _pathfix
|
||||
|
||||
from mhapi.db import MHDB, MHDBX
|
||||
from mhapi.damage import MotionValueDB, WeaponMonsterDamage
|
||||
from mhapi.model import SharpnessLevel, Weapon
|
||||
from mhapi.model import SharpnessLevel, Weapon, ItemStars
|
||||
from mhapi import skills
|
||||
from mhapi.util import ELEMENTS, WEAPON_TYPES, WTYPE_ABBR
|
||||
|
||||
@@ -30,6 +30,25 @@ def weapon_match_tuple(arg):
|
||||
return (wtype, element)
|
||||
|
||||
|
||||
ANY = object()
|
||||
def parse_stars(arg):
|
||||
if arg is None:
|
||||
return None
|
||||
arg = arg.lower()
|
||||
if arg in ("*", "any"):
|
||||
return ANY
|
||||
if arg in ("none", ""):
|
||||
return None
|
||||
return int(arg)
|
||||
|
||||
|
||||
def quest_level_tuple(arg):
|
||||
parts = arg.split(",")
|
||||
while len(parts) < 4:
|
||||
parts.append(None)
|
||||
return [parse_stars(p) for p in parts]
|
||||
|
||||
|
||||
def _make_db_sharpness_string(level_string):
|
||||
#print "level string", level_string
|
||||
level_value = SharpnessLevel.__dict__[level_string.upper()]
|
||||
@@ -199,6 +218,9 @@ def parse_args(argv):
|
||||
+" Examples: 'DinoSnS,SnS,190,0,Blue,Fire,30'"
|
||||
+" 'AkantorHam,Hammer,240,25,Green'",
|
||||
type=weapon_stats_tuple, default=[])
|
||||
parser.add_argument("-q", "--quest-level",
|
||||
help="village,guild[,permit[,arena]]",
|
||||
type=quest_level_tuple)
|
||||
parser.add_argument("monster",
|
||||
help="Full name of monster")
|
||||
parser.add_argument("weapon", nargs="*",
|
||||
@@ -324,7 +346,20 @@ def print_damage_percent_diff(names, damage_map_base, weapon_damage_map, parts):
|
||||
print "%22s %0.2f (%s)" % (avg_type, base, diff_s)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def match_quest_level(match_level, weapon_level):
|
||||
#print match_level, weapon_level
|
||||
if match_level is ANY:
|
||||
return True
|
||||
if match_level is None:
|
||||
if weapon_level is not None:
|
||||
return False
|
||||
return True
|
||||
if weapon_level is None or weapon_level > match_level:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args(None)
|
||||
|
||||
game_uses_true_raw = False
|
||||
@@ -332,7 +367,11 @@ if __name__ == '__main__':
|
||||
db = MHDBX()
|
||||
game_uses_true_raw = True
|
||||
elif args.monster_hunter_gen:
|
||||
db = MHDB(game="gen")
|
||||
if args.quest_level:
|
||||
comps = True
|
||||
else:
|
||||
comps = False
|
||||
db = MHDB(game="gen", include_item_components=comps)
|
||||
game_uses_true_raw = True
|
||||
else:
|
||||
db = MHDB(game="4u")
|
||||
@@ -362,8 +401,12 @@ if __name__ == '__main__':
|
||||
for match_tuple in args.match:
|
||||
# TODO: better validation
|
||||
wtype, element = match_tuple
|
||||
if args.quest_level:
|
||||
final=None
|
||||
else:
|
||||
final=1
|
||||
match_weapons = db.get_weapons_by_query(wtype=wtype, element=element,
|
||||
final=1)
|
||||
final=final)
|
||||
for w in match_weapons:
|
||||
# skip weapons already explicitly names in arg list.
|
||||
# Especially useful in diff mode.
|
||||
@@ -398,12 +441,34 @@ if __name__ == '__main__':
|
||||
else:
|
||||
limit_parts = None
|
||||
|
||||
if args.quest_level:
|
||||
village, guild, permit, arena = args.quest_level
|
||||
print "Filter by Quest Levels:", args.quest_level
|
||||
weapons2 = dict()
|
||||
for w in weapons:
|
||||
if (not match_quest_level(village, w["village_stars"])
|
||||
and not match_quest_level(guild, w["guild_stars"])):
|
||||
continue
|
||||
if not match_quest_level(permit, w["permit_stars"]):
|
||||
continue
|
||||
if not match_quest_level(arena, w["arena_stars"]):
|
||||
continue
|
||||
weapons2[w.id] = w
|
||||
parent_ids = set(w.parent_id for w in weapons2.values())
|
||||
for wid in weapons2.keys():
|
||||
if wid in parent_ids:
|
||||
del weapons2[wid]
|
||||
weapons = weapons2.values()
|
||||
names = [w.name for w in weapons]
|
||||
|
||||
weapon_damage_map = dict()
|
||||
for row in weapons:
|
||||
name = row["name"]
|
||||
row_type = row["wtype"]
|
||||
if row_type != weapon_type:
|
||||
raise ValueError("Weapon '%s' is different type" % name)
|
||||
raise ValueError(
|
||||
"Weapon '%s' is different type, got '%s' expected '%s'"
|
||||
% (name, row_type, weapon_type))
|
||||
try:
|
||||
skill_args = skill_args_map.get(name, args)
|
||||
wd = WeaponMonsterDamage(row,
|
||||
@@ -456,3 +521,6 @@ if __name__ == '__main__':
|
||||
print_sorted_damage(names, damage_map_base,
|
||||
weapon_damage_map, parts)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
BIN
db/mhgen.db
BIN
db/mhgen.db
Binary file not shown.
@@ -214,7 +214,7 @@ class WeaponMonsterDamage(object):
|
||||
self.sharpness = self.weapon.sharpness.max
|
||||
#print "sharpness=", self.sharpness
|
||||
if self.weapon["affinity"]:
|
||||
if (isinstance(self.weapon["affinity"], str)
|
||||
if (isinstance(self.weapon["affinity"], basestring)
|
||||
and "/" in self.weapon["affinity"]):
|
||||
self.chaotic = True
|
||||
# Handle chaotic gore affinity, e.g. -35/10. This means that
|
||||
|
||||
46
mhapi/db.py
46
mhapi/db.py
@@ -25,6 +25,13 @@ def _db_path(game=None):
|
||||
return os.path.join(project_path, "db", "mh%s.db" % game)
|
||||
|
||||
|
||||
ARMOR_HUNTER_TYPES = {
|
||||
"Blade": 0,
|
||||
"Gunner": 1,
|
||||
"Both": 2,
|
||||
}
|
||||
|
||||
|
||||
class MHDB(object):
|
||||
"""
|
||||
Wrapper around the Android App sqlite3 db. The following conventions
|
||||
@@ -38,8 +45,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.rarity, weapons.*
|
||||
SELECT items.*, weapons.*
|
||||
FROM weapons
|
||||
LEFT JOIN items ON weapons._id = items._id
|
||||
"""
|
||||
@@ -74,6 +80,16 @@ class MHDB(object):
|
||||
game = os.environ.get("MHAPI_GAME")
|
||||
assert game in ("4u", "gen")
|
||||
self.game = game
|
||||
|
||||
if game == "4u":
|
||||
# filter out non-localized DLC
|
||||
self._weapon_select = (MHDB._weapon_select
|
||||
+ "WHERE items.name != items.name_jp\n")
|
||||
else:
|
||||
# no filter needed, but having where in all cases simplifies
|
||||
# queries below
|
||||
self._weapon_select = (MHDB._weapon_select
|
||||
+ "WHERE 1=1\n")
|
||||
if path is None:
|
||||
path = _db_path(game)
|
||||
self.conn = sqlite3.connect(path)
|
||||
@@ -341,7 +357,7 @@ class MHDB(object):
|
||||
def get_weapons(self):
|
||||
# Note: weapons only available via JP DLC have no localized
|
||||
# name, filter them out.
|
||||
q = MHDB._weapon_select
|
||||
q = self._weapon_select
|
||||
return self._query_all("weapons", q, model_cls=model.Weapon)
|
||||
|
||||
def get_weapons_by_query(self, wtype=None, element=None,
|
||||
@@ -353,7 +369,7 @@ class MHDB(object):
|
||||
|
||||
@final should be string '1' or '0'
|
||||
"""
|
||||
q = MHDB._weapon_select
|
||||
q = self._weapon_select
|
||||
where = []
|
||||
args = []
|
||||
if wtype is not None:
|
||||
@@ -369,24 +385,24 @@ class MHDB(object):
|
||||
where.append("final = ?")
|
||||
args.append(final)
|
||||
if where:
|
||||
q += "WHERE " + "\nAND ".join(where)
|
||||
q += "AND " + "\nAND ".join(where)
|
||||
results = self._query_all("weapons", q, tuple(args),
|
||||
model_cls=model.Weapon)
|
||||
return results
|
||||
|
||||
def get_weapon(self, weapon_id):
|
||||
return self._query_one("weapon", MHDB._weapon_select + """
|
||||
WHERE weapons._id=?
|
||||
return self._query_one("weapon", self._weapon_select + """
|
||||
AND weapons._id=?
|
||||
""", (weapon_id,), model_cls=model.Weapon)
|
||||
|
||||
def get_weapon_by_name(self, name):
|
||||
return self._query_one("weapon", MHDB._weapon_select + """
|
||||
WHERE items.name=?
|
||||
return self._query_one("weapon", self._weapon_select + """
|
||||
AND items.name=?
|
||||
""", (name,), model_cls=model.Weapon)
|
||||
|
||||
def get_weapons_by_parent(self, parent_id):
|
||||
return self._query_all("weapon_by_parent", MHDB._weapon_select + """
|
||||
WHERE weapons.parent_id=?
|
||||
return self._query_all("weapon_by_parent", self._weapon_select + """
|
||||
AND weapons.parent_id=?
|
||||
""", (parent_id,), model_cls=model.Weapon)
|
||||
|
||||
def get_armors(self):
|
||||
@@ -467,7 +483,11 @@ class MHDB(object):
|
||||
def get_armors_by_skills(self, skill_tree_ids, hunter_type):
|
||||
args = sorted(skill_tree_ids)
|
||||
placeholders = ", ".join(["?"] * len(skill_tree_ids))
|
||||
args += [hunter_type]
|
||||
both_type = "Both"
|
||||
if self.game == "gen":
|
||||
both_type = ARMOR_HUNTER_TYPES[both_type]
|
||||
hunter_type = ARMOR_HUNTER_TYPES[hunter_type]
|
||||
args += [both_type, hunter_type]
|
||||
return self._query_all("decorations", """
|
||||
SELECT items._id, items.type, items.name, items.rarity, items.buy,
|
||||
armor.*
|
||||
@@ -479,7 +499,7 @@ class MHDB(object):
|
||||
WHERE items.type = 'Armor'
|
||||
AND item_to_skill_tree.skill_tree_id IN (%s)
|
||||
AND item_to_skill_tree.point_value > 0
|
||||
AND armor.hunter_type IN ('Both', ?)
|
||||
AND armor.hunter_type IN (?, ?)
|
||||
GROUP BY item_to_skill_tree.item_id
|
||||
""" % placeholders, tuple(args), model_cls=model.Armor)
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ class RowModel(ModelBase):
|
||||
data[key_value].append(item)
|
||||
|
||||
def __str__(self):
|
||||
if "name" in self._data:
|
||||
if "name" in self._data and self.name is not None:
|
||||
name = urllib.quote(self.name, safe=" ")
|
||||
else:
|
||||
name = str(self.id)
|
||||
|
||||
Reference in New Issue
Block a user