fix cross game compat, quest filter

main
Bryce Allen 9 years ago
parent 912ea1f6ce
commit 3a2eba00e7

@ -38,7 +38,7 @@ def parse_args(argv):
def find_armors(args): def find_armors(args):
db = MHDB(_pathfix.db_path) db = MHDB()
skills = {} skills = {}
skill_ids = [] # preserve arg order skill_ids = [] # preserve arg order
@ -113,7 +113,7 @@ def find_armors(args):
if args.type and a.slot != args.type: if args.type and a.slot != args.type:
continue continue
total = skill_totals[a.id] 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: if args.resist:
print args.resist.title(), a[args.resist + "_res"] print args.resist.title(), a[args.resist + "_res"]
else: else:

@ -9,7 +9,7 @@ import _pathfix
from mhapi.db import MHDB, MHDBX from mhapi.db import MHDB, MHDBX
from mhapi.damage import MotionValueDB, WeaponMonsterDamage 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 import skills
from mhapi.util import ELEMENTS, WEAPON_TYPES, WTYPE_ABBR from mhapi.util import ELEMENTS, WEAPON_TYPES, WTYPE_ABBR
@ -30,6 +30,25 @@ def weapon_match_tuple(arg):
return (wtype, element) 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): def _make_db_sharpness_string(level_string):
#print "level string", level_string #print "level string", level_string
level_value = SharpnessLevel.__dict__[level_string.upper()] level_value = SharpnessLevel.__dict__[level_string.upper()]
@ -199,6 +218,9 @@ def parse_args(argv):
+" Examples: 'DinoSnS,SnS,190,0,Blue,Fire,30'" +" Examples: 'DinoSnS,SnS,190,0,Blue,Fire,30'"
+" 'AkantorHam,Hammer,240,25,Green'", +" 'AkantorHam,Hammer,240,25,Green'",
type=weapon_stats_tuple, default=[]) type=weapon_stats_tuple, default=[])
parser.add_argument("-q", "--quest-level",
help="village,guild[,permit[,arena]]",
type=quest_level_tuple)
parser.add_argument("monster", parser.add_argument("monster",
help="Full name of monster") help="Full name of monster")
parser.add_argument("weapon", nargs="*", 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) 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) args = parse_args(None)
game_uses_true_raw = False game_uses_true_raw = False
@ -332,7 +367,11 @@ if __name__ == '__main__':
db = MHDBX() db = MHDBX()
game_uses_true_raw = True game_uses_true_raw = True
elif args.monster_hunter_gen: 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 game_uses_true_raw = True
else: else:
db = MHDB(game="4u") db = MHDB(game="4u")
@ -362,8 +401,12 @@ if __name__ == '__main__':
for match_tuple in args.match: for match_tuple in args.match:
# TODO: better validation # TODO: better validation
wtype, element = match_tuple wtype, element = match_tuple
if args.quest_level:
final=None
else:
final=1
match_weapons = db.get_weapons_by_query(wtype=wtype, element=element, match_weapons = db.get_weapons_by_query(wtype=wtype, element=element,
final=1) final=final)
for w in match_weapons: for w in match_weapons:
# skip weapons already explicitly names in arg list. # skip weapons already explicitly names in arg list.
# Especially useful in diff mode. # Especially useful in diff mode.
@ -398,12 +441,34 @@ if __name__ == '__main__':
else: else:
limit_parts = None 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() weapon_damage_map = dict()
for row in weapons: for row in weapons:
name = row["name"] name = row["name"]
row_type = row["wtype"] row_type = row["wtype"]
if row_type != weapon_type: 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: try:
skill_args = skill_args_map.get(name, args) skill_args = skill_args_map.get(name, args)
wd = WeaponMonsterDamage(row, wd = WeaponMonsterDamage(row,
@ -456,3 +521,6 @@ if __name__ == '__main__':
print_sorted_damage(names, damage_map_base, print_sorted_damage(names, damage_map_base,
weapon_damage_map, parts) weapon_damage_map, parts)
if __name__ == '__main__':
main()

Binary file not shown.

@ -214,7 +214,7 @@ class WeaponMonsterDamage(object):
self.sharpness = self.weapon.sharpness.max self.sharpness = self.weapon.sharpness.max
#print "sharpness=", self.sharpness #print "sharpness=", self.sharpness
if self.weapon["affinity"]: if self.weapon["affinity"]:
if (isinstance(self.weapon["affinity"], str) if (isinstance(self.weapon["affinity"], basestring)
and "/" in self.weapon["affinity"]): and "/" in self.weapon["affinity"]):
self.chaotic = True self.chaotic = True
# Handle chaotic gore affinity, e.g. -35/10. This means that # Handle chaotic gore affinity, e.g. -35/10. This means that

@ -25,6 +25,13 @@ def _db_path(game=None):
return os.path.join(project_path, "db", "mh%s.db" % game) return os.path.join(project_path, "db", "mh%s.db" % game)
ARMOR_HUNTER_TYPES = {
"Blade": 0,
"Gunner": 1,
"Both": 2,
}
class MHDB(object): class MHDB(object):
""" """
Wrapper around the Android App sqlite3 db. The following conventions 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 # buy and sell are empty, uses weapon.create_cost and upgrade_cost
_weapon_select = """ _weapon_select = """
SELECT items._id, items.type, items.name, SELECT items.*, weapons.*
items.rarity, weapons.*
FROM weapons FROM weapons
LEFT JOIN items ON weapons._id = items._id LEFT JOIN items ON weapons._id = items._id
""" """
@ -74,6 +80,16 @@ class MHDB(object):
game = os.environ.get("MHAPI_GAME") game = os.environ.get("MHAPI_GAME")
assert game in ("4u", "gen") assert game in ("4u", "gen")
self.game = game 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: if path is None:
path = _db_path(game) path = _db_path(game)
self.conn = sqlite3.connect(path) self.conn = sqlite3.connect(path)
@ -341,7 +357,7 @@ class MHDB(object):
def get_weapons(self): def get_weapons(self):
# Note: weapons only available via JP DLC have no localized # Note: weapons only available via JP DLC have no localized
# name, filter them out. # name, filter them out.
q = MHDB._weapon_select q = self._weapon_select
return self._query_all("weapons", q, model_cls=model.Weapon) return self._query_all("weapons", q, model_cls=model.Weapon)
def get_weapons_by_query(self, wtype=None, element=None, def get_weapons_by_query(self, wtype=None, element=None,
@ -353,7 +369,7 @@ class MHDB(object):
@final should be string '1' or '0' @final should be string '1' or '0'
""" """
q = MHDB._weapon_select q = self._weapon_select
where = [] where = []
args = [] args = []
if wtype is not None: if wtype is not None:
@ -369,24 +385,24 @@ class MHDB(object):
where.append("final = ?") where.append("final = ?")
args.append(final) args.append(final)
if where: if where:
q += "WHERE " + "\nAND ".join(where) q += "AND " + "\nAND ".join(where)
results = self._query_all("weapons", q, tuple(args), results = self._query_all("weapons", q, tuple(args),
model_cls=model.Weapon) model_cls=model.Weapon)
return results return results
def get_weapon(self, weapon_id): def get_weapon(self, weapon_id):
return self._query_one("weapon", MHDB._weapon_select + """ return self._query_one("weapon", self._weapon_select + """
WHERE weapons._id=? AND weapons._id=?
""", (weapon_id,), model_cls=model.Weapon) """, (weapon_id,), model_cls=model.Weapon)
def get_weapon_by_name(self, name): def get_weapon_by_name(self, name):
return self._query_one("weapon", MHDB._weapon_select + """ return self._query_one("weapon", self._weapon_select + """
WHERE items.name=? AND items.name=?
""", (name,), model_cls=model.Weapon) """, (name,), model_cls=model.Weapon)
def get_weapons_by_parent(self, parent_id): def get_weapons_by_parent(self, parent_id):
return self._query_all("weapon_by_parent", MHDB._weapon_select + """ return self._query_all("weapon_by_parent", self._weapon_select + """
WHERE weapons.parent_id=? AND weapons.parent_id=?
""", (parent_id,), model_cls=model.Weapon) """, (parent_id,), model_cls=model.Weapon)
def get_armors(self): def get_armors(self):
@ -467,7 +483,11 @@ class MHDB(object):
def get_armors_by_skills(self, skill_tree_ids, hunter_type): def get_armors_by_skills(self, skill_tree_ids, hunter_type):
args = sorted(skill_tree_ids) args = sorted(skill_tree_ids)
placeholders = ", ".join(["?"] * len(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", """ return self._query_all("decorations", """
SELECT items._id, items.type, items.name, items.rarity, items.buy, SELECT items._id, items.type, items.name, items.rarity, items.buy,
armor.* armor.*
@ -479,7 +499,7 @@ class MHDB(object):
WHERE items.type = 'Armor' WHERE items.type = 'Armor'
AND item_to_skill_tree.skill_tree_id IN (%s) AND item_to_skill_tree.skill_tree_id IN (%s)
AND item_to_skill_tree.point_value > 0 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 GROUP BY item_to_skill_tree.item_id
""" % placeholders, tuple(args), model_cls=model.Armor) """ % placeholders, tuple(args), model_cls=model.Armor)

@ -85,7 +85,7 @@ class RowModel(ModelBase):
data[key_value].append(item) data[key_value].append(item)
def __str__(self): 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=" ") name = urllib.quote(self.name, safe=" ")
else: else:
name = str(self.id) name = str(self.id)

Loading…
Cancel
Save