Posted on 2015-03-13 13:53 by Aaron Meier
Monk damage simulator output
Calculating damage at 20 rounds per day over 1000 days for ACs of [15, 20, 25]
========================================
Name: Many attacks with Fiery Fist,
Stuns per day: 0.0
Damage per day: 641.644
Hits per day: 45.208
Misses per day: 54.792
Attack penalties: [0, 0, 0, 0, -5]
========================================
Name: High-hit Fiery Fist,
Stuns per day: 0.0
Damage per day: 614.348
Hits per day: 38.847
Misses per day: 21.153
Attack penalties: [2, 2, 2]
========================================
Name: Many attacks with Stunning Fist,
Stuns per day: 6.435
Damage per day: 568.416
Hits per day: 47.378
Misses per day: 52.622
Attack penalties: [0, 0, 0, 0, -5]
========================================
Name: High-hit Stunning Fist,
Stuns per day: 8.902
Damage per day: 530.728
Hits per day: 40.802
Misses per day: 19.198
Attack penalties: [2, 2, 2]
Source code
#!/usr/bin/python3
import random
import json
# NPC
ac = [15,20,25]
fort_base_save = 5
stunned_ac_loss = 2
# PC
bab = 6
level = 9
# Misc
days = 1000
rounds = 20
# Fiery Fist
def damage_roll_a(option):
droll = random.randint(2,16)
d6fire = 0
if option['attack_i'] == 0 and option['stuns'] > 0:
option['stuns'] -= 1
option['is_stunned'] = True
if option['is_stunned']:
d6fire = random.randint(1,6)
option['total_dmg'] += (droll + option['str_mod'] + d6fire)
return option
# Stunning fist
def damage_roll_b(option):
droll = random.randint(2,16)
if not option['is_stunned'] and option['attack_i'] == 0 and\
option['stuns'] > 0:
# Try to stun
fort_roll = fort_base_save + random.randint(1,20)
if option['stun_save'] > fort_roll:
option['is_stunned'] = True
option['total_stuns'] += 1
option['stuns'] -= 1
option['total_dmg'] += (droll + option['str_mod'])
return option
def calc_hits(option):
hits = 0
misses = 0
total_dmg = 0
dmg = option['dmg']
str_mod = option['str_mod']
attacks = option['attacks']
stuns_per_day = option['stuns'] + 0
for d in range(days):
option['stuns'] = stuns_per_day
for r in range(rounds):
option['attack_i'] = 0
random.shuffle(option['ac'])
option['is_stunned'] = False
for a in attacks:
crit = False
d20 = random.randint(1,20)
if d20 == 20:
crit == True
hit_roll = d20 + bab + str_mod + a
this_ac = option['ac'][0]
if option['is_stunned']:
this_ac -= option['stunned_ac_loss']
if hit_roll >= this_ac:
hits += 1
option = dmg(option)
if crit:
hits += 1
option = dmg(option)
else:
misses += 1
option['attack_i'] += 1
option['dmg_per_day'] = option['total_dmg'] / days
option['stuns_per_day'] = option['total_stuns'] / days
option['hits_per_day'] = hits / days
option['misses_per_day'] = misses / days
print("="*40)
print("""
Name: %(name)s,
Stuns per day: %(stuns_per_day)s
Damage per day: %(dmg_per_day)s
Hits per day: %(hits_per_day)s
Misses per day: %(misses_per_day)s
Attack penalties: %(attacks)s
"""%(option))
option1 = dict(
name="Many attacks with Fiery Fist",
attacks=[0,0,0,0,-5],
ac=ac,
stuns=10,
stun_save=0,
stunned_ac_loss=0,
total_stuns=0,
str_mod=3,
dmg=damage_roll_a,
total_dmg=0,
)
option2 = dict(
name="High-hit Fiery Fist",
attacks=[2,2,2],
ac=ac,
str_mod=4,
stuns=16,
stun_save=0,
stunned_ac_loss=0,
total_stuns=0,
dmg=damage_roll_a,
total_dmg=0,
)
option3 = dict(
name="Many attacks with Stunning Fist",
attacks=[0,0,0,0,-5],
ac=ac,
stuns=10,
stun_save=10+level+1,
stunned_ac_loss=stunned_ac_loss,
total_stuns=0,
str_mod=3,
dmg=damage_roll_b,
total_dmg=0,
)
option4 = dict(
name="High-hit Stunning Fist",
attacks=[2,2,2],
ac=ac,
str_mod=4,
stuns=10,
stun_save=10+level+2+2+1,
stunned_ac_loss=stunned_ac_loss,
total_stuns=0,
dmg=damage_roll_b,
total_dmg=0,
)
print("Calculating damage at %s rounds per day over %s days for ACs of %s"%(rounds, days, ac))
calc_hits(option1)
calc_hits(option2)
calc_hits(option3)
calc_hits(option4)