Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Simulator of Machinist DPS
- #Cascadi @ FFXIV Forums
- #Last updated: 7/14/2015
- import random
- random.seed(0)
- #you can edit this
- #dex potion and crits implemented
- #stats implemented
- #once you finish inputing your opener, cds will be used whenever they are available, input as a string with _ for spaces
- #ex. prev_custom_opener = ["reload","split_shot","hawks_eye"]
- #gauss_barrel_start means if you will start with gauss barrel on
- #starting_ammo means how much ammo you start with
- #gcd means what your Recast timer (Global Cooldown) is
- #gauss_barrel_always_on means if you'll have Gauss Barrel up for the whole time instead of toggling it on and off
- #how_many_sims means how many times you want to run the simulation
- gauss_barrel_start = True
- prev_custom_opener = ["blood_for_blood","hypercharge","gauss_round","hot_shot","raging_strikes","hawks_eye","lead_shot","rapid_fire","reload","split_shot","wildfire","slug_shot","potion","split_shot","reassemble","clean_shot","quick_reload","gauss_round","slug_shot","ricochet","head_graze","clean_shot","blank"]
- starting_ammo = 0
- parse_time = 240
- gauss_barrel_always_on = False
- how_many_sims = 1
- DEX = 955.0
- AA_DMG = 57.2
- AA_DELAY = 2.64
- SKILLSPEED = 611.0
- DET = 450.0
- CRIT = 679.0
- WD = 65.0
- #don't edit the below
- gcd = 0
- TEMP_DEX = 0.0
- list_of_results = []
- list_of_skills = []
- custom_opener = []
- ammo = 0
- parse_tick = 0.01
- gauss_barrel = False
- reassemble = False
- hot_shot = 300
- lead_shot = 0
- lead_shot_cd = 300
- blood_for_blood = 0
- raging_strikes = 0
- hypercharge = 0
- hawks_eye = 0
- rapid_fire = 0
- wildfire = 0
- potion = 0
- reassemble = False
- aa = 0
- wildfire_damage = 0.0
- turret_hit = 0
- #rotation
- def rotations(temp_time):
- #variables
- global hot_shot
- global lead_shot
- global lead_shot_potency
- global lead_shot_cd
- global blood_for_blood
- global raging_strikes
- global hypercharge
- global hawks_eye
- global rapid_fire
- global wildfire
- global reassemble
- global potion
- global wildfire_damage
- global gauss_barrel
- global starting_ammo
- global ammo
- global aa
- global DEX
- global TEMP_DEX
- global AA_DMG
- global AA_DELAY
- global CRIT
- global DET
- global SKILLSPEED
- global WD
- global gcd
- global parse_tick
- global parse_time
- global total_damage
- global list_of_skills
- TEMP_DEX = DEX
- ammo = starting_ammo
- custom_opener = prev_custom_opener[:]
- slug_shot = False
- clean_shot = False
- blood_for_blood_cd = 900
- raging_strikes_cd = 1800
- hypercharge_cd = 1200
- hawks_eye_cd = 900
- rapid_fire_cd = 900
- wildfire_cd = 900
- reassemble_cd = 600
- potion_cd = 2700
- ricochet = 600
- blank = 300
- head_graze = 250
- gauss_round = 200
- remover = 0
- turret_delay = 0
- hot_shot = 300
- lead_shot = 0
- lead_shot_cd = 300
- m_reload = 600
- quick_reload = 300
- rapid_fire_count = 0
- t_gcd = gcd
- c_gcd = 0
- o_gcd = 0
- turret_potency = 80.0
- total_damage = 0.0
- #let's calculate gcd
- gcd = 2.50256-(0.01*(SKILLSPEED-354.0)/26.5)
- #start with gauss barrel?
- if(gauss_barrel_start == True):
- list_of_skills.append("gauss_barrel_on")
- gauss_barrel = True
- #parse update
- while(temp_time > 0):
- #gauss barrel always on?
- if(gauss_barrel_always_on == True and gauss_barrel == False):
- list_of_skills.append("gauss_barrel_on")
- gauss_barrel = True
- temp_time -= parse_tick
- c_gcd += parse_tick
- o_gcd += parse_tick
- hot_shot += parse_tick
- lead_shot_cd += parse_tick
- blood_for_blood_cd += parse_tick
- raging_strikes_cd += parse_tick
- hypercharge_cd += parse_tick
- hawks_eye_cd += parse_tick
- rapid_fire_cd += parse_tick
- wildfire_cd += parse_tick
- reassemble_cd += parse_tick
- quick_reload += parse_tick
- potion_cd += parse_tick
- m_reload += parse_tick
- ricochet += parse_tick
- gauss_round += parse_tick
- blood_for_blood -= parse_tick
- raging_strikes -= parse_tick
- hypercharge -= parse_tick
- hawks_eye -= parse_tick
- wildfire -= parse_tick
- potion -= parse_tick
- #let's calculate turret damage
- turret_delay += parse_tick
- if(turret_delay >= 3.0 and temp_time > 0):
- potency_mod = 1.0
- turret_hit = ((turret_potency/100)*(WD/25+1)*(TEMP_DEX/9*1.2)*(DET/7290+1)*potency_mod)-1.5
- if(random.uniform(0.0,100.0) <= ((CRIT-354)*0.0233)+4.9511233):
- potency_mod *= ((CRIT-354)*0.000233)+1.4483610
- if(hypercharge > 0):
- potency_mod *= 1.05
- if(hypercharge > 10):
- turret_hit += ((turret_potency/100)*(WD/25+1)*(TEMP_DEX/9*1.2)*(DET/7290+1)*potency_mod)-1.5
- if(wildfire_cd > 0):
- wildfire_damage += turret_hit
- total_damage += turret_hit
- list_of_skills.append("turret hit - " + str(turret_hit))
- turret_delay = 0
- #let's check lead shot DoT
- lead_shot -= parse_tick
- if(lead_shot % 3 <= parse_tick and lead_shot > 0):
- potency_mod = 1.0
- if(random.uniform(0.0,100.0) <= ((CRIT-354)*0.0233)+4.9511233):
- potency_mod *= ((CRIT-354)*0.000233)+1.4483610
- total_damage += (lead_shot_potency * potency_mod)
- if(wildfire > 0):
- wildfire_damage += (lead_shot_potency * potency_mod)
- #GB recast time
- remover -= parse_tick
- #if no custom opener defined
- if(len(custom_opener) == 0):
- # gcd skill rotation
- if(c_gcd >= t_gcd):
- if(rapid_fire > 0):
- rapid_fire -= 1
- c_gcd = 0
- if(hot_shot >= 30):
- add_potency("hot_shot")
- if(ammo > 0):
- ammo -= 1
- hot_shot = 0
- elif(lead_shot_cd >= 30):
- add_potency("lead_shot")
- if(ammo > 0):
- ammo -= 1
- lead_shot = 30 + parse_tick
- lead_shot_cd = 0
- else:
- if(clean_shot == True):
- if(ammo > 0):
- if(reassemble_cd >= 60):
- list_of_skills.append("reassemble")
- reassemble = True
- add_potency("clean_shot")
- clean_shot = False
- reassemble_cd = 0
- ammo -= 1
- else:
- add_potency("clean_shot")
- clean_shot = False
- elif(ammo == 0):
- add_potency("clean_shot")
- clean_shot = False
- elif(slug_shot == True):
- add_potency("slug_shot")
- slug_shot = False
- if(ammo > 0):
- ammo -= 1
- clean_shot = True
- else:
- rng = random.randint(0, 100)
- if(rng >= 50):
- clean_shot = True
- else:
- add_potency("split_shot")
- if(ammo > 0):
- ammo -= 1
- slug_shot = True
- else:
- rng = random.randint(0, 100)
- if(rng >= 50):
- slug_shot = True
- # buffs and mmo
- if(o_gcd >= 1):
- o_gcd = 0
- if(ammo < 5):
- if(m_reload >= 60 and ammo == 0):
- list_of_skills.append("reload")
- m_reload = 0
- ammo = 5
- elif(quick_reload >= 30 and slug_shot == True):
- list_of_skills.append("quick_reload")
- quick_reload = 0
- ammo += 1
- if(potion_cd >= 270):
- list_of_skills.append("potion")
- potion = 15
- potion_cd = 0
- if(raging_strikes_cd >= 180):
- list_of_skills.append("raging_strikes")
- raging_strikes = 20
- raging_strikes_cd = 0
- elif(hawks_eye_cd >= 90):
- list_of_skills.append("hawks_eye")
- hawks_eye = 20
- hawks_eye_cd = 0
- elif(blood_for_blood_cd >= 90):
- list_of_skills.append("blood_for_blood")
- blood_for_blood = 20
- blood_for_blood_cd = 0
- elif(hypercharge_cd >= 120):
- list_of_skills.append("hypercharge")
- hypercharge = 25
- hypercharge_cd = 0
- elif(wildfire_cd >= 90 and gauss_barrel_always_on == False and gauss_barrel == False):
- list_of_skills.append("gauss_barrel_on")
- gauss_barrel = True
- remover = 15
- elif(wildfire_cd >= 90):
- list_of_skills.append("wildfire")
- wildfire = 15
- wildfire_cd = 0
- elif(rapid_fire_cd >= 90):
- list_of_skills.append("rapid_fire")
- rapid_fire_count = 3
- rapid_fire_cd = 0
- elif(gauss_barrel == True):
- if(ricochet >= 60):
- add_potency("ricochet")
- ricochet = 0
- elif(gauss_round >= 20):
- add_potency("gauss_round")
- gauss_round = 0
- elif(head_graze >= 25):
- add_potency("head_graze")
- head_graze = 0
- elif(blank >= 30):
- add_potency("blank")
- blank = 0
- elif(gauss_barrel_always_on == False and remover <= parse_tick):
- list_of_skills.append("gauss_barrel_off")
- gauss_barrel = False
- elif(head_graze >= 25):
- add_potency("head_graze")
- head_graze = 0
- elif(blank >= 30):
- add_potency("blank")
- blank = 0
- #auto attacks
- if(gauss_barrel == False):
- aa += parse_tick
- if(aa >= AA_DELAY):
- add_potency("auto")
- aa = 0
- #apply wildfire damage
- if(wildfire > 0 and wildfire <= parse_tick):
- total_damage += wildfire_damage * 0.25
- list_of_skills.append("wildfire off - " + str(wildfire_damage * 0.25))
- wildfire_damage = 0
- wildfire = 0
- if(rapid_fire > 0):
- t_gcd = 1.5
- else:
- t_gcd = gcd
- #custom opener happens
- elif(len(custom_opener) > 0):
- list_of_buffs = ["reload","quick reload","raging_strikes","hawks_eye","hypercharge","blood_for_blood","wildfire","rapid_fire","gauss_barrel","gauss_round","ricochet","blank","head_graze"]
- list_of_weaponskills = ["hot_shot","lead_shot","split_shot","slug_shot","clean_shot"]
- #buffs
- if(o_gcd >= 1):
- o_gcd = 0
- if(custom_opener[0] == "reload"):
- list_of_skills.append("reload")
- m_reload = 0
- ammo = 5
- elif(custom_opener[0] == "quick_reload"):
- list_of_skills.append("quick_reload")
- quick_reload = 0
- ammo += 1
- if(custom_opener[0] == "reassemble"):
- list_of_skills.append("reassemble")
- reassemble = True
- reassemble_cd = 0
- elif(custom_opener[0] == "raging_strikes"):
- list_of_skills.append("raging_strikes")
- raging_strikes = 20
- raging_strikes_cd = 0
- elif(custom_opener[0] == "hawks_eye"):
- list_of_skills.append("hawks_eye")
- hawks_eye = 20
- hawks_eye_cd = 0
- elif(custom_opener[0] == "blood_for_blood"):
- list_of_skills.append("blood_for_blood")
- blood_for_blood = 20
- blood_for_blood_cd = 0
- elif(custom_opener[0] == "hypercharge"):
- list_of_skills.append("hypercharge")
- hypercharge = 25
- hypercharge_cd = 0
- elif(custom_opener[0] == "wildfire"):
- list_of_skills.append("wildfire")
- wildfire = 15
- wildfire_cd = 0
- elif(custom_opener[0] == "rapid_fire"):
- list_of_skills.append("rapid_fire")
- rapid_fire_count = 3
- rapid_fire_cd = 0
- elif(custom_opener[0] == "gauss_barrel" and gauss_barrel_always_on == False):
- if(gauss_barrel == True):
- list_of_skills.append("gauss_barrel_off")
- gauss_barrel = False
- else:
- list_of_skills.append("gauss_barrel_on")
- gauss_barrel = True
- remover = 15
- elif(custom_opener[0] == "potion"):
- list_of_skills.append("potion")
- potion = 15
- potion_cd = 0
- elif(custom_opener[0] == "gauss_round"):
- add_potency(custom_opener[0])
- gauss_round = 0
- elif(custom_opener[0] == "ricochet"):
- add_potency(custom_opener[0])
- ricochet = 0
- elif(custom_opener[0] == "blank"):
- add_potency(custom_opener[0])
- blank = 0
- elif(custom_opener[0] == "head_graze"):
- add_potency(custom_opener[0])
- head_graze = 0
- #done with custom opener
- custom_opener.pop(0)
- # gcd skill rotation
- if(c_gcd >= t_gcd):
- if(custom_opener[0] in list_of_weaponskills):
- if(rapid_fire > 0):
- rapid_fire -= 1
- c_gcd = 0
- if(ammo > 0):
- ammo -= 1
- add_potency(custom_opener[0])
- if(custom_opener[0] == "hot_shot"):
- hot_shot = 0
- elif(custom_opener[0] == "lead_shot"):
- lead_shot = 30 + parse_tick
- lead_shot_cd = 0
- #done with custom opener
- custom_opener.pop(0)
- #auto attacks
- if(gauss_barrel == False):
- aa += parse_tick
- if(aa >= AA_DELAY):
- add_potency("auto")
- aa = 0
- #apply wildfire damage
- if(wildfire <= 0):
- total_damage += wildfire_damage * 0.25
- wildfire_damage = 0
- #rapid fire gcd mod
- if(rapid_fire > 0):
- t_gcd = 1.5
- else:
- t_gcd = gcd
- #reset DEX mods
- if(hawks_eye <= parse_tick and potion <= parse_tick):
- TEMP_DEX = DEX
- if(temp_time <= 0):
- list_of_results.append(total_damage / parse_time)
- print "The total damage was: " + str(total_damage) + " over " + str(parse_time) + " seconds. " + "DPS: " + str(total_damage / parse_time)
- print "The skill rotation was: " + str(list_of_skills)
- #uses skill
- def add_potency(skill):
- #variables
- global hot_shot
- global lead_shot
- global lead_shot_potency
- global lead_shot_cd
- global blood_for_blood
- global raging_strikes
- global hypercharge
- global hawks_eye
- global rapid_fire
- global wildfire
- global reassemble
- global wildfire_damage
- global potion
- global gauss_barrel
- global ammo
- global aa
- global AA_DELAY
- global gcd
- global total_damage
- global list_of_skills
- global DEX
- global TEMP_DEX
- global DET
- global AA_DMG
- global AA_DELAY
- global SKILLSPEED
- global CRIT
- global WD
- potency_mod = 1.0
- if(hot_shot > 0):
- potency_mod *= 1.05
- if(blood_for_blood > 0):
- potency_mod *= 1.1
- if(raging_strikes > 0):
- potency_mod *= 1.2
- if(hypercharge > 0):
- potency_mod *= 1.05
- if(hawks_eye > 0 and potion > 0):
- TEMP_DEX = DEX * 1.15 + 84
- elif(hawks_eye > 0):
- TEMP_DEX = DEX * 1.15
- elif(potion > 0):
- TEMP_DEX = DEX + 84
- if(gauss_barrel):
- potency_mod *= 1.3
- if(reassemble):
- potency_mod *= ((CRIT-354)*0.000233)+1.4483610
- reassemble = False
- elif(reassemble == False):
- if(random.uniform(0.0,100.0) < (((CRIT-354)*0.0233)+4.9511233)):
- potency_mod *= ((CRIT-354)*0.000233)+1.4483610
- temp_damage = 0
- ammo_potency = 0
- temp_potency = 0
- eligible_skills = ["hot_shot","lead_shot","split_shot","slug_shot","clean_shot"]
- if(ammo > 0 and skill in eligible_skills):
- ammo_potency += 20.0
- if(skill == "auto"):
- temp_damage = ((AA_DMG/33.04+1)*(TEMP_DEX/6.92)*(DET/6715+1)*(1) * potency_mod) - (1.5*AA_DELAY)
- if(skill == "hot_shot"):
- temp_potency += (120.0 + ammo_potency)
- if(skill == "lead_shot"):
- temp_potency += (40.0 + ammo_potency)
- lead_shot_potency = ((45.0/100)*(WD/25+1)*(TEMP_DEX/9*1.2)*(DET/7290+1)*potency_mod*(1+(SKILLSPEED-354.0)*0.000138))-1.5
- if(skill == "split_shot"):
- temp_potency += (140.0 + ammo_potency)
- if(skill == "slug_shot"):
- temp_potency += (180.0 + ammo_potency)
- if(skill == "clean_shot"):
- temp_potency += (200.0 + ammo_potency)
- if(skill == "blank"):
- temp_potency += 100.0
- if(skill == "head_graze"):
- temp_potency += 100.0
- if(skill == "gauss_round"):
- temp_potency += 180.0
- if(skill == "ricochet"):
- temp_potency += 300.0
- if(skill != "auto"):
- temp_damage = ((temp_potency/100)*(WD/25+1)*(TEMP_DEX/9*1.2)*(DET/7290+1)*potency_mod)-1.5
- #add skill to list
- #if(skill != "auto"):
- list_of_skills.append(skill + " - " + str(temp_damage))
- if(wildfire > 0):
- wildfire_damage += temp_damage
- total_damage += temp_damage
- #perform rotation
- while(how_many_sims > 0):
- rotations(parse_time)
- how_many_sims -= 1
- random.seed(how_many_sims)
- #reset all the variables
- slug_shot = False
- clean_shot = False
- blood_for_blood_cd = 900
- raging_strikes_cd = 1800
- hypercharge_cd = 1200
- hawks_eye_cd = 900
- rapid_fire_cd = 900
- wildfire_cd = 900
- reassemble_cd = 600
- potion_cd = 2700
- ricochet = 600
- blank = 300
- head_graze = 250
- gauss_round = 200
- remover = 0
- hot_shot = 300
- lead_shot = 0
- lead_shot_cd = 300
- m_reload = 600
- quick_reload = 300
- rapid_fire_count = 0
- t_gcd = gcd
- c_gcd = 0
- o_gcd = 0
- turret_potency = 80.0
- total_damage = 0.0
- list_of_skills = []
- gauss_barrel = False
- reassemble = False
- blood_for_blood = 0
- raging_strikes = 0
- hypercharge = 0
- hawks_eye = 0
- rapid_fire = 0
- wildfire = 0
- potion = 0
- reassemble = False
- aa = 0
- wildfire_damage = 0.0
- if(how_many_sims == 0):
- print "The average DPS was: " + str(sum(list_of_results) / len(list_of_results))
- print "The lowest DPS was: " + str(min(list_of_results))
- print "The highest DPS was: " + str(max(list_of_results))
- print "The DPS variance was: " + str((max(list_of_results) - min(list_of_results)) / (sum(list_of_results) / len(list_of_results)) * 100) + "%."
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement