Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # elemental shaman biscalc in ruby
- #
- #
- # v3: gems no longer hardcoded but chosen by staweights
- # v4: profession perks added (jewelcrafting NYI)
- # v4.1: changing profs/stat weights will re-gem, re-enchant and recalculate reforgings
- # v4.2: added two-handed weapon support
- # v4.3: added toggles for legendary weapon socket and meta and sorted settings a bit
- ##--------------------------------------------------------------------------------
- ##
- ## things you might want to change:
- ##
- ##--------------------------------------------------------------------------------
- #--------------------------------------------------------------------------------
- #
- # setup character professions (partially NYI)
- #
- #--------------------------------------------------------------------------------
- $profs = {
- "alc" => 0, # alchemy (not relevant for simcraft?)
- "bla" => 1, # blacksmithing (prismatic sockets on wrists and hands)
- "enc" => 1, # enchanting (160 int enchant on rings
- "eng" => 0, # engineering (synapse springs on hands)
- "her" => 0, # herbalism (not relevant for simcraft?)
- "ins" => 0, # inscription (520 int, 100 crit on shoulders)
- "jew" => 0, # jewelcrafting NYI
- "lea" => 0, # leatherworking (500 int on wrists)
- "min" => 0, # mining
- "ski" => 0, # skinning
- "tai" => 0 # tailoring (lightweave emroidery on back)
- }
- $wrathion_weapon_socket = true
- $wrathion_meta = true
- #--------------------------------------------------------------------------------
- #
- # statweights
- #
- #--------------------------------------------------------------------------------
- #puts "#{Time.now-$t_start} setting up gems & statweights"
- # $w = Hash["int" => 4.64, "splpwr" => 3.66, "spi" => 5.23, "hit" => 5.23, "haste" => 2.51, "mastery" => 2.36, "crit" => 2.29] #t15hc bis
- $w = Hash["int" => 4.42, "splpwr" => 3.47, "spi" => 5.05, "hit" => 5.05, "haste" => 2.47, "mastery" => 2.31, "crit" => 1.98] # oxi 20130430
- $wnh = $w.dup # statweights without hit/spi
- $wnh["spi"] = 0
- $wnh["hit"] = 0
- ##--------------------------------------------------------------------------------
- ##
- ## things you shouldn't change (unless you know what you're doing )
- ##
- ##--------------------------------------------------------------------------------
- require 'yaml'
- require 'net/http'
- require 'rexml/document'
- $t_start = Time.now
- $startid = 0 # NYI: resume calculating sets at this index
- $startmax = 0 # NYI: set maximum value for resuming
- $maxhit = 5200 # maximum allowable combined hit & spi after reforging
- $infile = "" # item base to use
- $outfolder = "" # folder to output to
- $addItems = [] # array of items to add to itemBase
- $remItems = [] # array of items to remove from itemBase
- $debug = false # outputs some debug information (only duration of reforge-calls atm)
- def timedMsg(msg)
- time = Time.now-$t_start
- time = "%010.4f" % time
- puts time + " " + msg
- end
- #--------------------------------------------------------------------------------
- #
- # parse options
- #
- #--------------------------------------------------------------------------------
- while ARGV.length >= 2 do
- switch = ARGV.shift
- case switch
- when "-i","-input"
- $infile = ARGV.shift
- when "-o","-output"
- $outfolder = ARGV.shift
- if File.directory?($outfolder) == false then
- Dir.mkdir($outfolder)
- end
- when "-a","-add"
- while (ARGV.length > 0) and (ARGV[0][0] != "-") do
- $addItems.push(ARGV.shift.to_i)
- end
- when "-r","-remove"
- while (ARGV.length > 0) and (ARGV[0][0] != "-") do
- $remItems.push(ARGV.shift.to_i)
- end
- else
- puts "unknown option \"#{switch}\""
- puts "usage:"
- puts "-i(nput) <inputfile>"
- puts "-o(utput) <outputfolder>"
- puts "-a(dd) <itemIDs>"
- puts "-r(emove) <itemIDs>"
- exit
- end
- end
- #--------------------------------------------------------------------------------
- #
- # setup stat prios for reforging
- #
- #--------------------------------------------------------------------------------
- timedMsg("setting up stats & gems")
- $nonhitrefstats = Hash["mastery" => $w["mastery"], "haste" => $w["haste"], "crit" => $w["crit"]]
- $nonhitrefstats = $nonhitrefstats.sort_by {|_key, value| value}
- $high, $medium, $low = $nonhitrefstats[2][0], $nonhitrefstats[1][0], $nonhitrefstats[0][0]
- #--------------------------------------------------------------------------------
- #
- # setup stat prios for reforging
- #
- #--------------------------------------------------------------------------------
- $gemsByColor = {
- "r" => [
- [
- "160int",
- 160*$w["int"],
- 160*$wnh["int"],
- Hash["int" => 160],
- 0
- ],
- [
- "80int_160#{$high}",
- 80*$w["int"]+160*$w[$high],
- 80*$wnh["int"]+160*$wnh[$high],
- Hash["int" => 80, $high => 160],
- 0
- ]
- ],
- "y" => [
- [
- "80int_160#{$high}",
- 80*$w["int"]+160*$w[$high],
- 80*$wnh["int"]+160*$wnh[$high],
- Hash["int" => 80, $high => 160],
- 1
- ],
- [
- "320#{$high}",
- 320*$w[$high],
- 320*$wnh[$high],
- Hash[$high => 320],
- 1
- ]
- ],
- "b" => [
- [
- "80int_160spi",
- 80*$w["int"]+160*$w["spi"],
- 80*$wnh["int"]+160*$wnh["spi"],
- Hash["int" => 80, "spi" => 160],
- 2
- ],
- [
- "160#{$high}_160spi",
- 160*$w[$high]+160*$w["spi"],
- 160*$wnh[$high]+160*$wnh["spi"],
- Hash[$high => 160, "spi" => 160],
- 2
- ]
- ]
- }
- if $wration_meta then
- $gemsByColor["m"] = [[
- "sinister_primal",
- 324*$w["crit"],
- 324*$w["crit"],
- Hash["crit" => 324],
- 3
- ]]
- else
- $gemsByColor["m"] = [[
- "burning_primal",
- 216*$w["int"],
- 216*$w["int"],
- Hash["int" => 216],
- 3
- ]]
- end
- $gemsByColor.each do |sc|
- sc[1].each do |gem|
- sc[1].sort!{ |a,b| b[1] <=> a[1] }
- end
- end
- $allgems = $gemsByColor["r"] + $gemsByColor["y"] + $gemsByColor["b"]
- $allgems.sort!{ |a,b| b[2] <=> a[2]}
- $gemcols = ["red","yellow","blue","meta","prismatic"]
- $maxgemcol = $allgems[0][4]
- $gems = [$gemsByColor["r"][0][0],$gemsByColor["y"][0][0],$gemsByColor["b"][0][0],$gemsByColor["m"][0][0],$allgems[0][0]]
- $gemval = [$gemsByColor["r"][0][1],$gemsByColor["y"][0][1],$gemsByColor["b"][0][1],$gemsByColor["m"][0][1],$allgems[0][1]]
- $gemstats = [$gemsByColor["r"][0][3],$gemsByColor["y"][0][3],$gemsByColor["b"][0][3],$gemsByColor["m"][0][3],$allgems[0][3]]
- #$gems = ["160int","80int_160#{$high}","80int_160spi","sinister_primal","160int"]
- #$gemval = [160 * $w["int"], 80 * $w["int"] + 160 * $w[$high], 80 * $w["int"] + 160 * $w["spi"], 324 * $w["crit"],160 * $w["int"]]
- if $debug then
- (0..4).each do |i|
- puts "best #{$gemcols[i]} gem: #{$gems[i]} at #{$gemval[i]}"
- end
- end
- #--------------------------------------------------------------------------------
- #
- # setup classes for items and sets
- #
- #--------------------------------------------------------------------------------
- timedMsg("setting up classes")
- class Item
- def initialize(id, name, slot, int = 0, splpwr = 0, spi = 0, hit = 0, haste = 0, mastery = 0, crit = 0, sockets = nil)
- @id = id
- @name = name
- @slot = slot #head,shoulder,back,chest,wrist,hands,waist,legs,feet,finger,trinket,main_hand,off_hand
- @basestats = Hash["int" => int, "splpwr" => splpwr, "spi" => spi, "hit" => hit, "haste" => haste, "mastery" => mastery, "crit" => crit]
- # setup gems
- @sockets = sockets # array of skt colors, bonus value, bonus stat: 0 = red, 1 = yellow, 2 = blue, 3 = meta, 4 = prismatic
- # [1, 2, 3, 180, "int"]
- @gembonus = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- @gemstring = ""
- if @sockets then
- self.gem()
- end
- # setup enchants
- @enchantbonus = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- @enchantstring = ""
- self.enchant()
- # setup reforging
- @reforges = []
- self.getRefs()
- @refindex = nil
- @refstring = ""
- end
- def getName
- out = @name
- end
- def getID
- out = @id
- end
- def getSpiHit()
- spihit = @basestats["spi"] + @basestats["hit"] + @gembonus["spi"] + @gembonus["hit"] + @enchantbonus["spi"] + @enchantbonus["hit"]# + @reforgebonus["spi"] + @reforgebonus["hit"]
- end
- def getReforgableSpiHit()
- out = @basestats["spi"] + @basestats["hit"]
- end
- def reforge()
- maxval = 0
- maxref = nil
- (0..@reforges.length-1).each do |r|
- self.setReforge(r)
- tempval = self.getValue
- if tempval > maxval then
- maxval = tempval
- maxref = r
- end
- end
- self.setReforge(maxref)
- end
- def getValue()
- value = 0
- stats = $w.keys
- stats.each do |s|
- # if (s != "spi") and (s != "hit") then
- value += @basestats[s] * $w[s]
- value += @gembonus[s] * $w[s]
- value += @enchantbonus[s] * $w[s]
- #value += @reforgebonus[s] * $w[s]
- # end
- end
- out = value
- end
- def getStats()
- itemstats = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- stats = $w.keys
- stats.each do |s|
- itemstats[s] += @basestats[s]
- itemstats[s] += @gembonus[s]
- itemstats[s] += @enchantbonus[s]
- #itemstats[s] += @reforgebonus[s]
- end
- out = itemstats
- end
- def enchant()
- @enchantbonus.each do |k,v|
- @enchantbonus[k] = 0
- end
- case @slot
- when "shoulders"
- if $profs["ins"] == 1 then
- @enchantbonus["int"] += 520
- @enchantbonus["crit"] += 100
- enchantstring = ",enchant=520int_100crit"
- else
- @enchantbonus["int"] += 200
- @enchantbonus["crit"] += 100
- enchantstring = ",enchant=200int_100crit"
- end
- when "back"
- if $profs["tai"] == 1 then
- enchantstring = ",enchant=lightweave_embroidery_3"
- else
- @enchantbonus["int"] += 180
- enchantstring = ",enchant=180int"
- end
- when "chest"
- @enchantbonus["int"] += 80
- @enchantbonus["spi"] += 80
- enchantstring = ",enchant=80all"
- when "wrists"
- if $profs["lea"] == 1 then
- @enchantbonus["int"] += 500
- enchantstring = ",enchant=500int"
- else
- @enchantbonus["int"] += 180
- enchantstring = ",enchant=180int"
- end
- when "hands"
- @enchantbonus["haste"] += 170
- enchantstring = ",enchant=170haste"
- if $profs["eng"] == 1 then
- enchantstring = "#{enchantstring},addon=synapse_springs_mark_ii"
- end
- when "legs"
- @enchantbonus["int"] += 285
- @enchantbonus["spi"] += 165
- enchantstring = ",enchant=285int_165spi"
- when "feet"
- @enchantbonus["mastery"] += 140
- enchantstring = ",enchant=140mastery"
- when "finger"
- if $profs["enc"] == 1 then
- @enchantbonus["int"] += 160
- enchantstring = ",enchant=160int"
- end
- when "main_hand"
- enchantstring = ",enchant=jade_spirit"
- when "off_hand"
- @enchantbonus["int"] += 165
- enchantstring = ",enchant=165int"
- else
- enchantstring = ""
- end
- @enchantstring = enchantstring
- end
- def gem()
- if @sockets then
- @gembonus.each do |k,v|
- @gembonus[k] = 0
- end
- # calc matching value
- v_match = 0
- @sockets[0..-3].each do |s|
- v_match += $gemval[s]
- end
- v_match += @sockets[-2] * $w[@sockets[-1]]
- #puts "matching value: #{v_match}"
- # calc pure value
- v_pure = 0
- bonus = true
- @sockets[0..-3].each do |s|
- s != 3 ? v_pure += $gemval[4] : v_pure += $gemval[s]
- s != $maxgemcol ? bonus = false : nil
- end
- bonus ? v_pure += @sockets[-2] * $w[@sockets[-1]] : nil
- #puts "pure value: #{v_pure}"
- #construct gemstring
- gemstring = ",gems="
- bonus = true # assume matching sockets
- if v_match >= v_pure then
- @sockets[0..-3].each do |s|
- gemstring += "#{$gems[s]}_"
- $gemstats[s].each do |k,v|
- @gembonus[k] += v
- end
- end
- @gembonus[@sockets[-1]] += @sockets[-2]
- gemstring += "#{@sockets[-2]}#{@sockets[-1]}_"
- else
- @sockets[0..-3].each do |s|
- if s != 3 then
- gemstring += "#{$gems[4]}_"
- s != $maxgemcol ? bonus = false : nil
- $gemstats[4].each do |k,v|
- @gembonus[k] += v
- end
- else
- gemstring += "#{$gems[s]}_"
- $gemstats[s].each do |k,v|
- @gembonus[k] += v
- end
- end
- end
- if bonus then
- gemstring += "#{@sockets[-2]}#{@sockets[-1]}_"
- end
- end
- gemstring.chop!
- @gemstring = gemstring
- end
- end
- # def refSanity(s, t)
- # sensible = true
- # if ((t == "spi") or (t == "hit")) and ((@basestats["spi"] > 0) or (@basestats["hit"] > 0)) then sensible = false end
- # end
- def getRefs()
- hitstats = ["spi", "hit"]
- secstats = ["haste", "mastery", "crit"]
- secstats.sort!{|a,b| $w[b] <=> $w[a]}
- secmin = secstats.sort{|a,b| $w[a] <=> $w[b]}
- refs = Array.new
- sources, targets = Array.new, Array.new
- secstats.each do |s|
- @basestats[s] > 0 ? sources.push(s) : targets.push(s)
- end
- #get all refs that take hit/spi and turn it into sth else
- hitstats.each do |s|
- if @basestats[s] > 0 then
- amnt = (0.4*@basestats[s]).floor
- secstats.each do |t|
- if @basestats[t] == 0 then
- refs.push([s,t,amnt])
- break
- end
- end
- end
- end
- #get all refs from any stat to hit/spi if not on the item yet
- if (@basestats["spi"] == 0) and (@basestats["hit"] == 0) then
- secmin.each do |s|
- if @basestats[s] > 0 then
- amnt = (0.4*@basestats[s]).floor
- refs.push([s,"spi",amnt])
- break
- end
- end
- end
- #get minsource to maxtarget
- secmin.each do |s|
- if @basestats[s] > 0 then
- amnt = (0.4*@basestats[s]).floor
- secstats.each do |t|
- if (@basestats[t] == 0) and ($w[t] > $w[s]) then
- refs.push([s,t,amnt])
- break
- end
- end
- break
- end
- end
- # add no-reforge option if applicable
- # only one stat, either spi, hit or highest sec
- numstats = 0
- (secstats+hitstats).each do |s|
- if @basestats[s] > 0 then
- numstats += 1
- end
- end
- if (numstats == 1) and ((@basestats["hit"] > 0) or (@basestats["spi"] > 0) or (@basestats[secstats[0]] > 0)) then
- refs.push(nil)
- elsif (numstats == 2) and (((@basestats["hit"] > 0) and (@basestats[secstats[0]] > 0)) or ((@basestats["spi"] > 0) and (@basestats[secstats[0]] > 0)) or ((@basestats[secstats[1]] > 0) and (@basestats[secstats[0]] > 0)))
- refs.push(nil)
- end
- if refs.length == 0 then
- refs.push(nil)
- end
- @reforges = refs
- out = refs
- end
- def setReforge(index)
- @refindex = index
- if @reforges[@refindex] != nil then
- @refstring =",reforge=#{@reforges[@refindex][0]}_#{@reforges[@refindex][1]}"
- else
- @refstring = ""
- end
- end
- def getRefIndex
- out = @refindex
- end
- def getReforge()
- out = @reforges[@refindex]
- end
- def getReforges() #deprecated
- refstats = ["spi","hit","haste","mastery","crit"]
- refs = Array.new
- sources, targets = Array.new, Array.new
- refstats.each do |s|
- @basestats[s] > 0 ? sources.push(s) : targets.push(s)
- end
- if (sources.include?("spi") and sources.include?($high)) then
- refs.push(nil)
- refs.push(["spi",$medium])
- elsif (sources.include?("hit") and sources.include?($high)) then
- refs.push(nil)
- refs.push(["hit",$medium])
- elsif (sources.include?("spi") and sources.include?($medium)) then
- refs.push(["spi",$high])
- refs.push([$medium,$high])
- elsif (sources.include?("hit") and sources.include?($medium)) then
- refs.push(["hit",$high])
- refs.push([$medium,$high])
- elsif (sources.include?("spi") and sources.include?($low)) then
- refs.push(["spi",$high])
- refs.push([$low,$high])
- elsif (sources.include?("hit") and sources.include?($low)) then
- refs.push(["hit",$high])
- refs.push([$low,$high])
- elsif (sources.include?($high) and sources.include?($medium)) then
- refs.push(nil)
- refs.push([$medium,"spi"])
- elsif (sources.include?($high) and sources.include?($low)) then
- refs.push([$low,"spi"])
- refs.push([$low,$medium])
- elsif (sources.include?($medium) and sources.include?($low)) then
- refs.push([$low,"spi"])
- refs.push([$low,$high])
- elsif (sources.length == 1) then
- if sources.include?("spi") then
- refs.push(nil)
- refs.push(["spi",$high])
- elsif sources.include?("hit") then
- refs.push(nil)
- refs.push(["hit",$high])
- elsif sources.include?($high) then
- refs.push(nil)
- refs.push([$high,"spi"])
- elsif sources.include?($medium) then
- refs.push([$medium,"spi"])
- refs.push([$medium,$high])
- elsif sources.include?($low) then
- refs.push([$low,"spi"])
- refs.push([$low,$high])
- end
- else
- refs.push(nil)
- end
- # puts "sources: #{sources.to_s}"
- # puts "targets: #{targets.to_s}"
- # puts "refs: #{refs.to_s}"
- end
- def getNumReforges()
- out = @reforges.length
- end
- def to_s # only for debugging
- out = "itemID\t\t#@id\nName\t\t#@name\nSlot\t\t#@slot\nBase Stats\nInt\t\t#{@basestats["int"]}\nSpellpower\t#{@basestats["splpwr"]}\nSpirit\t\t#{@basestats["spi"]}\nHit Rating\t#{@basestats["hit"]}\nHaste Rating\t#{@basestats["haste"]}\nMastery Rating\t#{@basestats["mastery"]}\nCrit Rating\t#{@basestats["crit"]}\nEnchant\t\t#@enchantstring\n\t\t#{@enchantbonus.to_s}\nGems\t\t#@gemstring\n\t\t#{@gembonus.to_s}\nReforge\t\t#{@reforgestring}\n\t\t#{@reforgebonus.to_s}"
- end
- def getSimc(slotnmbr = "")
- #clean up the item name
- name = @name.gsub(" ", "_") # space to underscore
- name.gsub!("'", "") # remove apostrophes
- name.gsub!(",", "") # remove commata
- name.gsub!("-", "") # remove dashes
- name.downcase!
- out = "#@slot#{slotnmbr}=#{name},id=#@id#{@gemstring}#{@enchantstring}#{@refstring}"
- end
- end
- class ItemSet
- # $items = [$setslots, $neck, $back, $wrists, $waist, $feet, $fingers, $trinkets, $main_hand, $off_hand]
- # def initialize(head, neck, shoulders, back, chest, wrists, hands, waist, legs, feet, finger1, finger2, trinket1, trinket2, main_hand, off_hand)
- # @slots = [head, neck, shoulders, back, chest, wrists, hands, waist, legs, feet, finger1, finger2, trinket1, trinket2, main_hand, off_hand]
- # end
- def initialize(setItems)
- @slots = setItems.flatten
- @reforgebonus = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- end
- def getSpiHit()
- spihit = 0
- @slots.each do |s|
- spihit += s.getSpiHit
- end
- spihit += @reforgebonus["spi"] + @reforgebonus["hit"]
- result = spihit
- end
- def getReforgableSpiHit()
- spihit = 0
- @slots.each do |s|
- spihit += s.getReforgableSpiHit
- end
- out = spihit
- end
- def to_s
- @slots.each do |s|
- out = s.to_s
- end
- end
- def getSimc
- temp = ""
- slotnmbr = 0
- @slots.each do |s|
- case slotnmbr
- when 2, 4
- nmbrstr = "1"
- when 3, 5
- nmbrstr = "2"
- else
- nmbrstr = ""
- end
- temp += "#{s.getSimc(nmbrstr)}\n"
- slotnmbr += 1
- end
- out = temp
- end
- def calcrefs(a, b)
- if a.length == 1 then
- a[0].each do |i|
- set = b.dup
- set.push(i)
- # do ref related stuff here
- # set reforges for all items
- (0..set.length-1).each do |index|
- if @slots[index].getRefIndex != set[index] then
- @slots[index].setReforge(set[index])
- end
- end
- # reset reforgebonus to 0
- @reforgebonus = Hash["spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- # recalculate reforgebonus
- @slots.each do |s|
- ref = s.getReforge
- if ref != nil then
- @reforgebonus[ref[0]] -= ref[2]
- @reforgebonus[ref[1]] += ref[2]
- end
- end
- # check for hitcap
- if self.getSpiHit < $maxhit then
- tempval = self.getValue
- if tempval > @refmaxval then
- @refmaxval = tempval
- @refmaxref = set
- @refmaxrefbonus = @reforgebonus
- end
- end
- end
- else
- ta = a.dup
- fa = ta.shift
- fa.each do |i|
- tb = b.dup
- tb.push(i)
- calcrefs(ta, tb)
- end
- end
- end
- def reforge
- if $debug then mstart = Time.now end
- @refmaxval = 0
- @refmaxref = nil
- @refmaxrefbonus = nil
- refarr = []
- @slots.each do |s|
- refarr.push(Array(0..s.getNumReforges-1))
- end
- calcrefs(refarr, [])
- # (0..@slots[0].getNumReforges-1).each do |he|
- # @slots[0].setReforge(he)
- # (0..@slots[1].getNumReforges-1).each do |ne|
- # @slots[1].setReforge(ne)
- # (0..@slots[2].getNumReforges-1).each do |sh|
- # @slots[2].setReforge(sh)
- # (0..@slots[3].getNumReforges-1).each do |ba|
- # @slots[3].setReforge(ba)
- # (0..@slots[4].getNumReforges-1).each do |ch|
- # @slots[4].setReforge(ch)
- # (0..@slots[5].getNumReforges-1).each do |wr|
- # @slots[5].setReforge(wr)
- # (0..@slots[6].getNumReforges-1).each do |ha|
- # @slots[6].setReforge(ha)
- # (0..@slots[7].getNumReforges-1).each do |wa|
- # @slots[7].setReforge(wa)
- # (0..@slots[8].getNumReforges-1).each do |le|
- # @slots[8].setReforge(le)
- # (0..@slots[9].getNumReforges-1).each do |fe|
- # @slots[9].setReforge(fe)
- # (0..@slots[10].getNumReforges-1).each do |f1|
- # @slots[10].setReforge(f1)
- # (0..@slots[11].getNumReforges-1).each do |f2|
- # @slots[11].setReforge(f2)
- # (0..@slots[12].getNumReforges-1).each do |t1|
- # @slots[12].setReforge(t1)
- # (0..@slots[13].getNumReforges-1).each do |t2|
- # @slots[13].setReforge(t2)
- # (0..@slots[14].getNumReforges-1).each do |mh|
- # @slots[14].setReforge(mh)
- # (0..@slots[15].getNumReforges-1).each do |oh|
- # @slots[15].setReforge(oh)
- # @reforgebonus = Hash["spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- # (0..15).each do |s|
- # ref = @slots[s].getReforge
- # if ref != nil then
- # @reforgebonus[ref[0]] -= ref[2]
- # @reforgebonus[ref[1]] += ref[2]
- # end
- # end
- # if self.getSpiHit < $maxhit then
- # tempval = self.getValue
- # if tempval > maxval then
- # maxval = tempval
- # maxref = [he,ne,sh,ba,ch,wr,ha,wa,le,fe,f1,f2,t1,t2,mh,oh]
- # maxrefbonus = @reforgebonus
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- # end
- if @refmaxref == nil then
- #puts "#{Time.now-$t_start} can't reforge set to below #$maxhit hit"
- else
- (0..@slots.length-1).each do |s|
- @slots[s].setReforge(@refmaxref[s])
- end
- @reforgebonus = @refmaxrefbonus
- end
- if $debug then
- mend = Time.now
- dur = mend - mstart
- puts "ItemSet::reforge took #{dur} seconds"
- end
- end
- def getStats()
- totalStats = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- @slots.each do |s|
- # puts s
- itemStats = s.getStats
- totalStats.keys.each do |k|
- totalStats[k] += itemStats[k]
- end
- end
- @reforgebonus.keys.each do |k|
- totalStats[k] += @reforgebonus[k]
- end
- out = totalStats
- end
- def getValue()
- # if $debug then mstart = Time.now end
- totalStats = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
- @slots.each do |s|
- # puts s
- itemStats = s.getStats
- totalStats.keys.each do |k|
- totalStats[k] += itemStats[k]
- end
- end
- @reforgebonus.keys.each do |k|
- totalStats[k] += @reforgebonus[k]
- end
- value = 0
- if (totalStats["spi"] + totalStats["hit"]).between?(5100,$maxhit) then
- totalStats.keys.each do |s|
- if (s != "spi") and (s != "hit") then
- value += totalStats[s] * $w[s]
- end
- end
- end
- # if totalStats["spi"] + totalStats["hit"] > 5100 then
- # value -= (totalStats["spi"] + totalStats["hit"] - 5100) * $w["spi"]
- # end
- # if $debug then
- # mend = Time.now
- # dur = mend - mstart
- # puts "ItemSet::getValue took #{dur} seconds"
- # end
- out = value
- end
- end
- #--------------------------------------------------------------------------------
- #
- # load itembase from file and update it if necessary
- #
- #--------------------------------------------------------------------------------
- timedMsg("setting up item base")
- if File.exist?($infile) then
- # load existing data
- $itemBase = YAML::load(File.read($infile))
- else
- # create empty filebase
- $itemBase = Hash.new
- end
- # add new items
- if $addItems.length > 0 then
- timedMsg("adding #{$addItems.length} items from wowhead")
- bonusTrans = {
- "Intellect" => "int",
- "Hit" => "hit",
- "Spirit" => "spi",
- "Haste" => "haste",
- "Mastery" => "mastery",
- "Critical Strike" => "crit"
- }
- socketTrans = {1 => 3, 2 => 0, 4 => 1, 8 => 2}
- slotTrans = {
- 1 => "head",
- 2 => "neck",
- 3 => "shoulders",
- 16 => "back",
- 5 => "chest",
- 9 => "wrists",
- 10 => "hands",
- 6 => "waist",
- 7 => "legs",
- 8 => "feet",
- 11 => "finger",
- 12 => "trinket",
- 14 => "off_hand",
- 23 => "off_hand",
- 13 => "main_hand",
- 17 => "two_hand"
- }
- $addItems.each do |itemID|
- #check if item already exists
- itemExists = false
- $itemBase.keys.each do |key|
- $itemBase[key].each do |i|
- if i.getID == itemID then
- itemExists = true
- timedMsg("Item #{itemID} already exists")
- end
- end
- end
- if itemExists == false then
- timedMsg("adding #{itemID}")
- # uri = URI("http://www.wowhead.com/item=#{itemID}&xml=1")
- # file = File.new("out.txt")
- doc = REXML::Document.new(Net::HTTP.get(URI("http://www.wowhead.com/item=#{itemID}&xml=1")))
- root = doc.root
- str = root.elements[1].elements["jsonEquip"].to_s
- str = str[20..-16]
- str.gsub!("\"","")
- arr = str.split(/[,:]/)
- #puts str + "\n"
- #puts arr.to_s
- hsh = Hash[*arr]
- #puts hsh.to_s
- #hit = hsh["hitrtng"].to_i
- tooltip = root.elements[1].elements["htmlTooltip"].to_s
- strSocketBonus = tooltip.match(/Socket Bonus: \+[0-9]+ [A-za-z ]+/).to_s
- bonusValue = strSocketBonus.match(/[0-9]+/).to_s
- bonusStat = strSocketBonus.match(/[0-9] [A-za-z ]+/).to_s[2..-1]
- #puts bonusValue
- #puts bonusStat
- #puts bonusTrans[bonusStat]
- id = itemID
- puts name = root.elements[1].elements["name"].to_s[15..-11]
- slot = root.elements[1].elements["inventorySlot"].attributes["id"].to_i
- slotName = slotTrans[slot]
- int = hsh["int"].to_i
- splpwr = hsh["splpwr"].to_i
- spi = hsh["spi"].to_i
- hit = hsh["hitrtng"].to_i
- haste = hsh["hastertng"].to_i
- mastery = hsh["mastrtng"].to_i
- crit = hsh["critstrkrtng"].to_i
- sockets = []
- if hsh["socket1"] != nil then sockets.push(socketTrans[hsh["socket1"].to_i].to_i) end
- if hsh["socket2"] != nil then sockets.push(socketTrans[hsh["socket2"].to_i].to_i) end
- if hsh["socket3"] != nil then sockets.push(socketTrans[hsh["socket3"].to_i].to_i) end
- if slotName == "waist" then
- sockets.push(4)
- elsif slotName == "hands" then
- if $profs["bla"] == 1 then
- sockets.push(4)
- end
- elsif slotName == "wrists" then
- if $profs["bla"] == 1 then
- sockets.push(4)
- end
- elsif (slotName == "main_hand") or (slotName == "two_hand") then
- if $wrathion_weapon_socket then
- sockets.push(4)
- end
- end
- if bonusValue != "" then
- sockets.push(bonusValue.to_i)
- sockets.push(bonusTrans[bonusStat])
- end
- if sockets.length == 1 then
- sockets.push(0)
- sockets.push("int")
- end
- if sockets.length == 0 then sockets = nil end
- # if we just added a socket to an item that had none, add a dummy socket bonus to avoid errors
- #puts "sockets: #{sockets}"
- if not ($itemBase.key?(slotName)) then $itemBase[slotName] = Array.new end
- if slotName == "two_hand" then
- simcSlotName = "main_hand"
- else
- simcSlotName = slotName
- end
- $itemBase[slotName].push(Item.new(id,name,simcSlotName,int,splpwr,spi,hit,haste,mastery,crit,sockets))
- end
- end
- end
- # remove old items
- if $remItems.length > 0 then
- timedMsg("removing #{$remItems.length} items")
- $remItems.each do |remID|
- timedMsg("removing #{remID}")
- $itemBase.keys.each do |key|
- $itemBase[key].delete_if{ |a| a.getID == remID }
- end
- end
- end
- # remove duplicates
- $itemBase.keys.each do |key|
- $itemBase[key].uniq!
- end
- # update gems, enchants and reforges in case profs or stat weights changed
- $itemBase.keys.each do |key|
- $itemBase[key].each do |item|
- item.enchant
- item.getRefs
- item.gem
- end
- end
- # write new itemBase to file
- timedMsg("writing updated item base to file")
- outFile = File.open($infile,"w")
- outFile.syswrite($itemBase.to_yaml)
- outFile.close
- #--------------------------------------------------------------------------------
- #
- # build setslots array: head, shoulders, chest, hands, legs with at least 4t15
- #
- #--------------------------------------------------------------------------------
- timedMsg("building setslots array")
- $setslots = Array.new
- $itemBase["head"].each do |he|
- $itemBase["shoulders"].each do |sh|
- $itemBase["chest"].each do |ch|
- $itemBase["hands"].each do |ha|
- $itemBase["legs"].each do |le|
- numset = 0
- he.getName.include?("Witch Doctor") ? numset += 1 : nil
- sh.getName.include?("Witch Doctor") ? numset += 1 : nil
- ch.getName.include?("Witch Doctor") ? numset += 1 : nil
- ha.getName.include?("Witch Doctor") ? numset += 1 : nil
- le.getName.include?("Witch Doctor") ? numset += 1 : nil
- numset >= 4 ? $setslots.push([he,sh,ch,ha,le]) : nil
- end
- end
- end
- end
- end
- #--------------------------------------------------------------------------------
- #
- # build fingers array: all combinations of non-identical rings
- #
- #--------------------------------------------------------------------------------
- timedMsg("building fingers array")
- $fingers = Array.new
- (0..$itemBase["finger"].length-2).each do |f1|
- (f1+1..$itemBase["finger"].length-1).each do |f2|
- $fingers.push([$itemBase["finger"][f1],$itemBase["finger"][f2]])
- end
- end
- #--------------------------------------------------------------------------------
- #
- # build trinkets array: all combinations of non-identical trinkets
- #
- #--------------------------------------------------------------------------------
- timedMsg("building trinkets array")
- $trinkets = Array.new
- (0..$itemBase["trinket"].length-2).each do |t1|
- (t1+1..$itemBase["trinket"].length-1).each do |t2|
- $trinkets.push([$itemBase["trinket"][t1],$itemBase["trinket"][t2]])
- end
- end
- #--------------------------------------------------------------------------------
- #
- # build main/off-hand array
- #
- #--------------------------------------------------------------------------------
- timedMsg("building main-/off-hand array")
- $mohand = Array.new
- (0..$itemBase["main_hand"].length-1).each do |mh|
- (0..$itemBase["off_hand"].length-1).each do |oh|
- $mohand.push([$itemBase["main_hand"][mh],$itemBase["off_hand"][oh]])
- end
- end
- (0..$itemBase["two_hand"].length-1).each do |th|
- $mohand.push($itemBase["two_hand"][th])
- end
- #--------------------------------------------------------------------------------
- #
- # main loop: recursively build, filter, optimize and value sets
- #
- #--------------------------------------------------------------------------------
- def buildSets(items, set)
- if items.length == 1 then
- items[0].each do |i|
- if $num >= $startid then
- curSet = set.dup
- curSet.push(i)
- testset = ItemSet.new(curSet)
- temphit = testset.getSpiHit
- temprefhit = testset.getReforgableSpiHit
- if (temphit - 0.4 * temprefhit < $maxhit) then
- #puts "#{Time.now-$t_start} set #$num has reforgable amount of spirit (#{temphit})"
- testset.reforge
- tempval = testset.getValue
- if tempval > $maxval then
- timedMsg("set #{"%06d" % $num} is new best at #{"%.4f" % tempval}, ~#{"%d" % estRemaining($num)}sec left")
- $maxval = tempval
- $maxset = testset
- outFile = File.open("#{$outfolder}\\#{tempval}.txt","w")
- outFile.syswrite("name=set#{$num}\n")
- outFile.syswrite(testset.getSimc)
- outFile.syswrite("\##{testset.getStats.to_s}")
- outFile.close
- else
- timedMsg("set #{"%06d" % $num} valued #{"%.4f" % tempval} (max: #{"%.4f" % $maxval}), ~#{"%d" % estRemaining($num)}sec left")
- end
- end
- end
- $num += 1
- end
- else
- curItems = items.dup
- curSlot = curItems.pop
- curSlot.each do |i|
- curSet = set.dup
- curSet.push(i)
- buildSets(curItems, curSet)
- end
- end
- end
- # build array of available items, sorted by value
- timedMsg("sorting slot arrays by value")
- $itemBase["neck"].sort!{|a,b| b.getValue <=> a.getValue}
- $itemBase["back"].sort!{|a,b| b.getValue <=> a.getValue}
- $itemBase["wrists"].sort!{|a,b| b.getValue <=> a.getValue}
- $itemBase["waist"].sort!{|a,b| b.getValue <=> a.getValue}
- $itemBase["feet"].sort!{|a,b| b.getValue <=> a.getValue}
- $itemBase["main_hand"].sort!{|a,b| b.getValue <=> a.getValue}
- $itemBase["off_hand"].sort!{|a,b| b.getValue <=> a.getValue}
- #$mohand.sort!{|a,b| b[0].getValue + (b[1].getValue or 0) <=> a[0].getValue + (a[1].getValue or 0)}
- $mohand.sort!{
- |a,b|
- if a.class == Array then
- ta = 0
- a.each do |x|
- ta += x.getValue
- end
- else
- ta = a.getValue
- end
- if b.class == Array then
- tb = 0
- b.each do |x|
- tb += x.getValue
- end
- else
- tb = b.getValue
- end
- tb <=> ta
- }
- $setslots.sort!{|a,b| b[0].getValue + b[1].getValue + b[2].getValue + b[3].getValue + b[4].getValue <=> a[0].getValue + a[1].getValue + a[2].getValue + a[3].getValue + a[4].getValue}
- $fingers.sort!{|a,b| b[0].getValue + b[1].getValue <=> a[0].getValue + a[1].getValue}
- $trinkets.sort!{|a,b| b[0].getValue + b[1].getValue <=> a[0].getValue + a[1].getValue}
- $items = [$setslots, $itemBase["neck"], $itemBase["back"], $itemBase["wrists"], $itemBase["waist"], $itemBase["feet"], $fingers, $trinkets, $mohand]
- #--------------------------------------------------------------------------------
- #
- # establish number of possible sets for estimating remaining time
- #
- #--------------------------------------------------------------------------------
- $numPosSets = $itemBase["neck"].length * $itemBase["back"].length * $itemBase["wrists"].length * $itemBase["waist"].length * $itemBase["feet"].length * $mohand.length * $setslots.length * $fingers.length * $trinkets.length
- timedMsg("setup finished, #{$numPosSets} possible sets will be analyzed")
- def estRemaining(num)
- remaining = (Time.now - $t_start) * ($numPosSets - num) / num
- end
- # main program
- timedMsg("starting main loop")
- #puts $trinket[2].to_s
- #puts $trinket[2].getRefs.to_s
- $num = 0
- $maxval = $startmax
- $maxset = nil
- buildSets($items, [])
Add Comment
Please, Sign In to add comment