Permalink
Browse files

Merge git://github.com/dazer/ShadowCraft-Engine

Conflicts:
	scripts/mop_assassination_import.py
	scripts/mop_combat_import.py
	scripts/mop_subtlety_import.py
  • Loading branch information...
2 parents fc5bd81 + 7e9223b commit 65d1084e1751ad09f793c306b7d8a119e53881a0 @Aldriana committed Nov 3, 2012
@@ -342,7 +342,7 @@ def get_gear_stats(self):
#ilvl is included in the gear array for some unknown reason, lets ignore it
if p != 'averageItemLevelEquipped' and p != 'averageItemLevel':
tmpItem = get_item_cached(self.region, self.raw_data['data'][u'items'][p][u'id'])
- self.verbosePrint('\n' + p + ': ' + self.raw_data['data'][u'items'][p][u'name'])
+ self.verbose_print('\n' + p + ': ' + self.raw_data['data'][u'items'][p][u'name'])
params = self.raw_data['data'][u'items'][p][u'tooltipParams']
#grab the reforge if it exists
if u'reforge' in self.raw_data['data'][u'items'][p][u'tooltipParams']:
@@ -357,11 +357,11 @@ def get_gear_stats(self):
tmpVal = math.ceil(key[u'amount'] * .6)
lst[ CharacterData.statMap[key[u'stat']] ] += tmpVal
lst[ reforge[1] ] += key[u'amount'] - tmpVal
- self.verbosePrint('Reforge found: +' + str(tmpVal) + ' ' + reforge[0] + ', +' + str(key[u'amount'] - tmpVal) + ' ' + reforge[1])
+ self.verbose_print('Reforge found: +' + str(tmpVal) + ' ' + reforge[0] + ', +' + str(key[u'amount'] - tmpVal) + ' ' + reforge[1])
else:
#otherwise, no reforge
lst[ CharacterData.statMap[key[u'stat']] ] += key[u'amount']
- self.verbosePrint('+' + str(key[u'amount']) + ' ' + CharacterData.statMap[key[u'stat']])
+ self.verbose_print('+' + str(key[u'amount']) + ' ' + CharacterData.statMap[key[u'stat']])
#prevents cached reforges from affecting subsequent items
reforge = ('none', 'none')
#add stats from gems, check if socket colors are matched along the way
@@ -382,35 +382,35 @@ def get_gear_stats(self):
if gemNumber < len(sockets):
if not sockets[gemNumber][u'type'] in gemColorToSocketColors[tmpGem['data'][u'gemInfo'][u'type'][u'type']]:
socketBonusActivated = False
- self.verbosePrint(tmpGem['data'][u'name'] + ' does not match socket of color ' + sockets[gemNumber][u'type'] + ', socket bonus not activated!')
+ self.verbose_print(tmpGem['data'][u'name'] + ' does not match socket of color ' + sockets[gemNumber][u'type'] + ', socket bonus not activated!')
for entry in tmpGem['data'][u'gemInfo'][u'bonus'][u'name'].split(' and '):
tmpLst = entry.split(' ')
if not '%' in tmpLst[0]:
tmpVal = int(tmpLst[0][1:])
tmpStat = verboseStatMap[' '.join(tmpLst[1:])]
lst[tmpStat] += tmpVal
- self.verbosePrint(tmpGem['data'][u'name'] + ': +' + str(tmpVal) + ' ' + tmpStat)
+ self.verbose_print(tmpGem['data'][u'name'] + ': +' + str(tmpVal) + ' ' + tmpStat)
else:
self.chaotic_metagem = True
- self.verbosePrint(tmpGem['data'][u'name'] + ' is a meta gem')
+ self.verbose_print(tmpGem['data'][u'name'] + ' is a meta gem')
#add stats from socket bonuses
if socketBonusActivated == True and gemCount >= len(socketInfo[u'sockets']):
for entry in socketInfo[u'socketBonus'].split(' and '): #similar to gem treatment... is there ever a socket bonus that gives multiple stats?
tmpLst = entry.split(' ')
tmpVal = int(tmpLst[0][1:])
tmpStat = verboseStatMap[ ' '.join(tmpLst[1:]) ]
lst[ tmpStat ] += tmpVal
- self.verbosePrint('Socket bonus +' + str(tmpVal) + ' ' + tmpStat)
+ self.verbose_print('Socket bonus +' + str(tmpVal) + ' ' + tmpStat)
#add stats from enchants
if u'enchant' in params.keys():
if not type( CharacterData.enchants[ params[u'enchant'] ] ) == type(''):
for key in CharacterData.enchants[ params[u'enchant'] ]:
lst[ key['stat'] ] += key['value']
- self.verbosePrint('Enchant +' + str(key['value']) + ' ' + key['stat'])
+ self.verbose_print('Enchant +' + str(key['value']) + ' ' + key['stat'])
else:
- self.verbosePrint(CharacterData.enchants[params[u'enchant']])
+ self.verbose_print(CharacterData.enchants[params[u'enchant']])
else:
- self.verbosePrint('Unenchanted')
+ self.verbose_print('Unenchanted')
except Exception as inst:
#it's okay, we can keep going, just so long as we pretend to handle the exception
print "\n"
@@ -451,6 +451,6 @@ def get_glyphs(self):
glyphs.append(CharacterData.glyphs[glyph_name])
return glyphs
- def verbosePrint(self, str):
+ def verbose_print(self, str):
if self.verbose:
print str
@@ -69,14 +69,15 @@
test_procs = procs.ProcsList(*character_procs_allowed)
+# Set up a calcs object..
+lst = character_data.get_gear_stats()
+
# Set up gear buffs.
character_gear_buffs = character_data.get_gear_buffs() + ['leather_specialization', 'virmens_bite', 'virmens_bite_prepot']
if character_data.has_chaotic_metagem():
character_gear_buffs.append('chaotic_metagem')
test_gear_buffs = stats.GearBuffs(*character_gear_buffs)
-# Set up a calcs object..
-lst = character_data.get_gear_stats()
test_stats = stats.Stats(test_mh, test_oh, test_procs, test_gear_buffs, **lst)
# Initialize talents..
@@ -26,7 +26,10 @@
key = 1
while key < len(sys.argv):
terms = sys.argv[key].split(':')
- charInfo[ terms[0] ] = terms[1]
+ if terms[0] in ['stormlash', 'shiv']:
+ charInfo[ terms[0] ] = float(terms[1])
+ else:
+ charInfo[ terms[0] ] = terms[1]
key += 1
print "Loading " + charInfo['name'] + " of " + charInfo['region'] + "-" + charInfo['realm'] + "\n"
@@ -67,14 +70,15 @@
test_procs = procs.ProcsList(*character_procs_allowed)
+# Set up a calcs object..
+lst = character_data.get_gear_stats()
+
# Set up gear buffs.
character_gear_buffs = character_data.get_gear_buffs() + ['leather_specialization', 'virmens_bite', 'virmens_bite_prepot']
if character_data.has_chaotic_metagem():
character_gear_buffs.append('chaotic_metagem')
test_gear_buffs = stats.GearBuffs(*character_gear_buffs)
-# Set up a calcs object..
-lst = character_data.get_gear_stats()
test_stats = stats.Stats(test_mh, test_oh, test_procs, test_gear_buffs, **lst)
# Initialize talents..
@@ -67,14 +67,15 @@
test_procs = procs.ProcsList(*character_procs_allowed)
+# Set up a calcs object..
+lst = character_data.get_gear_stats()
+
# Set up gear buffs.
character_gear_buffs = character_data.get_gear_buffs() + ['leather_specialization', 'virmens_bite', 'virmens_bite_prepot']
if character_data.has_chaotic_metagem():
character_gear_buffs.append('chaotic_metagem')
test_gear_buffs = stats.GearBuffs(*character_gear_buffs)
-# Set up a calcs object..
-lst = character_data.get_gear_stats()
test_stats = stats.Stats(test_mh, test_oh, test_procs, test_gear_buffs, **lst)
# Initialize talents..
@@ -460,19 +460,20 @@ def get_damage_breakdown(self, current_stats, attacks_per_second, crit_rates, da
p_double_crit = crit_rates['killing_spree'] ** 2
munch_per_sec = attacks_per_second['mh_killing_spree'] * p_double_crit
damage_breakdown['ksp_munch'] = 0, munch_per_sec * mh_dmg[1]
-
+
+ finisher_per_second = {'envenom': 0, 'eviscerate': 0, 'rupture_ticks':0}
if 'rupture_ticks' in attacks_per_second:
average_dps = crit_dps = 0
for i in xrange(1, 6):
dps_tuple = self.get_dps_contribution(self.rupture_tick_damage(average_ap, i), crit_rates['rupture_ticks'], attacks_per_second['rupture_ticks'][i])
average_dps += dps_tuple[0]
crit_dps += dps_tuple[1]
+ finisher_per_second['rupture_ticks'] += attacks_per_second['rupture_ticks'][i]
damage_breakdown['rupture'] = average_dps, crit_dps
if 'garrote_ticks' in attacks_per_second:
damage_breakdown['garrote'] = self.get_dps_contribution(self.garrote_tick_damage(average_ap), crit_rates['garrote'], attacks_per_second['garrote_ticks'])
- finisher_per_second = {'envenom': 0, 'eviscerate': 0}
if 'envenom' in attacks_per_second:
average_dps = crit_dps = 0
for i in xrange(1, 6):
@@ -491,10 +492,15 @@ def get_damage_breakdown(self, current_stats, attacks_per_second, crit_rates, da
finisher_per_second['eviscerate'] += attacks_per_second['eviscerate'][i]
damage_breakdown['eviscerate'] = average_dps, crit_dps
+ if 'hemorrhage_ticks' in attacks_per_second:
+ dps_from_hit_hemo = self.get_dps_contribution(self.hemorrhage_tick_damage(average_ap, from_crit_hemo=False), crit_rates['hemorrhage'], attacks_per_second['hemorrhage_ticks'] * (1 - crit_rates['hemorrhage']))
+ dps_from_crit_hemo = self.get_dps_contribution(self.hemorrhage_tick_damage(average_ap, from_crit_hemo=True), crit_rates['hemorrhage'], attacks_per_second['hemorrhage_ticks'] * crit_rates['hemorrhage'])
+ damage_breakdown['hemorrhage_dot'] = dps_from_hit_hemo[0] + dps_from_crit_hemo[0], dps_from_hit_hemo[1] + dps_from_crit_hemo[1]
+
stormlash_mod_table = {'mh_autoattack_hits': .4 * (self.stats.mh.speed / 2.6),
'oh_autoattack_hits': .4 * (self.stats.mh.speed / 2.6) * .5,
- 'mh_shadow_blades': .4 * (self.stats.mh.speed / 2.6),
- 'oh_shadow_blades': .4 * (self.stats.mh.speed / 2.6) * .5,
+ 'mh_shadow_blade': .4 * (self.stats.mh.speed / 2.6),
+ 'oh_shadow_blade': .4 * (self.stats.mh.speed / 2.6) * .5,
'sinister_strike': .5}
if self.settings.use_stormlash:
@@ -503,23 +509,18 @@ def get_damage_breakdown(self, current_stats, attacks_per_second, crit_rates, da
average_dps = crit_dps = 0
uptime = int(self.settings.use_stormlash) * 10. / (5 * 60)
for value in attacks_per_second:
- if value in self.melee_hit_chance_attacks:
- damage_mod = 1
+ if value in self.all_attacks:
+ damage_mod = 1.
if value in stormlash_mod_table:
damage_mod = stormlash_mod_table[value]
- if value in ('envenom', 'eviscerate'):
+ if value in ('envenom', 'eviscerate', 'rupture_ticks'):
damage_tuple = self.get_dps_contribution(self.stormlash_totem_damage(average_ap, mod=damage_mod), self.spell_crit_rate(), finisher_per_second[value])
else:
damage_tuple = self.get_dps_contribution(self.stormlash_totem_damage(average_ap, mod=damage_mod), self.spell_crit_rate(), attacks_per_second[value])
average_dps += uptime * damage_tuple[0] * self.spell_hit_chance()
crit_dps += uptime * damage_tuple[1] * self.spell_hit_chance()
damage_breakdown['stormlash'] = average_dps, crit_dps
- if 'hemorrhage_ticks' in attacks_per_second:
- dps_from_hit_hemo = self.get_dps_contribution(self.hemorrhage_tick_damage(average_ap, from_crit_hemo=False), crit_rates['hemorrhage'], attacks_per_second['hemorrhage_ticks'] * (1 - crit_rates['hemorrhage']))
- dps_from_crit_hemo = self.get_dps_contribution(self.hemorrhage_tick_damage(average_ap, from_crit_hemo=True), crit_rates['hemorrhage'], attacks_per_second['hemorrhage_ticks'] * crit_rates['hemorrhage'])
- damage_breakdown['hemorrhage_dot'] = dps_from_hit_hemo[0] + dps_from_crit_hemo[0], dps_from_hit_hemo[1] + dps_from_crit_hemo[1]
-
for proc in damage_procs:
if proc.proc_name not in damage_breakdown:
# Toss multiple damage procs with the same name (Avalanche):
@@ -593,8 +594,8 @@ def update_with_autoattack_passives(self, attacks_per_second, *args, **kwargs):
if 'main_gauche_proc_rate' in kwargs:
main_gauche_proc_rate = kwargs['main_gauche_proc_rate']
elif 'current_stats' in kwargs:
- main_gauche_proc_rate = .02 * self.stats.get_mastery_from_rating(kwargs['current_stats']['mastery']) * self.one_hand_melee_hit_chance()
- attacks_per_second['main_gauche'] = main_gauche_proc_rate * attacks_per_second['mh_autoattack_hits']
+ main_gauche_proc_rate = self.combat_mastery_conversion * self.stats.get_mastery_from_rating(kwargs['current_stats']['mastery']) * self.one_hand_melee_hit_chance()
+ attacks_per_second['main_gauche'] = main_gauche_proc_rate * (attacks_per_second['mh_autoattack_hits'] + attacks_per_second['mh_shadow_blade'])
def get_mh_procs_per_second(self, proc, attacks_per_second, crit_rates):
@@ -1316,7 +1317,7 @@ def combat_attack_counts(self, current_stats):
attack_speed_multiplier = self.base_speed_multiplier * haste_multiplier
self.attack_speed_increase = attack_speed_multiplier
- main_gauche_proc_rate = .02 * self.stats.get_mastery_from_rating(current_stats['mastery']) * self.one_hand_melee_hit_chance()
+ main_gauche_proc_rate = self.combat_mastery_conversion * self.stats.get_mastery_from_rating(current_stats['mastery']) * self.one_hand_melee_hit_chance()
combat_potency_regen_per_oh = 15 * .2 * self.stats.oh.speed / 1.4 # the new "normalized" formula
combat_potency_from_mg = 15 * .2
@@ -1553,7 +1554,7 @@ def subtlety_attack_counts_backstab(self, current_stats):
haste_multiplier = self.stats.get_haste_multiplier_from_rating(current_stats['haste'])
- mastery_snd_speed = 1 + .4 * (1 + .03 * self.stats.get_mastery_from_rating(current_stats['mastery']))
+ mastery_snd_speed = 1 + .4 * (1 + self.subtlety_mastery_conversion * self.stats.get_mastery_from_rating(current_stats['mastery']))
attack_speed_multiplier = self.base_speed_multiplier * haste_multiplier * mastery_snd_speed / 1.4
self.attack_speed_increase = attack_speed_multiplier
@@ -18,12 +18,22 @@ class RogueDamageCalculator(DamageCalculator):
default_ep_stats = ['white_hit', 'yellow_hit', 'str', 'agi', 'haste',
'crit', 'mastery', 'dodge_exp', 'spell_hit', 'spell_exp', 'pvp_power', 'ap']
normalize_ep_stat = 'ap'
+ if normalize_ep_stat in default_ep_stats:
+ default_ep_stats.remove(normalize_ep_stat)
melee_attacks = ['mh_autoattack_hits', 'oh_autoattack_hits', 'mh_shadow_blade', 'oh_shadow_blade',
- 'rupture', 'eviscerate', 'envenom', 'ambush',
+ 'rupture', 'eviscerate', 'envenom', 'ambush', 'garrote',
'sinister_strike', 'revealing_strike', 'main_gauche', 'mh_killing_spree', 'oh_killing_spree',
'backstab', 'hemorrhage',
- 'mh_mutilate', 'oh_mutilate', 'dispatch']
- melee_hit_chance_attacks = melee_attacks + ['deadly_poison', 'deadly_instant_poison']
+ 'mutilate', 'mh_mutilate', 'oh_mutilate', 'dispatch']
+ melee_hit_chance_attacks = melee_attacks + ['deadly_instant_poison', 'fan_of_knives', 'crimson_tempest']
+ dot_ticks = ['rupture_ticks', 'garrote_ticks', 'deadly_poison', 'hemorrhage_dot']
+ ranged_attacks = ['shuriken_toss', 'throw']
+ non_dot_attacks = melee_hit_chance_attacks + ranged_attacks
+ all_attacks = melee_hit_chance_attacks + ranged_attacks + dot_ticks
+
+ assassination_mastery_conversion = .035
+ combat_mastery_conversion = .02
+ subtlety_mastery_conversion = .03
def __setattr__(self, name, value):
object.__setattr__(self, name, value)
@@ -99,9 +109,9 @@ def get_modifiers(self, *args, **kwargs):
base_modifier = 1
kwargs.setdefault('mastery', None)
if 'executioner' in args and self.settings.is_subtlety_rogue():
- base_modifier += .03 * self.stats.get_mastery_from_rating(kwargs['mastery'])
+ base_modifier += self.subtlety_mastery_conversion * self.stats.get_mastery_from_rating(kwargs['mastery'])
if 'potent_poisons' in args and self.settings.is_assassination_rogue():
- base_modifier += .035 * self.stats.get_mastery_from_rating(kwargs['mastery'])
+ base_modifier += self.assassination_mastery_conversion * self.stats.get_mastery_from_rating(kwargs['mastery'])
# Assassasins's Resolve
if self.settings.is_assassination_rogue() and (self.stats.mh.type == 'dagger'):
base_modifier *= 1.2

0 comments on commit 65d1084

Please sign in to comment.