add top two weapon comparison based on ratio

main
Bryce Allen 9 years ago
parent 3a2eba00e7
commit 88ff0d15be

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

Loading…
Cancel
Save