Combat, Watchman Simulators
Inspired by the tremendous amount of work done by others on these forums, I built my trooper DPS simulator ( here) into a DPS simulator for Combat and Watchman specs. I post them here for anyone whose interested, and to catch the mistakes I'm sure to have made. Both of these scripts are written in python and should be poked and prodded until they give you the numbers you want.
It is fairly straightforward to calculate stat weights out of this. A script to do this automatically is included below as well.
Now, blocks of code:
Combat:
Code:
import math
import random
#buffs
smuggler = 1
knight = 1
consular = 1
import sys
#base stats
#str = 1505
#will = 140
#fpower = 1213
#power = 345
#crit = 192
#surge = 294
#acc = 147
#alac = 0
#weapondam = 450
str = (1912 )* (1 +.05*consular)
will = 140 * (1 +.05*consular)
fpower = 1261
power = (993 + 113)
crit = 164
surge = 342
acc = 228
alac = 1
mh_dam = 405
oh_dam = 405
str = int(sys.argv[1]) + str
will = int(sys.argv[2]) + will
fpower = int(sys.argv[3]) + fpower
power = int(sys.argv[4]) + power
crit = int(sys.argv[5]) + crit
surge = int(sys.argv[6]) + surge
acc = int(sys.argv[7]) + acc
alac = int(sys.argv[8]) + alac
mh_dam = int(sys.argv[9]) + mh_dam
oh_dam = int(sys.argv[10])+ oh_dam
#skills
#static bonuses
bonus_acc = 0.07
bonus_crit = 0.01 +0.05*smuggler
bonus_alac = 0.00
bonus_surge = 0.01
def diminishing_returns(x,max,lam):
return max*(1-(1-(0.01/max))**(x/(50*lam)))
#derived stats
#armor_dr = 0.8727
#armor_dr = 0.69
armor_dr = 0.65
mh_hit = min(.82+bonus_acc+diminishing_returns(acc,0.3,0.55) ,1)
oh_hit = min(.49+bonus_acc+diminishing_returns(acc,0.3,0.55) ,1)
mcrit = 0.05+bonus_crit+diminishing_returns(crit,0.3,0.45)+diminishing_returns(str,0.3,2.5)
critvalue = 0.50+bonus_surge+diminishing_returns(surge,0.3,0.11)
haste = bonus_alac+diminishing_returns(alac,0.3,0.55)
bonusdmg = (str*0.2+power*0.23)*(1+0.05*knight)
bonusfdmg = (str*0.2+will*0.2+power*0.23+fpower*0.23)*(1+0.05*knight)
t = 0
focus = 0
tot_damage = 0
remove_armor = 0
centering = 0
zen = 0
ataru_cd = 0
ataru_oa_buff = 0
ataru_trance = 0
br_ataru_buff = 0
zealous_strike_cd = 0
precision_slash_cd = 0
master_strike_cd = 0
blade_storm_cd = 0
force_stasis_cd = 0
dispatch_cd = 0
valorous_call_cd = 0
proc_trinket_cd = 0
n_as = 0
n_br = 0
n_s = 0
n_zs = 0
n_ps = 0
n_ms = 0
n_bs = 0
n_fs = 0
n_z = 0
n_d = 0
n_vc = 0
n_pt = 0
d_as = 0
d_br = 0
d_s = 0
d_zs = 0
d_ps = 0
d_ms = 0
d_bs = 0
d_fs = 0
d_z = 0
d_d = 0
d_vc = 0
def try_proc_trinket(delay):
global tot_damage
global proc_trinket_cd
global armor_dr
global n_pt
return
if (proc_trinket_cd - delay) > 0: return
thisdmg = 0
mhdmg = (246)
#mhdmg = (0)
thisdmg = thisdmg + mhdmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
tot_damage = tot_damage + thisdmg
proc_trinket_cd = 4.5+delay
n_pt = n_pt + 1
#print "Proccy Trinket: ", thisdmg ," , "
def ataru_strike(isfree, delay):
global focus
global tot_damage
global remove_armor
global ataru_cd
global ataru_oa_buff
global ataru_trance
global n_as , d_as
thisdmg = 0
bdmg = (1610*0.038+bonusdmg*0.38+mh_dam*0.385)*1.3
if random.uniform(0,1) < (mh_hit+0.1):
if isfree < 1: ataru_cd = 1.5+delay
#ataru_cd = 1.5+delay
if ataru_trance < 0: ataru_trance = 6.0
if (random.uniform < 0.3): ataru_oa_buff = 1
thisdmg = bdmg
if random.uniform(0,1) < (mcrit):
thisdmg = bdmg*(1+critvalue+0.3)
if remove_armor < 0: thisdmg = thisdmg*armor_dr
tot_damage = tot_damage + thisdmg
n_as = n_as + 1
d_as = d_as + thisdmg
#print "Ataru Proc: ", thisdmg
def try_ataru(isfree = False, delay = 0):
global br_ataru_buff
global ataru_cd
if (ataru_cd <= delay or isfree):
if (random.uniform(0,1) < (0.2+0.3*br_ataru_buff) or isfree):
ataru_strike(isfree, delay)
def blade_rush():
global focus
global tot_damage
global passtime
global remove_armor
global centering
global zen
global br_ataru_buff
global ataru_oa_buff
global n_br , d_br
thisdmg = 0
nhits = 0
mhdmg = (1610*0.134+bonusdmg*1.34+mh_dam*0.89)
ohdmg = (oh_dam*0.89*0.66)
if random.uniform(0,1) < (mh_hit+0.1):
nhits = nhits+1
br_ataru_buff = 6.0
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue+0.3)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit+0.1):
nhits = nhits + 1
br_ataru_buff = 6.0
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue+0.3)
thisdmg = thisdmg+ohdmg
if ataru_oa_buff == 1:
thisdmg = thisdmg*1.1
ataru_oa_buff = 0
if remove_armor < 0: thisdmg = thisdmg*armor_dr
try_ataru(True)
#try_ataru(False)
if zen > 0:
focus = focus - 1
passtime = 1
zen = zen - 1
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1/nhits+1*n/nhits
try_ataru(False, swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
else:
focus = focus - 2
passtime = 1.5
centering = centering + 4
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_ataru(False, swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
br_ataru_buff = 6
tot_damage = tot_damage + thisdmg
n_br = n_br + 1
d_br = d_br + thisdmg
#print "Blade Rush: ", thisdmg ," , " , passtime , focus
def zealous_strike():
global focus
global tot_damage
global passtime
global remove_armor
global centering
global zen
global zealous_strike_cd
global n_zs , d_zs
thisdmg = 0
nhits = 0
mhdmg = (1610*0.1+bonusdmg*1+mh_dam*0.33)
ohdmg = (oh_dam*0.67*0.66)
if random.uniform(0,1) < (mh_hit+0.1):
nhits = nhits+1
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit+0.1):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue)
thisdmg = thisdmg+ohdmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
#try_ataru(False)
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_ataru(False, swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
focus = focus + 6
zealous_strike_cd = 11.5
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_zs = n_zs + 1
d_zs = d_zs + thisdmg
#print "Zealous Strike: ", thisdmg ," , " , passtime , focus
def strike():
global focus
global tot_damage
global passtime
global remove_armor
global centering
global zen
global n_s , d_s
thisdmg = 0
nhits = 0
mhdmg = (1610*0.0+bonusdmg*1+mh_dam*1.01)
ohdmg = (oh_dam*0.99*0.66)
if random.uniform(0,1) < (mh_hit):
nhits = nhits+1
if random.uniform(0,1) < (mh_hit):
nhits = nhits+1
if random.uniform(0,1) < (mh_hit):
nhits = nhits+1
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue)
thisdmg = thisdmg+ohdmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
#try_ataru(False)
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_ataru(False, swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
focus = focus + 2
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_s = n_s + 1
d_s = d_s + thisdmg
#print "Strike: ", thisdmg ," , " , passtime , focus
def precision_slash():
global focus
global tot_damage
global passtime
global remove_armor
global centering
global zen
global ataru_oa_buff
global precision_slash_cd
global n_ps , d_ps
thisdmg = 0
nhits = 0
mhdmg = (1610*0.137+bonusdmg*1.37+mh_dam*0.91)*(.53/.91)
#ohdmg = (oh_dam*0.91*0.66)
ohdmg = (oh_dam*0.57*0.66)
remove_armor = 4.5
if random.uniform(0,1) < (mh_hit):
nhits = nhits+1
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue)
thisdmg = thisdmg+ohdmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
if ataru_oa_buff == 1:
thisdmg = thisdmg*1.1
ataru_oa_buff = 0
#try_ataru(False)
for n in xrange(nhits):
swing_delay = 0
try_ataru(False, swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
focus = focus - 3
precision_slash_cd = 15
if zen < 1: centering = centering + 4
passtime = 0
tot_damage = tot_damage + thisdmg
n_ps = n_ps + 1
d_ps = d_ps + thisdmg
#print "Precision Slash: ", thisdmg ," , " , passtime , focus
def master_strike():
global focus
global tot_damage
global passtime
global remove_armor
global centering
global zen
global master_strike_cd
global n_ms , d_ms
thisdmg = 0
nhits = 0
mhdmg = (1610*0.417+bonusdmg*4.17+mh_dam*2.775)*1.08
oh1dmg = (oh_dam*0.925*0.66)*1.08
oh2dmg = (oh_dam*1.85)*1.08
if random.uniform(0,1) < (mh_hit+0.1):
nhits = nhits+1
if random.uniform(0,1) < (mh_hit+0.1):
nhits = nhits+1
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit+0.1):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
oh1dmg = oh1dmg*(1+critvalue)
thisdmg = thisdmg+oh1dmg
if random.uniform(0,1) < (oh_hit+0.1):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
oh2dmg = oh2dmg*(1+critvalue)
thisdmg = thisdmg+oh2dmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
thisdmg = thisdmg*1.15
#try_ataru(False)
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*3/nhits+3*n/nhits
try_ataru(False, swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
master_strike_cd = 27
passtime = 3
tot_damage = tot_damage + thisdmg
n_ms = n_ms + 1
d_ms = d_ms + thisdmg
#print "Master Strike: ", thisdmg ," , " , passtime , focus
def blade_storm():
global focus
global tot_damage
global passtime
global remove_armor
global centering
global zen
global ataru_oa_buff
global blade_storm_cd
global n_bs , d_bs
thisdmg = 0
bonuscrit = 0
if ataru_trance > 0: bonuscrit = 1
mhdmg = (1610*0.187+bonusfdmg*1.87)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit+0.06+1*bonuscrit):
mhdmg = mhdmg*(1+critvalue+0.3)
thisdmg = thisdmg+mhdmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
if ataru_oa_buff == 1:
thisdmg = thisdmg*1.1
ataru_oa_buff = 0
focus = focus - 2
blade_storm_cd = 9
if zen < 1: centering = centering + 4
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_bs = n_bs + 1
d_bs = d_bs + thisdmg
#print "Blade Storm: ", thisdmg ," , " , passtime , focus
def force_stasis():
global focus
global tot_damage
global passtime
global remove_armor
global force_stasis_cd
global n_fs , d_fs
thisdmg = 0
mhdmg = (1610*0.272+bonusfdmg*2.72)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit+0.06):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
focus = focus +3
force_stasis_cd = 50
passtime = 3*(1-haste)
tot_damage = tot_damage + thisdmg
n_fs = n_fs + 1
d_fs = d_fs + thisdmg
#print "Force Stasis: ", thisdmg ," , " , passtime , focus
def dispatch():
global focus
global tot_damage
global passtime
global remove_armor
global centering
global zen
global ataru_oa_buff
global dispatch_cd
global n_d , d_d
thisdmg = 0
mhdmg = (1610*0.285+bonusdmg*2.95+mh_dam*1.9)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if remove_armor < 0: thisdmg = thisdmg*armor_dr
if ataru_oa_buff == 1:
thisdmg = thisdmg*1.1
ataru_oa_buff = 0
focus = focus - 1
if zen < 1: centering = centering + 4
swing_delay = random.uniform(0,1)*1.5
try_ataru(False, swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
dispatch_cd = 6
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_d = n_d + 1
d_d = d_d + thisdmg
#print "Dispatch: ", thisdmg ," , " , passtime , focus
def zazen():
global passtime
global centering
global zen
global n_z
centering = 0
zen = 6
passtime = 0
n_z = n_z + 1
#print "Invoking Zen: ", thisdmg ," , " , passtime , focus
def valorous_call():
global passtime
global centering
global valorous_call_cd
global n_vc
centering = 30
valorous_call_cd = 150
passtime = 0
n_vc = n_vc + 1
#print "Valorous Call " , thisdmg , " , " , passtime , focus
for iteration in xrange(9999):
fight_length = 300
iteration_t = 0
focus = 0
remove_armor = 0
centering = 0
zen = 0
ataru_cd = 0
ataru_oa_buff = 0
ataru_trance = 0
br_ataru_buff = 0
zealous_strike_cd = 0
precision_slash_cd = 0
master_strike_cd = 0
blade_storm_cd = 0
force_stasis_cd = 0
dispatch_cd = 0
valorous_call_cd = 0
proc_trinket_cd = 0
choose_ability = 0
while iteration_t < fight_length:
thisdmg = 0
passtime = 0
######SIMPLE PRIORITY######
#if centering >= 30: zazen()
#elif zealous_strike_cd <= 0: zealous_strike()
#elif br_ataru_buff <= 0 and focus >= 3: blade_rush()
#elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
#elif ataru_trance > 0 and focus >= 2 and blade_storm_cd <= 0: blade_storm()
#elif master_strike_cd <= 0: master_strike()
#elif force_stasis_cd <= 0: force_stasis()
#elif focus >= 3: blade_rush()
#else: strike()
###END SIMPLE PRIORITY####
######ZEN BURN############
#if zealous_strike_cd <= 0: zealous_strike()
#elif centering >= 30:
# if br_ataru_buff <= 0 and focus >= 3: blade_rush()
# elif focus < 8: strike()
# else: zazen()
#elif zen > 0:
# if br_ataru_buff <= 0 and focus >= 3: blade_rush()
# elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
# elif focus >= 3: blade_rush()
# else: strike()
#else:
# if br_ataru_buff <= 0 and focus >= 3: blade_rush()
# elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
# elif ataru_trance > 0 and focus >= 2 and blade_storm_cd <= 0: blade_storm()
# elif master_strike_cd <= 0: master_strike()
# elif force_stasis_cd <= 0: force_stasis()
# elif focus >= 3: blade_rush()
# else: strike()
###END ZEN BURN###########
###PRECISE BURN########
#if centering >= 30: zazen()
#elif zealous_strike_cd <= 0: zealous_strike()
#elif br_ataru_buff <= 0 and focus >= 3: blade_rush()
#elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
#elif precision_slash_cd <= 3 and focus <= 5: strike()
#elif ataru_trance > 0 and focus >= 2 and blade_storm_cd <= 0: blade_storm()
#elif master_strike_cd <= 0: master_strike()
#elif force_stasis_cd <= 0: force_stasis()
#elif focus >= 3: blade_rush()
#else: strike()
##END PRECISE BURN#####
######PRECISE ZEN BURN############
if zealous_strike_cd <= 0: zealous_strike()
elif centering <= 5 and valorous_call_cd <= 0: valorous_call()
elif centering >= 30: zazen()
elif zen > 0:
if br_ataru_buff <= 0 and focus >= 3: blade_rush()
elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
elif iteration_t > fight_length*0.70 and focus >= 2 and dispatch_cd <=0: dispatch()
elif focus >= 3: blade_rush()
else: strike()
else:
if br_ataru_buff <= 0 and focus >= 3: blade_rush()
elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
elif iteration_t > fight_length*0.70 and focus >= 2 and dispatch_cd <=0: dispatch()
elif ataru_trance > 0 and focus >= 2 and blade_storm_cd <= 0: blade_storm()
elif master_strike_cd <= 0: master_strike()
elif force_stasis_cd <= 0: force_stasis()
elif focus >= 7: blade_rush()
else: strike()
###END PRECISE ZEN BURN###########
#########ATARU TEST####################
#if choose_ability == 0: strike()
#elif choose_ability == 1: blade_rush()
#choose_ability = 1 - choose_ability
####END ATARU TEST#####################
t = t+passtime
iteration_t = iteration_t + passtime
zealous_strike_cd = zealous_strike_cd - passtime
precision_slash_cd = precision_slash_cd - passtime
master_strike_cd = master_strike_cd - passtime
blade_storm_cd = blade_storm_cd - passtime
force_stasis_cd = force_stasis_cd - passtime
remove_armor = remove_armor - passtime
ataru_cd = ataru_cd - passtime
dispatch_cd = dispatch_cd - passtime
valorous_call_cd = valorous_call_cd - passtime
if ataru_trance > 0 and (ataru_trance - passtime) <= 0:
focue = focus +1
ataru_trance = ataru_trance - passtime
br_ataru_buff = br_ataru_buff - passtime
proc_trinket_cd = proc_trinket_cd - passtime
tot_damage = tot_damage + thisdmg
print "Total Time: ", t , " seconds"
print "Total Damage: " , tot_damage
print "DPS: " , tot_damage/t
print ""
if n_as > 0: print "Ataru ECD: " , t/n_as , " : " , 100*d_as/tot_damage
if n_br > 0: print "Blade Rush ECD: " , t/n_br , " : " , 100*d_br/tot_damage
if n_zs > 0: print "Zealous Strike ECD: " , t/n_zs , " : " , 100*d_zs/tot_damage
if n_s > 0: print "Strike ECD: ", t/n_s , " : " , 100*d_s/tot_damage
if n_ps > 0: print "Precision Stike ECD: " , t/n_ps , " : " , 100*d_ps/tot_damage
if n_z > 0: print "Zen ECD: " , t/n_z
if n_d > 0: print "Dispatch ECD: " , t/n_d , " : " , 100*d_d/tot_damage
if n_bs > 0: print "Blade Storm ECD: ", t/n_bs , " : " , 100*d_bs/tot_damage
if n_ms > 0: print "Master Strike ECD: ", t/n_ms , " : " , 100*d_ms/tot_damage
if n_fs > 0: print "Force Stasis ECD: ", t/n_fs , " : " , 100*d_fs/tot_damage
if n_vc > 0: print "Valorous Call ECD: ", t/n_vc
if n_pt > 0: print "Proccy Trinket ECD: ", t/n_pt
#import os
#os.environ['PYTHONINSPECT'] = '1'
Watchman
Code:
import math
import random
import array
from array import array
#buffs
smuggler = 1
knight = 1
consular = 0
import sys
#base stats
#str = 1505
#will = 140
#fpower = 1213
#power = 345
#crit = 192
#surge = 294
#acc = 147
#alac = 0
#weapondam = 450
str = 1922 * (1 +.05*consular)
will = 140 * (1 +.05*consular)
fpower = 1261
power = 944
crit = 119
surge = 342
acc = 228
alac = 1
mh_dam = 405
oh_dam = 405
str = int(sys.argv[1]) + str
will = int(sys.argv[2]) + will
fpower = int(sys.argv[3]) + fpower
power = int(sys.argv[4]) + power
crit = int(sys.argv[5]) + crit
surge = int(sys.argv[6]) + surge
acc = int(sys.argv[7]) + acc
alac = int(sys.argv[8]) + alac
mh_dam = int(sys.argv[9]) + mh_dam
oh_dam = int(sys.argv[10])+ oh_dam
#skills
#static bonuses
bonus_acc = 0.01
bonus_crit = 0.01 +0.05*smuggler
bonus_alac = 0.00
bonus_surge = 0.01
def diminishing_returns(x,max,lam):
return max*(1-(1-(0.01/max))**(x/(50*lam)))
#derived stats
#armor_dr = 0.8727
#armor_dr = 0.69
armor_dr = 0.65
mh_hit = min(.82+bonus_acc+diminishing_returns(acc,0.3,0.55) ,1)
oh_hit = min(.49+bonus_acc+diminishing_returns(acc,0.3,0.55) ,1)
mcrit = 0.05+bonus_crit+diminishing_returns(crit,0.3,0.45)+diminishing_returns(str,0.3,2.5)
critvalue = 0.50+bonus_surge+diminishing_returns(surge,0.3,0.11)
haste = bonus_alac+diminishing_returns(alac,0.3,0.55)
bonusdmg = (str*0.2+power*0.23)*(1+0.05*knight)
bonusfdmg = (str*0.2+will*0.2+power*0.23+fpower*0.23)*(1+0.05*knight)
t = 0
cauterize_tick_cd_array = array('f',[-1,-1,-1,-1,-1,-1])
overload_saber_tick_cd_array = array('f',[-1,-1,-1])
focus = 0
juyo_stacks = 0
juyo_cd = 0
tot_damage = 0
remove_armor = 0
centering = 0
zen = 0
zealous_strike_cd = 0
master_strike_cd = 0
force_stasis_cd = 0
force_leap_cd = 0
dispatch_cd = 0
valorous_call_cd = 0
overload_saber_cd = 0
overload_saber_buff_stacks = 0
overload_saber_dot_stacks = 0
overload_saber_apply_cd = 0
merciless_slash_cd = 0
merciless_buff = 0
merciless_buff_cd = 0
burning_focus_cd = 0
mind_sear_cd = 0
cauterize_cd = 0
proc_trinket_cd = 0
n_st = 0
n_zs = 0
n_ms = 0
n_me = 0
n_fs = 0
n_fl = 0
n_z = 0
n_d = 0
n_vc = 0
n_ca = 0
n_sl = 0
n_os = 0
n_pt = 0
def try_proc_trinket(delay):
global tot_damage
global juyo_stacks
global proc_trinket_cd
global n_pt
if (proc_trinket_cd - delay) > 0: return
thisdmg = 0
mhdmg = (246)
#mhdmg = (0)
thisdmg = thisdmg + mhdmg
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
tot_damage = tot_damage + thisdmg
proc_trinket_cd = 4.5+delay
n_pt = n_pt + 1
#print "Proccy Trinket: ", thisdmg ," , "
def try_overload_saber(delay):
global overload_saber_buff_stacks
global overload_saber_dot_stacks
global overload_saber_tick_cd_array
global overload_saber_apply_cd
if overload_saber_apply_cd <= 0 and overload_saber_buff_stacks > 0 and overload_saber_dot_stacks < 3:
overload_saber_tick_cd_array = array('f',[0.01+delay,3.01+delay,6.01+delay])
overload_saber_dot_stacks = overload_saber_dot_stacks + 1
overload_saber_buff_stacks = overload_saber_buff_stacks - 1
overload_saber_apply_cd = 1.5+delay
#print "Applied Overload Saber"
def overload_saber():
global focus
global passtime
global overload_saber_buff_stacks
global overload_saber_cd
global n_os
passtime = 0
overload_saber_buff_stacks = 3
overload_saber_cd = 12
focus = focus - 3
n_os = n_os + 1
#print "Overload Saber"
def overload_saber_tick():
global focus
global tot_damage
global juyo_stacks
global centering
global zen
global burning_focus_cd
global overload_saber_dot_stacks
thisdmg = 0
bonuscrit = 0
if zen > 0: bonuscrit = 1
mhdmg = (1610*0.02+bonusfdmg*0.2)*1.15
if random.uniform(0,1) < (mcrit + 0.06 + 0.01*juyo_stacks + bonuscrit):
mhdmg = mhdmg*(1+critvalue+0.3)
thisdmg = thisdmg+mhdmg*overload_saber_dot_stacks
thisdmg = thisdmg*(1+0.02*juyo_stacks)
if burning_focus_cd <= 0 and random.uniform(0,1) < 0.3: focus = focus + 1
if zen > 0: zen = zen - 1
tot_damage = tot_damage + thisdmg
#print "Overload Saber Tick: ", thisdmg
def merciless_slash():
global focus
global tot_damage
global passtime
global juyo_cd
global juyo_stacks
global centering
global zen
global merciless_slash_cd
global merciless_buff
global merciless_buff_cd
global mind_sear_cd
global cauterize_cd
global n_me
thisdmg = 0
nhits = 0
mhdmg = (1610*0.285+bonusdmg*2.85+mh_dam*1.9)
ohdmg = (oh_dam*1.9*0.66)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
nhits = nhits + 1
if random.uniform(0,1) < (oh_hit+0.1):
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue)
thisdmg = thisdmg+ohdmg
nhits = nhits + 1
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
focus = focus - 4
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
if zen < 1: centering = centering + 4
merciless_slash_cd = 12-1.5*merciless_buff
if merciless_buff < 3: merciless_buff = merciless_buff+1
merciless_buff_cd = 15
if mind_sear_cd <= 0 and random.uniform(0,1) < 0.66: cauterize_cd = 0
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_me = n_me + 1
#print "Merciless Slash: ", thisdmg ," , " , passtime , focus
def slash():
global focus
global tot_damage
global passtime
global juyo_cd
global juyo_stacks
global centering
global zen
global mind_sear_cd
global cauterize_cd
global n_sl
thisdmg = 0
nhits = 0
mhdmg = (1610*0.153+bonusdmg*1.53+mh_dam*1.02)
ohdmg = (oh_dam*1.02*0.66)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit+0.15):
mhdmg = mhdmg*(1+critvalue)
nhits = nhits + 1
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit+0.1):
if random.uniform(0,1) < (mcrit+0.15):
ohdmg = ohdmg*(1+critvalue)
nhits = nhits + 1
thisdmg = thisdmg+ohdmg
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
focus = focus - 2
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
if zen < 1: centering = centering + 4
if mind_sear_cd <= 0 and random.uniform(0,1) < 0.33: cauterize_cd = 0
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_sl = n_sl + 1
#print "Slash: ", thisdmg ," , " , passtime , focus
def cauterize():
global focus
global tot_damage
global passtime
global juyo_stacks
global juyo_cd
global centering
global zen
global cauterize_tick_cd_array
global cauterize_cd
global n_ca
thisdmg = 0
nhits = 0
mhdmg = (1610*0.06+bonusdmg*0.6+mh_dam*0.4)*1.3
ohdmg = (oh_dam*0.6*0.66)*1.3
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
nhits = nhits + 1
if random.uniform(0,1) < (oh_hit+0.1):
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue)
thisdmg = thisdmg+ohdmg
nhits = nhits + 1
cauterize_tick_cd_array = array('f',[1,2,3,4,5,6])
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
focus = focus - 2
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
if zen < 1: centering = centering + 4
cauterize_cd = 15
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_ca = n_ca + 1
#print "Cauterize Applied: ", thisdmg ," , " , passtime , focus
def cauterize_tick():
global focus
global tot_damage
global juyo_stacks
global centering
global zen
global burning_focus_cd
thisdmg = 0
bonuscrit = 0
if zen > 0: bonuscrit = 1
mhdmg = (1610*0.02+bonusfdmg*0.2)*1.15
if random.uniform(0,1) < (mcrit + 0.06 + 0.01*juyo_stacks + bonuscrit):
mhdmg = mhdmg*(1+critvalue+0.3)
thisdmg = thisdmg+mhdmg
thisdmg = thisdmg*(1+0.02*juyo_stacks)
if burning_focus_cd <= 0 and random.uniform(0,1) < 0.3: focus = focus + 1
if zen > 0: zen = zen - 1
tot_damage = tot_damage + thisdmg
#print "Cauterize Tick: ", thisdmg
def zealous_strike():
global focus
global tot_damage
global passtime
global juyo_stacks
global juyo_cd
global centering
global zen
global zealous_strike_cd
global n_zs
thisdmg = 0
nhits = 0
mhdmg = (1610*0.1+bonusdmg*1+mh_dam*0.33)
ohdmg = (oh_dam*0.67*0.66)
if random.uniform(0,1) < (mh_hit+0.1):
nhits = nhits+1
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit+0.1):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue)
thisdmg = thisdmg+ohdmg
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
focus = focus + 6
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
zealous_strike_cd = 15
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_zs = n_zs + 1
#print "Zealous Strike: ", thisdmg ," , " , passtime , focus
def strike():
global focus
global tot_damage
global passtime
global juyo_stacks
global juyo_cd
global centering
global zen
global n_st
thisdmg = 0
nhits = 0
mhdmg = (1610*0.0+bonusdmg*1+mh_dam*1.01)
ohdmg = (oh_dam*0.99*0.66)
if random.uniform(0,1) < (mh_hit):
nhits = nhits+1
if random.uniform(0,1) < (mh_hit):
nhits = nhits+1
if random.uniform(0,1) < (mh_hit):
nhits = nhits+1
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
ohdmg = ohdmg*(1+critvalue)
thisdmg = thisdmg+ohdmg
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
focus = focus + 2
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_st = n_st + 1
#print "Strike: ", thisdmg ," , " , passtime , focus
def master_strike():
global focus
global tot_damage
global passtime
global juyo_stacks
global juyo_cd
global centering
global zen
global master_strike_cd
global n_ms
thisdmg = 0
nhits = 0
mhdmg = (1610*0.417+bonusdmg*4.17+mh_dam*2.775)*1.08
oh1dmg = (oh_dam*0.925*0.66)*1.08
oh2dmg = (oh_dam*1.85)*1.08
if random.uniform(0,1) < (mh_hit+0.1):
nhits = nhits+1
if random.uniform(0,1) < (mh_hit+0.1):
nhits = nhits+1
if random.uniform(0,1) < (mcrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
if random.uniform(0,1) < (oh_hit+0.1):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
oh1dmg = oh1dmg*(1+critvalue)
thisdmg = thisdmg+oh1dmg
if random.uniform(0,1) < (oh_hit+0.1):
nhits = nhits + 1
if random.uniform(0,1) < (mcrit):
oh2dmg = oh2dmg*(1+critvalue)
thisdmg = thisdmg+oh2dmg
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*3/nhits+3*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
master_strike_cd = 27
passtime = 3
tot_damage = tot_damage + thisdmg
n_ms = n_ms + 1
#print "Master Strike: ", thisdmg ," , " , passtime , focus
def force_stasis():
global focus
global tot_damage
global passtime
global force_stasis_cd
global n_fs
thisdmg = 0
mhdmg = (1610*0.272+bonusfdmg*2.72)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit+0.06):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
if random.uniform (0,1) < 0.3: try_proc_trinket(0)
focus = focus +3
force_stasis_cd = 50
passtime = 3*(1-haste)
tot_damage = tot_damage + thisdmg
n_fs = n_fs + 1
#print "Force Stasis: ", thisdmg ," , " , passtime , focus
def force_leap():
global focus
global tot_damage
global passtime
global juyo_stacks
global juyo_cd
global force_leap_cd
global n_fl
thisdmg = 0
nhits = 0
mhdmg = (1610*0.091+bonusdmg*.91+mh_dam*0.61)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit+0.06):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
nhits = nhits + 1
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
thisdmg = thisdmg*armor_dr*(1+0.02*juyo_stacks)
focus = focus + 4
force_leap_cd = 12
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_fl = n_fl + 1
#print "Force Leap: ", thisdmg ," , " , passtime , focus
def dispatch():
global focus
global tot_damage
global passtime
global juyo_stacks
global juyo_cd
global centering
global zen
global dispatch_cd
global n_d
nhits = 0
thisdmg = 0
bonuscrit = 0
mhdmg = (1610*0.285+bonusdmg*2.95+mh_dam*1.9)
if random.uniform(0,1) < (mh_hit+0.1):
if random.uniform(0,1) < (mcrit+0.06+1*bonuscrit):
mhdmg = mhdmg*(1+critvalue)
thisdmg = thisdmg+mhdmg
nhits = nhits + 1
for n in xrange(nhits):
swing_delay = random.uniform(0,1)*1.5/nhits+1.5*n/nhits
try_overload_saber(swing_delay)
if random.uniform (0,1) < 0.3: try_proc_trinket(swing_delay)
focus = focus - 1
if juyo_stacks < 5 and juyo_cd <= 0: juyo_stacks = juyo_stacks+1
if zen < 1: centering = centering + 4
dispatch_cd = 6
passtime = 1.5
tot_damage = tot_damage + thisdmg
n_d = n_d + 1
#print "Dispatch: ", thisdmg ," , " , passtime , focus
def zazen():
global passtime
global centering
global zen
global n_z
centering = 0
zen = 6
passtime = 0
n_z = n_z + 1
#print "Invoking Zen: ", thisdmg ," , " , passtime , focus
def valorous_call():
global passtime
global centering
global valorous_call_cd
global n_vc
centering = 30
valorous_call_cd = 150
passtime = 0
n_vc = n_vc + 1
#print "Valorous Call " , thisdmg , " , " , passtime , focus
for iteration in xrange(30000):
fight_length = 300
iteration_t = 0
focus = 0
remove_armor = 0
centering = 0
zen = 0
zealous_strike_cd = 0
precision_slash_cd = 0
master_strike_cd = 0
blade_storm_cd = 0
force_stasis_cd = 0
dispatch_cd = 0
valorous_call_cd = 0
overload_saber_cd = 0
overload_saber_buff_stacks = 0
overload_saber_dot_stacks = 0
overload_saber_apply_cd = 0
merciless_slash_cd = 0
merciless_buff = 0
burning_focus_cd = 0
mind_sear_cd = 0
cauterize_cd = 0
cauterize_tick_cd_array = array('f',[-1,-1,-1,-1,-1,-1])
overload_saber_tick_cd_array = array('f',[-1,-1,-1])
while iteration_t < fight_length:
thisdmg = 0
passtime = 0
######MASH BUTTANS######
#if cauterize_cd <= 0 and focus >= 2: cauterize()
#elif merciless_slash_cd <=0 and focus >= 5: merciless_slash()
#else: strike()
###END MASH BUTTANS#####
######SIMPLE PRIORITY######
#if centering >= 30: zazen()
#elif centering <= 5 and valorous_call_cd <= 0: valorous_call()
#elif cauterize_cd <= 0 and focus >= 2: cauterize()
#elif overload_saber_cd <=0 and focus >= 3: overload_saber()
#elif zealous_strike_cd <= 0: zealous_strike()
#elif iteration_t > fight_length*0.7 and focus >= 7 and dispatch_cd <=0: dispatch()
#elif merciless_slash_cd <=0 and focus >= 5: merciless_slash()
#elif master_strike_cd <= 0: master_strike()
#elif force_leap_cd <= 0: force_leap()
#elif force_stasis_cd <= 0: force_stasis()
#elif focus > 5: slash()
#else: strike()
###END SIMPLE PRIORITY####
######HAND-OPTIMIZE######
if centering >= 30: zazen()
elif centering <= 5 and valorous_call_cd <= 0: valorous_call()
elif merciless_slash_cd <=0 and focus >= 5 and merciless_buff_cd <= 2: merciless_slash()
elif overload_saber_cd <=0 and focus >= 3: overload_saber()
elif cauterize_cd <= 0 and focus >= 2: cauterize()
elif zealous_strike_cd <= 0 and focus <= 6: zealous_strike()
elif force_leap_cd <= 0 and focus <= 8: force_leap()
elif iteration_t > fight_length*0.7 and focus >= 2 and dispatch_cd <=0: dispatch()
elif merciless_slash_cd <=0 and focus >= 5: merciless_slash()
elif master_strike_cd <= 0 and merciless_buff_cd >= 4: master_strike()
#elif force_stasis_cd <= 0 and merciless_buff_cd >= 4: force_stasis()
elif focus > 8: slash()
else: strike()
###END HAND-OPTIMIZE####
t = t+passtime
iteration_t = iteration_t + passtime
zealous_strike_cd = zealous_strike_cd - passtime
precision_slash_cd = precision_slash_cd - passtime
master_strike_cd = master_strike_cd - passtime
blade_storm_cd = blade_storm_cd - passtime
force_stasis_cd = force_stasis_cd - passtime
force_leap_cd = force_leap_cd - passtime
remove_armor = remove_armor - passtime
dispatch_cd = dispatch_cd - passtime
valorous_call_cd = valorous_call_cd - passtime
tot_damage = tot_damage + thisdmg
juyo_cd = juyo_cd - passtime
overload_saber_cd = overload_saber_cd - passtime
overload_saber_apply_cd = overload_saber_apply_cd - passtime
merciless_slash_cd = merciless_slash_cd - passtime
burning_focus_cd = burning_focus_cd - passtime
mind_sear_cd = mind_sear_cd - passtime
cauterize_cd = cauterize_cd - passtime
proc_trinket_cd = proc_trinket_cd - passtime
merciless_buff_cd = merciless_buff_cd - passtime
if merciless_buff_cd <= 0:
merciless_buff = 0
#print "Merciless Fell Off"
if focus > 12: focus = 12
#print focus, centering , zen
for n in xrange(len(cauterize_tick_cd_array)):
if cauterize_tick_cd_array[n] > 0 and cauterize_tick_cd_array[n] - passtime <= 0: cauterize_tick()
cauterize_tick_cd_array[n] = cauterize_tick_cd_array[n] - passtime
for n in xrange(len(overload_saber_tick_cd_array)):
if overload_saber_tick_cd_array[n] > 0 and overload_saber_tick_cd_array[n] - passtime <= 0:
overload_saber_tick()
if n == len(overload_saber_tick_cd_array) - 1: overload_saber_dot_stacks = 0
overload_saber_tick_cd_array[n] = overload_saber_tick_cd_array[n] - passtime
print "Total Time: ", t , " seconds"
print "Total Damage: " , tot_damage
print "DPS: " , tot_damage/t
print ""
if n_st > 0: print "Strike ECD: " , t/n_st
if n_zs > 0: print "Zealous Strike ECD:" , t/n_zs
if n_ms > 0: print "Master Strike ECD:" , t/n_ms
if n_me > 0: print "Merciless Slash ECD", t/n_me
if n_fs > 0: print "Force Stasis ECD:" , t/n_fs
if n_fl > 0: print "Force Leap ECD:" , t/n_fl
if n_z > 0: print "Zen ECD:" , t/n_z
if n_d > 0: print "Dispatch ECD:" , t/n_d
if n_vc > 0: print "Valorous Call ECD" , t/n_vc
if n_ca > 0: print "Cauterize ECD:" , t/n_ca
if n_sl > 0: print "Slash ECD:" , t/n_sl
if n_os > 0: print "Overload Saber ECD" , t/n_os
if n_vc > 0: print "Valorous Call ECD: ", t/n_vc
if n_pt > 0: print "Proccy Trinket ECD: ", t/n_pt
print ""
print ""
#import os
#os.environ['PYTHONINSPECT'] = '1'
One of the nicer things you can do with these macros is trivially implement any rotation you like, eg:
Code:
######MASH BUTTANS######
if cauterize_cd <= 0 and focus >= 2: cauterize()
elif merciless_slash_cd <=0 and focus >= 5: merciless_slash()
else: strike()
###END MASH BUTTANS#####
or
Code:
######PRECISE ZEN BURN############
if zealous_strike_cd <= 0: zealous_strike()
elif centering <= 5 and valorous_call_cd <= 0: valorous_call()
elif centering >= 30: zazen()
elif zen > 0:
if br_ataru_buff <= 0 and focus >= 3: blade_rush()
elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
elif iteration_t > fight_length*0.8 and focus >= 2 and dispatch_cd <=0: dispatch()
elif focus >= 3: blade_rush()
else: strike()
elif centering >= 24:
if br_ataru_buff <= 0 and focus >= 3: blade_rush()
elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
elif precision_slash_cd <= 3 and focus <= 5: strike()
elif iteration_t > fight_length*0.8 and focus >= 7 and dispatch_cd <=0: dispatch()
elif ataru_trance > 0 and focus >= 7 and blade_storm_cd <= 0: blade_storm()
elif master_strike_cd <= 0: master_strike()
elif force_stasis_cd <= 0: force_stasis()
else: strike()
else:
if br_ataru_buff <= 0 and focus >= 3: blade_rush()
elif precision_slash_cd <= 0 and focus >= 3: precision_slash()
elif precision_slash_cd <= 3 and focus <= 5: strike()
elif iteration_t > fight_length*0.8 and focus >= 2 and dispatch_cd <=0: dispatch()
elif ataru_trance > 0 and focus >= 2 and blade_storm_cd <= 0: blade_storm()
elif master_strike_cd <= 0: master_strike()
elif force_stasis_cd <= 0: force_stasis()
elif focus >= 3: blade_rush()
else: strike()
###END PRECISE ZEN BURN###########
The rotations will let you break the games rules (not enough focus, off of cooldown), but should still track everything properly even if you do. The big exception to this is that you should only use one ability per iteration of the loop. You can get away with doing more than this, but you will very clearly break the results.
Anyway, enjoy!
For those that don't want to run this themselves, the DPS of the two specs using a simple rotation for each and the same gear is:
Combat:
Code:
python combat_cl.py 0 0 0 0 0 0 0 0 0 0
Total Time: 300978.985374 seconds
Total Damage: 450784232.403
DPS: 1497.72659989
Ataru ECD: 1.35264766854
Blade Rush ECD: 3.87589802681
Zealous Strike ECD: 12.039159415
Strike ECD: 9.27716257356
Precision Stike ECD: 16.4974230089
Zen ECD: 60.1957970748
Blade Storm ECD: 12.3549519878
Master Strike ECD: 28.3061210735
Force Stasis ECD: 50.163164229
python weights.py
acc : 0.288960221211 1502.22246814
alac : 0.0710837357245 1498.34566969
baseline : 0.0 1497.08083693
power : 1.0 1514.87439754
surge : 0.420568725621 1504.56425204
str : 0.980003381122 1514.51858649
error : 0.00570366000512 1497.18232535
crit : 0.75024980006 1510.43045222
Watchman:
Code:
python watchman_cl.py 0 0 0 0 0 0 0 0 0 0
Total Time: 301125.066877 seconds
Total Damage: 461133823.103
DPS: 1531.36976568
Strike ECD: 7.44898124617
Zealous Strike ECD: 12.1534111021
Merciless Slash ECD: 7.3411118476
Force Stasis ECD: 50.1958771256
Zen ECD: 25.1755761957
Dispatch ECD: 64.2331627296
Valorous Call ECD 150.562533438
Cauterize ECD: 8.63342030668
Slash ECD: 9.27994905472
Overload Saber ECD 12.9627665466
python weights.py
acc : 0.746977573632 1545.57999733
alac : 0.00377735501129 1533.52811283
baseline : 0.0 1533.46685848
power : 1.0 1549.68305998
surge : 0.459749576373 1540.92225025
str : 0.956113551623 1548.97138849
error : -0.137802682089 1531.23222242
crit : 0.773390920186 1546.00832148
(n.b. The listed Watchman spec has a significantly higher return on accuracy because it isn't yet at the acc cap, while the combat buffs push it over that cap)
Clearly, one can be smarter about these rotations, eg, by conserving focus as Precision Strike is nearing its cooldown.
|