break improvements

main
Bryce Allen 11 years ago
parent 7b5e8c9dd8
commit b96bed0bc4

@ -43,6 +43,7 @@ def monster_json(db, path):
m.update_indexes(indexes) m.update_indexes(indexes)
data = m.as_data() data = m.as_data()
damage = db.get_monster_damage(m.id) damage = db.get_monster_damage(m.id)
damage.set_breakable(db.get_monster_breaks(m.id))
data["damage"] = damage.as_data() data["damage"] = damage.as_data()
with open(monster_path, "w") as f: with open(monster_path, "w") as f:
json.dump(data, f, cls=model.ModelJSONEncoder, indent=2) json.dump(data, f, cls=model.ModelJSONEncoder, indent=2)

@ -5,7 +5,7 @@ import difflib
import re import re
from mhapi import skills from mhapi import skills
from mhapi.model import SharpnessLevel from mhapi.model import SharpnessLevel, _break_find
WEAKPART_WEIGHT = 0.5 WEAKPART_WEIGHT = 0.5
@ -160,7 +160,7 @@ class WeaponMonsterDamage(object):
Class for calculating how much damage a weapon does to a monster. Class for calculating how much damage a weapon does to a monster.
Does not include overall monster defense. Does not include overall monster defense.
""" """
def __init__(self, weapon_row, monster_row, monster_damage_rows, motion, def __init__(self, weapon_row, monster_row, monster_damage, motion,
sharp_plus=False, breakable_parts=None, sharp_plus=False, breakable_parts=None,
attack_skill=skills.AttackUp.NONE, attack_skill=skills.AttackUp.NONE,
critical_eye_skill=skills.CriticalEye.NONE, critical_eye_skill=skills.CriticalEye.NONE,
@ -168,7 +168,7 @@ class WeaponMonsterDamage(object):
awaken=False): awaken=False):
self.weapon = weapon_row self.weapon = weapon_row
self.monster = monster_row self.monster = monster_row
self.monster_damage = monster_damage_rows self.monster_damage = monster_damage
self.motion = motion self.motion = motion
self.sharp_plus = sharp_plus self.sharp_plus = sharp_plus
self.breakable_parts = breakable_parts self.breakable_parts = breakable_parts
@ -259,7 +259,8 @@ class WeaponMonsterDamage(object):
part_damage.part = part part_damage.part = part
if alt is None: if alt is None:
if (self.breakable_parts if (self.breakable_parts
and _part_find(part, self.breakable_parts)): and _break_find(part, self.monster_damage.parts.keys(),
self.breakable_parts)):
part_damage.breakable = True part_damage.breakable = True
if hitbox > self.max_raw_part[1]: if hitbox > self.max_raw_part[1]:
self.max_raw_part = (part, hitbox) self.max_raw_part = (part, hitbox)
@ -505,26 +506,6 @@ class PartDamage(object):
hitbox, ehitbox, state) hitbox, ehitbox, state)
def _part_find(part, breaks):
if (part == "Wing" and "Wing" not in breaks
and "Talon" in breaks):
# for Teostra
return "Talon"
if (part == "Head" and "Head" not in breaks
and "Horn" in breaks):
# for Fatalis
return "Horn"
if (part == "Winglegs" and "Winglegs" not in breaks
and "Wing Leg" in breaks):
# for Gore
return "Wing Leg"
#print "part_find", part, breaks
matches = difflib.get_close_matches(part, breaks, 1, 0.8)
if matches:
return matches[0]
return None
def element_attack_up(value): def element_attack_up(value):
return value * 1.1 return value * 1.1

@ -309,9 +309,14 @@ class MHDB(object):
List of strings. List of strings.
""" """
def model(row): def model(row):
return row["condition"][len("Break "):] condition = row["condition"]
if condition == "Tail Carve":
return "Tail"
else:
return condition[len("Break "):]
return self._query_all("monster_breaks", """ return self._query_all("monster_breaks", """
SELECT DISTINCT condition FROM hunting_rewards SELECT DISTINCT condition FROM hunting_rewards
WHERE monster_id=? AND condition LIKE 'Break %' WHERE monster_id=?
AND (condition LIKE 'Break %' OR condition = 'Tail Carve')
""", (monster_id,), model_cls=model) """, (monster_id,), model_cls=model)

@ -3,6 +3,7 @@ import json
import urllib import urllib
from collections import defaultdict from collections import defaultdict
import re import re
import difflib
from mhapi.util import EnumBase from mhapi.util import EnumBase
@ -242,6 +243,11 @@ class MonsterPartStateDamage(RowModel):
self._data["part"] = part self._data["part"] = part
self._data["state"] = state self._data["state"] = state
def __eq__(self, other):
for col in "impact cut shot ko ice dragon water fire thunder".split():
if self[col] != other[col]:
return False
class MonsterPartDamage(ModelBase): class MonsterPartDamage(ModelBase):
""" """
@ -250,14 +256,30 @@ class MonsterPartDamage(ModelBase):
""" """
def __init__(self, part): def __init__(self, part):
self.part = part self.part = part
self.breakable = False
self.states = {} self.states = {}
def add_state(self, state, damage_row): def add_state(self, state, damage_row):
self.states[state] = MonsterPartStateDamage(self.part, state, self.states[state] = MonsterPartStateDamage(self.part, state,
damage_row) damage_row)
# TODO: what about state 'Without Hide' for S.Nerscylla, which
# appears like it might be the same as Break Part, or might
# affect across hitzones.
if state == "Break Part":
# the default damage should be sorted before the alternate
# state damage
assert "Default" in self.states
if self.states[state] != self.states["Default"]:
# if the damage is different for break state, the part
# must be breakable, even if we couldn't find a match
# when searching break rewards
self.breakable = True
def as_data(self): def as_data(self):
return self.states return dict(
breakable=self.breakable,
damage=self.states
)
class MonsterDamage(ModelBase): class MonsterDamage(ModelBase):
@ -270,8 +292,11 @@ class MonsterDamage(ModelBase):
self.parts = {} self.parts = {}
self.states = set() self.states = set()
for row in damage_rows: for row in damage_rows:
if row["cut"] == -1:
# -1 indicates missing data
continue
part = row["body_part"] part = row["body_part"]
state = "Normal" state = "Default"
m = re.match(r"([^(]+) \(([^)]+)\)", part) m = re.match(r"([^(]+) \(([^)]+)\)", part)
if m: if m:
part = m.group(1) part = m.group(1)
@ -286,3 +311,42 @@ class MonsterDamage(ModelBase):
states=list(self.states), states=list(self.states),
parts=self.parts parts=self.parts
) )
def set_breakable(self, breakable_list):
"""
Set breakable flag on parts based on the breakable list from
rewards (use MHDB.get_monster_breaks).
"""
for name, part_damage in self.parts.iteritems():
if _break_find(name, self.parts, breakable_list):
part_damage.breakable = True
def _break_find(part, parts, breaks):
# favor 'Tail Tip' over Tail for Basarios
if part == "Tail" and "Tail Tip" in parts:
return None
if part == "Tail Tip" and "Tail" in breaks:
return "Tail"
if part == "Neck/Tail" and "Tail" in breaks:
return "Tail"
if part == "Wing" and "Wing" not in breaks:
if "Talon" in breaks and "Talon" not in parts:
# for Teostra
return "Talon"
if part == "Head" and "Head" not in breaks:
if "Horn" in breaks and "Horn" not in parts:
# for Fatalis
return "Horn"
if "Ear" in breaks and "Ear" not in parts:
# Kecha Wacha
return "Ear"
if part == "Winglegs" and "Winglegs" not in breaks:
if "Wing Leg" in breaks and "Wing Leg" not in parts:
# for Gore
return "Wing Leg"
#print "part_find", part, breaks
matches = difflib.get_close_matches(part, breaks, 1, 0.8)
if matches:
return matches[0]
return None

Loading…
Cancel
Save