add top two weapon comparison based on ratio
This commit is contained in:
@@ -186,6 +186,9 @@ def parse_args(argv):
|
||||
parser.add_argument("-p", "--parts",
|
||||
help="Limit analysis to specified parts"
|
||||
+" (comma separated list)")
|
||||
parser.add_argument("-o", "--motion", type=int,
|
||||
help="Use specified motion value instead of weapon "
|
||||
+"average")
|
||||
parser.add_argument("-l", "--phial",
|
||||
help="Show CB phial damage at the sepcified level"
|
||||
+" (1, 2, 3, 5=ultra) instead of normal motion"
|
||||
@@ -290,6 +293,24 @@ def print_sorted_damage(names, damage_map_base, weapon_damage_map, parts):
|
||||
print "% 2d" % part_damage.average(),
|
||||
print
|
||||
|
||||
if len(names) > 1:
|
||||
w1 = weapon_damage_map[names_sorted[0]]
|
||||
w2 = weapon_damage_map[names_sorted[1]]
|
||||
m, ratio = w1.compare_break_even(w2)
|
||||
print
|
||||
print "Comparison of '%s' and '%s'" % (
|
||||
names_sorted[0], names_sorted[1])
|
||||
print "Hitbox ratio:", m, "%0.2f" % ratio
|
||||
|
||||
for line in w1.get_raw_element_ratios():
|
||||
line = list(line)
|
||||
if m*line[3] > m*ratio:
|
||||
line.append(names_sorted[0])
|
||||
else:
|
||||
line.append(names_sorted[1])
|
||||
# (part, raw, element, ratio)
|
||||
print "%-22s %02d %02d %0.2f %s" % tuple(line)
|
||||
|
||||
|
||||
def print_damage_percent_diff(names, damage_map_base, weapon_damage_map, parts):
|
||||
for part in parts:
|
||||
@@ -432,6 +453,9 @@ def main():
|
||||
motion = motiondb[weapon_type].average
|
||||
print "Weapon Type: %s" % weapon_type
|
||||
print "Average Motion: %0.1f" % motion
|
||||
if args.motion:
|
||||
motion = args.motion
|
||||
print "Specified Motion: %0.1f" % motion
|
||||
print "Monster Breaks: %s" % ", ".join(monster_breaks)
|
||||
skill_names = get_skill_names(args)
|
||||
print "Common Skills:", ", ".join(skill for skill in skill_names if skill)
|
||||
|
||||
@@ -21,11 +21,19 @@ def raw_damage(true_raw, sharpness, affinity, monster_hitbox, motion):
|
||||
Calculate raw damage to a monster part with the given true raw,
|
||||
sharpness, monster raw weakness, and weapon motion value.
|
||||
"""
|
||||
return floor(true_raw
|
||||
return floor(raw_damage_nohitbox(true_raw, sharpness, affinity, motion)
|
||||
* monster_hitbox / 100.0)
|
||||
|
||||
|
||||
def raw_damage_nohitbox(true_raw, sharpness, affinity, motion):
|
||||
"""
|
||||
Calculate raw damage to a monster part with the given true raw,
|
||||
sharpness, monster raw weakness, and weapon motion value.
|
||||
"""
|
||||
return (true_raw
|
||||
* SharpnessLevel.raw_modifier(sharpness)
|
||||
* (1 + (affinity / 400.0))
|
||||
* motion / 100.0
|
||||
* monster_hitbox / 100.0)
|
||||
* motion / 100.0)
|
||||
|
||||
|
||||
def element_damage(raw_element, sharpness, monster_ehitbox):
|
||||
@@ -34,11 +42,19 @@ def element_damage(raw_element, sharpness, monster_ehitbox):
|
||||
attack, the given sharpness, and the given monster elemental weakness.
|
||||
Note that this is independent of the motion value of the attack.
|
||||
"""
|
||||
return floor(raw_element
|
||||
* SharpnessLevel.element_modifier(sharpness)
|
||||
return floor(element_damage_nohitbox(raw_element, sharpness)
|
||||
* monster_ehitbox / 100.0)
|
||||
|
||||
|
||||
def element_damage_nohitbox(raw_element, sharpness):
|
||||
"""
|
||||
Calculate elemental damage to a monster part with the given elemental
|
||||
attack, the given sharpness, and the given monster elemental weakness.
|
||||
Note that this is independent of the motion value of the attack.
|
||||
"""
|
||||
return (raw_element * SharpnessLevel.element_modifier(sharpness))
|
||||
|
||||
|
||||
class MotionType(object):
|
||||
CUT = "cut"
|
||||
IMPACT = "impact"
|
||||
@@ -506,6 +522,52 @@ class WeaponMonsterDamage(object):
|
||||
average += damage.total
|
||||
return average / self.break_count
|
||||
|
||||
def compare_break_even(self, other_wd, motion=None):
|
||||
"""
|
||||
Compare with another weapon damage, to determine the break even
|
||||
point of the raw/element hitbox. Assumes same element.
|
||||
|
||||
Returns (m, ratio), where ratio is the break even for the ratio of
|
||||
raw hitbox to element hitbox. If m is 1, then self is better
|
||||
when the ratio is larger (favors raw). If m is -1, then self is
|
||||
better when the ratio is smaller (favors element).
|
||||
"""
|
||||
r1, e1 = self.nohitbox_damage(motion)
|
||||
r2, e2 = other_wd.nohitbox_damage(motion)
|
||||
#print r1, e1
|
||||
#print r2, e2
|
||||
rdiff = r1 - r2
|
||||
ediff = e2 - e1
|
||||
m = 1
|
||||
if rdiff < 0:
|
||||
m = -1
|
||||
return m, (float(ediff) / rdiff)
|
||||
|
||||
def get_raw_element_ratios(self):
|
||||
# TODO: better MIXED handling
|
||||
if self.damage_type in (WeaponType.CUT, WeaponType.MIXED):
|
||||
raw_type = "cut"
|
||||
else:
|
||||
raw_type = "impact"
|
||||
hitboxes = []
|
||||
for row in self.monster_damage._rows:
|
||||
part = row["body_part"]
|
||||
hitbox = int(row[raw_type])
|
||||
ehitbox = int(row[str(self.etype.lower())])
|
||||
hitboxes.append((part, hitbox, ehitbox, float(hitbox) / ehitbox))
|
||||
return hitboxes
|
||||
|
||||
def nohitbox_damage(self, motion=None):
|
||||
"""
|
||||
Note: uses first element only, so not good for dual element DB.
|
||||
"""
|
||||
if motion is None:
|
||||
motion = self.motion
|
||||
raw = raw_damage_nohitbox(self.true_raw, self.sharpness,
|
||||
self.affinity, motion)
|
||||
element = element_damage_nohitbox(self.eattack, self.sharpness)
|
||||
return (raw, element)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.damage_map[key]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user