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):
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()

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

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

Loading…
Cancel
Save