solidity

elemental shaman bis calulator

Apr 30th, 2013
414
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 34.34 KB | None | 0 0
  1. # elemental shaman biscalc in ruby
  2. #
  3. #
  4. # v3:   gems no longer hardcoded but chosen by staweights
  5. # v4:   profession perks added (jewelcrafting NYI)
  6. # v4.1: changing profs/stat weights will re-gem, re-enchant and recalculate reforgings
  7. # v4.2: added two-handed weapon support
  8. # v4.3: added toggles for legendary weapon socket and meta and sorted settings a bit
  9.  
  10. ##--------------------------------------------------------------------------------
  11. ##
  12. ## things you might want to change:
  13. ##
  14. ##--------------------------------------------------------------------------------
  15.  
  16. #--------------------------------------------------------------------------------
  17. #
  18. # setup character professions (partially NYI)
  19. #
  20. #--------------------------------------------------------------------------------
  21. $profs = {
  22.     "alc" => 0, # alchemy (not relevant for simcraft?)
  23.     "bla" => 1, # blacksmithing (prismatic sockets on wrists and hands)
  24.     "enc" => 1, # enchanting (160 int enchant on rings
  25.     "eng" => 0, # engineering (synapse springs on hands)
  26.     "her" => 0, # herbalism (not relevant for simcraft?)
  27.     "ins" => 0, # inscription (520 int, 100 crit on shoulders)
  28.     "jew" => 0, # jewelcrafting NYI
  29.     "lea" => 0, # leatherworking (500 int on wrists)
  30.     "min" => 0, # mining
  31.     "ski" => 0, # skinning
  32.     "tai" => 0  # tailoring (lightweave emroidery on back)
  33. }
  34. $wrathion_weapon_socket = true
  35. $wrathion_meta = true
  36.  
  37. #--------------------------------------------------------------------------------
  38. #
  39. # statweights
  40. #
  41. #--------------------------------------------------------------------------------
  42. #puts "#{Time.now-$t_start} setting up gems & statweights"
  43. # $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
  44. $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
  45. $wnh = $w.dup   # statweights without hit/spi
  46. $wnh["spi"] = 0
  47. $wnh["hit"] = 0
  48.  
  49.  
  50. ##--------------------------------------------------------------------------------
  51. ##
  52. ## things you shouldn't change (unless you know what you're doing )
  53. ##
  54. ##--------------------------------------------------------------------------------
  55.  
  56. require 'yaml'
  57. require 'net/http'
  58. require 'rexml/document'
  59.  
  60.  
  61. $t_start = Time.now
  62.  
  63. $startid = 0        # NYI: resume calculating sets at this index
  64. $startmax = 0       # NYI: set maximum value for resuming
  65. $maxhit = 5200      # maximum allowable combined hit & spi after reforging
  66. $infile = ""        # item base to use
  67. $outfolder = ""     # folder to output to
  68. $addItems = []      # array of items to add to itemBase
  69. $remItems = []      # array of items to remove from itemBase
  70.  
  71. $debug = false      # outputs some debug information (only duration of reforge-calls atm)
  72.  
  73.  
  74.  
  75. def timedMsg(msg)
  76.     time = Time.now-$t_start
  77.     time = "%010.4f" % time
  78.     puts time + " " + msg
  79. end
  80.  
  81. #--------------------------------------------------------------------------------
  82. #
  83. # parse options
  84. #
  85. #--------------------------------------------------------------------------------
  86. while ARGV.length >= 2 do
  87.     switch = ARGV.shift
  88.     case switch
  89.     when "-i","-input"
  90.         $infile = ARGV.shift
  91.     when "-o","-output"
  92.         $outfolder = ARGV.shift
  93.         if File.directory?($outfolder) == false then
  94.             Dir.mkdir($outfolder)
  95.         end
  96.     when "-a","-add"
  97.         while (ARGV.length > 0) and (ARGV[0][0] != "-") do
  98.             $addItems.push(ARGV.shift.to_i)
  99.         end
  100.     when "-r","-remove"
  101.         while (ARGV.length > 0) and (ARGV[0][0] != "-") do
  102.             $remItems.push(ARGV.shift.to_i)
  103.         end
  104.     else
  105.         puts "unknown option \"#{switch}\""
  106.         puts "usage:"
  107.         puts "-i(nput) <inputfile>"
  108.         puts "-o(utput) <outputfolder>"
  109.         puts "-a(dd) <itemIDs>"
  110.         puts "-r(emove) <itemIDs>"
  111.         exit
  112.     end
  113. end
  114.  
  115. #--------------------------------------------------------------------------------
  116. #
  117. # setup stat prios for reforging
  118. #
  119. #--------------------------------------------------------------------------------
  120. timedMsg("setting up stats & gems")
  121. $nonhitrefstats = Hash["mastery" => $w["mastery"], "haste" => $w["haste"], "crit" => $w["crit"]]
  122. $nonhitrefstats = $nonhitrefstats.sort_by {|_key, value| value}
  123. $high, $medium, $low = $nonhitrefstats[2][0], $nonhitrefstats[1][0], $nonhitrefstats[0][0]
  124.  
  125.  
  126. #--------------------------------------------------------------------------------
  127. #
  128. # setup stat prios for reforging
  129. #
  130. #--------------------------------------------------------------------------------
  131. $gemsByColor = {
  132.     "r" => [
  133.         [
  134.             "160int",
  135.             160*$w["int"],
  136.             160*$wnh["int"],
  137.             Hash["int" => 160],
  138.             0
  139.         ],
  140.         [
  141.             "80int_160#{$high}",
  142.             80*$w["int"]+160*$w[$high],
  143.             80*$wnh["int"]+160*$wnh[$high],
  144.             Hash["int" => 80, $high => 160],
  145.             0
  146.         ]
  147.     ],
  148.     "y" => [
  149.         [
  150.             "80int_160#{$high}",
  151.             80*$w["int"]+160*$w[$high],
  152.             80*$wnh["int"]+160*$wnh[$high],
  153.             Hash["int" => 80, $high => 160],
  154.             1
  155.         ],
  156.         [
  157.             "320#{$high}",
  158.             320*$w[$high],
  159.             320*$wnh[$high],
  160.             Hash[$high => 320],
  161.             1
  162.         ]
  163.     ],
  164.     "b" => [
  165.         [
  166.             "80int_160spi",
  167.             80*$w["int"]+160*$w["spi"],
  168.             80*$wnh["int"]+160*$wnh["spi"],
  169.             Hash["int" => 80, "spi" => 160],
  170.             2
  171.         ],
  172.         [
  173.             "160#{$high}_160spi",
  174.             160*$w[$high]+160*$w["spi"],
  175.             160*$wnh[$high]+160*$wnh["spi"],
  176.             Hash[$high => 160, "spi" => 160],
  177.             2
  178.         ]
  179.     ]
  180. }
  181. if $wration_meta then
  182.     $gemsByColor["m"] = [[
  183.         "sinister_primal",
  184.         324*$w["crit"],
  185.         324*$w["crit"],
  186.         Hash["crit" => 324],
  187.         3
  188.     ]]
  189. else
  190.     $gemsByColor["m"] = [[
  191.         "burning_primal",
  192.         216*$w["int"],
  193.         216*$w["int"],
  194.         Hash["int" => 216],
  195.         3
  196.     ]]
  197. end
  198. $gemsByColor.each do |sc|
  199.     sc[1].each do |gem|
  200.         sc[1].sort!{ |a,b| b[1] <=> a[1] }
  201.     end
  202. end
  203. $allgems = $gemsByColor["r"] + $gemsByColor["y"] + $gemsByColor["b"]
  204. $allgems.sort!{ |a,b| b[2] <=> a[2]}
  205. $gemcols = ["red","yellow","blue","meta","prismatic"]
  206. $maxgemcol = $allgems[0][4]
  207. $gems = [$gemsByColor["r"][0][0],$gemsByColor["y"][0][0],$gemsByColor["b"][0][0],$gemsByColor["m"][0][0],$allgems[0][0]]
  208. $gemval = [$gemsByColor["r"][0][1],$gemsByColor["y"][0][1],$gemsByColor["b"][0][1],$gemsByColor["m"][0][1],$allgems[0][1]]
  209. $gemstats = [$gemsByColor["r"][0][3],$gemsByColor["y"][0][3],$gemsByColor["b"][0][3],$gemsByColor["m"][0][3],$allgems[0][3]]
  210. #$gems = ["160int","80int_160#{$high}","80int_160spi","sinister_primal","160int"]
  211. #$gemval = [160 * $w["int"], 80 * $w["int"] + 160 * $w[$high], 80 * $w["int"] + 160 * $w["spi"], 324 * $w["crit"],160 * $w["int"]]
  212. if $debug then
  213.     (0..4).each do |i|
  214.         puts "best #{$gemcols[i]} gem: #{$gems[i]} at #{$gemval[i]}"
  215.     end
  216. end
  217.  
  218.  
  219. #--------------------------------------------------------------------------------
  220. #
  221. # setup classes for items and sets
  222. #
  223. #--------------------------------------------------------------------------------
  224. timedMsg("setting up classes")
  225. class Item
  226.     def initialize(id, name, slot, int = 0, splpwr = 0, spi = 0, hit = 0, haste = 0, mastery = 0, crit = 0, sockets = nil)
  227.         @id = id
  228.         @name = name
  229.         @slot = slot    #head,shoulder,back,chest,wrist,hands,waist,legs,feet,finger,trinket,main_hand,off_hand
  230.         @basestats = Hash["int" => int, "splpwr" => splpwr, "spi" => spi, "hit" => hit, "haste" => haste, "mastery" => mastery, "crit" => crit]
  231.         # setup gems
  232.         @sockets = sockets  # array of skt colors, bonus value, bonus stat: 0 = red, 1 = yellow, 2 = blue, 3 = meta, 4 = prismatic
  233.                             # [1, 2, 3, 180, "int"]
  234.         @gembonus = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  235.         @gemstring = ""
  236.         if @sockets then
  237.             self.gem()
  238.         end
  239.         # setup enchants
  240.         @enchantbonus = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  241.         @enchantstring = ""
  242.         self.enchant()
  243.         # setup reforging
  244.         @reforges = []
  245.         self.getRefs()
  246.         @refindex = nil
  247.         @refstring = ""
  248.     end
  249.    
  250.     def getName
  251.         out = @name
  252.     end
  253.    
  254.     def getID
  255.         out = @id
  256.     end
  257.    
  258.     def getSpiHit()
  259.         spihit = @basestats["spi"] + @basestats["hit"] + @gembonus["spi"] + @gembonus["hit"] + @enchantbonus["spi"] + @enchantbonus["hit"]# + @reforgebonus["spi"] + @reforgebonus["hit"]
  260.     end
  261.    
  262.     def getReforgableSpiHit()
  263.         out = @basestats["spi"] + @basestats["hit"]
  264.     end
  265.    
  266.     def reforge()
  267.         maxval = 0
  268.         maxref = nil
  269.         (0..@reforges.length-1).each do |r|
  270.             self.setReforge(r)
  271.             tempval = self.getValue
  272.             if tempval > maxval then
  273.                 maxval = tempval
  274.                 maxref = r
  275.             end
  276.         end
  277.         self.setReforge(maxref)
  278.     end
  279.    
  280.     def getValue()
  281.         value = 0
  282.         stats = $w.keys
  283.         stats.each do |s|
  284.             # if (s != "spi") and (s != "hit") then
  285.             value += @basestats[s] * $w[s]
  286.             value += @gembonus[s] * $w[s]
  287.             value += @enchantbonus[s] * $w[s]
  288.             #value += @reforgebonus[s] * $w[s]
  289.             # end
  290.         end
  291.         out = value
  292.     end
  293.    
  294.     def getStats()
  295.         itemstats = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  296.         stats = $w.keys
  297.         stats.each do |s|
  298.             itemstats[s] += @basestats[s]
  299.             itemstats[s] += @gembonus[s]
  300.             itemstats[s] += @enchantbonus[s]
  301.             #itemstats[s] += @reforgebonus[s]
  302.         end
  303.         out = itemstats
  304.     end
  305.    
  306.     def enchant()
  307.         @enchantbonus.each do |k,v|
  308.             @enchantbonus[k] = 0
  309.         end
  310.         case @slot
  311.         when "shoulders"
  312.             if $profs["ins"] == 1 then
  313.                 @enchantbonus["int"] += 520
  314.                 @enchantbonus["crit"] += 100
  315.                 enchantstring = ",enchant=520int_100crit"
  316.             else
  317.                 @enchantbonus["int"] += 200
  318.                 @enchantbonus["crit"] += 100
  319.                 enchantstring = ",enchant=200int_100crit"
  320.             end
  321.         when "back"
  322.             if $profs["tai"] == 1 then
  323.                 enchantstring = ",enchant=lightweave_embroidery_3"
  324.             else
  325.                 @enchantbonus["int"] += 180
  326.                 enchantstring = ",enchant=180int"
  327.             end
  328.         when "chest"
  329.             @enchantbonus["int"] += 80
  330.             @enchantbonus["spi"] += 80
  331.             enchantstring = ",enchant=80all"
  332.         when "wrists"
  333.             if $profs["lea"] == 1 then
  334.                 @enchantbonus["int"] += 500
  335.                 enchantstring = ",enchant=500int"
  336.             else
  337.                 @enchantbonus["int"] += 180
  338.                 enchantstring = ",enchant=180int"
  339.             end
  340.         when "hands"
  341.             @enchantbonus["haste"] += 170
  342.             enchantstring = ",enchant=170haste"
  343.             if $profs["eng"] == 1 then
  344.                 enchantstring = "#{enchantstring},addon=synapse_springs_mark_ii"
  345.             end
  346.         when "legs"
  347.             @enchantbonus["int"] += 285
  348.             @enchantbonus["spi"] += 165
  349.             enchantstring = ",enchant=285int_165spi"
  350.         when "feet"
  351.             @enchantbonus["mastery"] += 140
  352.             enchantstring = ",enchant=140mastery"
  353.         when "finger"
  354.             if $profs["enc"] == 1 then
  355.                 @enchantbonus["int"] += 160
  356.                 enchantstring = ",enchant=160int"
  357.             end
  358.         when "main_hand"
  359.             enchantstring = ",enchant=jade_spirit"
  360.         when "off_hand"
  361.             @enchantbonus["int"] += 165
  362.             enchantstring = ",enchant=165int"
  363.         else
  364.             enchantstring = ""
  365.         end
  366.         @enchantstring = enchantstring
  367.     end
  368.    
  369.     def gem()
  370.         if @sockets then
  371.             @gembonus.each do |k,v|
  372.                 @gembonus[k] = 0
  373.             end
  374.             # calc matching value
  375.             v_match = 0
  376.             @sockets[0..-3].each do |s|
  377.                 v_match += $gemval[s]
  378.             end
  379.             v_match += @sockets[-2] * $w[@sockets[-1]]
  380.             #puts "matching value: #{v_match}"
  381.             # calc pure value
  382.             v_pure = 0
  383.             bonus = true
  384.             @sockets[0..-3].each do |s|
  385.                 s != 3 ? v_pure += $gemval[4] : v_pure += $gemval[s]
  386.                 s != $maxgemcol ? bonus = false : nil
  387.             end
  388.             bonus ? v_pure += @sockets[-2] * $w[@sockets[-1]] : nil
  389.             #puts "pure value: #{v_pure}"
  390.            
  391.             #construct gemstring
  392.             gemstring = ",gems="
  393.             bonus = true    # assume matching sockets
  394.             if v_match >= v_pure then
  395.                 @sockets[0..-3].each do |s|
  396.                     gemstring += "#{$gems[s]}_"
  397.                     $gemstats[s].each do |k,v|
  398.                         @gembonus[k] += v
  399.                     end
  400.                 end
  401.                 @gembonus[@sockets[-1]] += @sockets[-2]
  402.                 gemstring += "#{@sockets[-2]}#{@sockets[-1]}_"
  403.             else
  404.                 @sockets[0..-3].each do |s|
  405.                     if s != 3 then
  406.                         gemstring += "#{$gems[4]}_"
  407.                         s != $maxgemcol ? bonus = false : nil
  408.                         $gemstats[4].each do |k,v|
  409.                             @gembonus[k] += v
  410.                         end
  411.                     else
  412.                         gemstring += "#{$gems[s]}_"
  413.                         $gemstats[s].each do |k,v|
  414.                             @gembonus[k] += v
  415.                         end
  416.                     end
  417.                 end
  418.                 if bonus then
  419.                     gemstring += "#{@sockets[-2]}#{@sockets[-1]}_"
  420.                 end
  421.             end
  422.             gemstring.chop!
  423.             @gemstring = gemstring
  424.         end
  425.     end
  426.    
  427.     # def refSanity(s, t)
  428.         # sensible = true
  429.         # if ((t == "spi") or (t == "hit")) and ((@basestats["spi"] > 0) or (@basestats["hit"] > 0)) then sensible = false end
  430.        
  431.     # end
  432.    
  433.     def getRefs()
  434.         hitstats = ["spi", "hit"]
  435.         secstats = ["haste", "mastery", "crit"]
  436.         secstats.sort!{|a,b| $w[b] <=> $w[a]}
  437.         secmin = secstats.sort{|a,b| $w[a] <=> $w[b]}
  438.         refs = Array.new
  439.         sources, targets = Array.new, Array.new
  440.         secstats.each do |s|
  441.             @basestats[s] > 0 ? sources.push(s) : targets.push(s)
  442.         end
  443.         #get all refs that take hit/spi and turn it into sth else
  444.         hitstats.each do |s|
  445.             if @basestats[s] > 0 then
  446.                 amnt = (0.4*@basestats[s]).floor
  447.                 secstats.each do |t|
  448.                     if @basestats[t] == 0 then
  449.                         refs.push([s,t,amnt])
  450.                         break
  451.                     end
  452.                 end
  453.             end
  454.         end
  455.         #get all refs from any stat to hit/spi if not on the item yet
  456.         if (@basestats["spi"] == 0) and (@basestats["hit"] == 0) then
  457.             secmin.each do |s|
  458.                 if @basestats[s] > 0 then
  459.                     amnt = (0.4*@basestats[s]).floor
  460.                     refs.push([s,"spi",amnt])
  461.                     break
  462.                 end
  463.             end
  464.         end
  465.         #get minsource to maxtarget
  466.         secmin.each do |s|
  467.             if @basestats[s] > 0 then
  468.                 amnt = (0.4*@basestats[s]).floor
  469.                 secstats.each do |t|
  470.                     if (@basestats[t] == 0) and ($w[t] > $w[s]) then
  471.                         refs.push([s,t,amnt])
  472.                         break
  473.                     end
  474.                 end
  475.                 break
  476.             end
  477.         end
  478.         # add no-reforge option if applicable
  479.         # only one stat, either spi, hit or highest sec
  480.         numstats = 0
  481.         (secstats+hitstats).each do |s|
  482.             if @basestats[s] > 0 then
  483.                 numstats += 1
  484.             end
  485.         end
  486.         if (numstats == 1) and ((@basestats["hit"] > 0) or (@basestats["spi"] > 0) or (@basestats[secstats[0]] > 0)) then
  487.             refs.push(nil)
  488.         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)))
  489.             refs.push(nil)
  490.         end
  491.         if refs.length == 0 then
  492.             refs.push(nil)
  493.         end
  494.         @reforges = refs
  495.         out = refs
  496.     end
  497.    
  498.     def setReforge(index)
  499.         @refindex = index
  500.         if @reforges[@refindex] != nil then
  501.             @refstring =",reforge=#{@reforges[@refindex][0]}_#{@reforges[@refindex][1]}"
  502.         else
  503.             @refstring = ""
  504.         end
  505.     end
  506.    
  507.     def getRefIndex
  508.         out = @refindex
  509.     end
  510.    
  511.     def getReforge()
  512.         out = @reforges[@refindex]
  513.     end
  514.    
  515.     def getReforges()   #deprecated
  516.         refstats = ["spi","hit","haste","mastery","crit"]
  517.         refs = Array.new
  518.         sources, targets = Array.new, Array.new
  519.         refstats.each do |s|
  520.             @basestats[s] > 0 ? sources.push(s) : targets.push(s)
  521.         end
  522.         if (sources.include?("spi") and sources.include?($high)) then
  523.             refs.push(nil)
  524.             refs.push(["spi",$medium])
  525.         elsif (sources.include?("hit") and sources.include?($high)) then
  526.             refs.push(nil)
  527.             refs.push(["hit",$medium])
  528.         elsif (sources.include?("spi") and sources.include?($medium)) then
  529.             refs.push(["spi",$high])
  530.             refs.push([$medium,$high])
  531.         elsif (sources.include?("hit") and sources.include?($medium)) then
  532.             refs.push(["hit",$high])
  533.             refs.push([$medium,$high])
  534.         elsif (sources.include?("spi") and sources.include?($low)) then
  535.             refs.push(["spi",$high])
  536.             refs.push([$low,$high])
  537.         elsif (sources.include?("hit") and sources.include?($low)) then
  538.             refs.push(["hit",$high])
  539.             refs.push([$low,$high])
  540.         elsif (sources.include?($high) and sources.include?($medium)) then
  541.             refs.push(nil)
  542.             refs.push([$medium,"spi"])
  543.         elsif (sources.include?($high) and sources.include?($low)) then
  544.             refs.push([$low,"spi"])
  545.             refs.push([$low,$medium])
  546.         elsif (sources.include?($medium) and sources.include?($low)) then
  547.             refs.push([$low,"spi"])
  548.             refs.push([$low,$high])
  549.         elsif (sources.length == 1) then
  550.             if sources.include?("spi") then
  551.                 refs.push(nil)
  552.                 refs.push(["spi",$high])
  553.             elsif sources.include?("hit") then
  554.                 refs.push(nil)
  555.                 refs.push(["hit",$high])
  556.             elsif sources.include?($high) then
  557.                 refs.push(nil)
  558.                 refs.push([$high,"spi"])
  559.             elsif sources.include?($medium) then
  560.                 refs.push([$medium,"spi"])
  561.                 refs.push([$medium,$high])
  562.             elsif sources.include?($low) then
  563.                 refs.push([$low,"spi"])
  564.                 refs.push([$low,$high])
  565.             end
  566.         else
  567.             refs.push(nil)
  568.         end
  569.         # puts "sources: #{sources.to_s}"
  570.         # puts "targets: #{targets.to_s}"
  571.         # puts "refs: #{refs.to_s}"
  572.     end
  573.    
  574.     def getNumReforges()
  575.         out = @reforges.length
  576.     end
  577.    
  578.     def to_s    # only for debugging
  579.         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}"
  580.     end
  581.    
  582.     def getSimc(slotnmbr = "")
  583.         #clean up the item name
  584.         name = @name.gsub(" ", "_") # space to underscore
  585.         name.gsub!("'", "")         # remove apostrophes
  586.         name.gsub!(",", "")         # remove commata
  587.         name.gsub!("-", "")         # remove dashes
  588.         name.downcase!
  589.    
  590.         out = "#@slot#{slotnmbr}=#{name},id=#@id#{@gemstring}#{@enchantstring}#{@refstring}"
  591.     end
  592. end
  593.  
  594. class ItemSet
  595.     # $items = [$setslots, $neck, $back, $wrists, $waist, $feet, $fingers, $trinkets, $main_hand, $off_hand]
  596.     # def initialize(head, neck, shoulders, back, chest, wrists, hands, waist, legs, feet, finger1, finger2, trinket1, trinket2, main_hand, off_hand)
  597.         # @slots = [head, neck, shoulders, back, chest, wrists, hands, waist, legs, feet, finger1, finger2, trinket1, trinket2, main_hand, off_hand]
  598.     # end
  599.     def initialize(setItems)
  600.         @slots = setItems.flatten
  601.         @reforgebonus = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  602.     end
  603.    
  604.     def getSpiHit()
  605.         spihit = 0
  606.         @slots.each do |s|
  607.             spihit += s.getSpiHit
  608.         end
  609.         spihit += @reforgebonus["spi"] + @reforgebonus["hit"]
  610.         result = spihit
  611.     end
  612.    
  613.     def getReforgableSpiHit()
  614.         spihit = 0
  615.         @slots.each do |s|
  616.             spihit += s.getReforgableSpiHit
  617.         end
  618.         out = spihit
  619.     end
  620.    
  621.     def to_s
  622.         @slots.each do |s|
  623.             out = s.to_s
  624.         end
  625.     end
  626.    
  627.     def getSimc
  628.         temp = ""
  629.         slotnmbr = 0
  630.         @slots.each do |s|
  631.             case slotnmbr
  632.             when 2, 4
  633.                 nmbrstr = "1"
  634.             when 3, 5
  635.                 nmbrstr = "2"
  636.             else
  637.                 nmbrstr = ""
  638.             end
  639.             temp += "#{s.getSimc(nmbrstr)}\n"
  640.             slotnmbr += 1
  641.         end
  642.         out = temp
  643.     end
  644.    
  645.     def calcrefs(a, b)
  646.         if a.length == 1 then
  647.             a[0].each do |i|
  648.                 set = b.dup
  649.                 set.push(i)
  650.                 # do ref related stuff here
  651.                 # set reforges for all items
  652.                 (0..set.length-1).each do |index|
  653.                     if @slots[index].getRefIndex != set[index] then
  654.                         @slots[index].setReforge(set[index])
  655.                     end
  656.                 end
  657.                 # reset reforgebonus to 0
  658.                 @reforgebonus = Hash["spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  659.                 # recalculate reforgebonus
  660.                 @slots.each do |s|
  661.                     ref = s.getReforge
  662.                     if ref != nil then
  663.                         @reforgebonus[ref[0]] -= ref[2]
  664.                         @reforgebonus[ref[1]] += ref[2]
  665.                     end
  666.                 end
  667.                 # check for hitcap
  668.                 if self.getSpiHit < $maxhit then
  669.                     tempval = self.getValue
  670.                     if tempval > @refmaxval then
  671.                         @refmaxval = tempval
  672.                         @refmaxref = set
  673.                         @refmaxrefbonus = @reforgebonus
  674.                     end
  675.                 end
  676.             end
  677.         else
  678.             ta = a.dup
  679.             fa = ta.shift
  680.             fa.each do |i|
  681.                 tb = b.dup
  682.                 tb.push(i)
  683.                 calcrefs(ta, tb)
  684.             end
  685.         end
  686.     end
  687.    
  688.     def reforge
  689.         if $debug then mstart = Time.now end
  690.         @refmaxval = 0
  691.         @refmaxref = nil
  692.         @refmaxrefbonus = nil
  693.         refarr = []
  694.         @slots.each do |s|
  695.             refarr.push(Array(0..s.getNumReforges-1))
  696.         end
  697.         calcrefs(refarr, [])
  698.         # (0..@slots[0].getNumReforges-1).each do |he|
  699.             # @slots[0].setReforge(he)
  700.             # (0..@slots[1].getNumReforges-1).each do |ne|
  701.                 # @slots[1].setReforge(ne)
  702.                 # (0..@slots[2].getNumReforges-1).each do |sh|
  703.                     # @slots[2].setReforge(sh)
  704.                     # (0..@slots[3].getNumReforges-1).each do |ba|
  705.                         # @slots[3].setReforge(ba)
  706.                         # (0..@slots[4].getNumReforges-1).each do |ch|
  707.                             # @slots[4].setReforge(ch)
  708.                             # (0..@slots[5].getNumReforges-1).each do |wr|
  709.                                 # @slots[5].setReforge(wr)
  710.                                 # (0..@slots[6].getNumReforges-1).each do |ha|
  711.                                     # @slots[6].setReforge(ha)
  712.                                     # (0..@slots[7].getNumReforges-1).each do |wa|
  713.                                         # @slots[7].setReforge(wa)
  714.                                         # (0..@slots[8].getNumReforges-1).each do |le|
  715.                                             # @slots[8].setReforge(le)
  716.                                             # (0..@slots[9].getNumReforges-1).each do |fe|
  717.                                                 # @slots[9].setReforge(fe)
  718.                                                 # (0..@slots[10].getNumReforges-1).each do |f1|
  719.                                                     # @slots[10].setReforge(f1)
  720.                                                     # (0..@slots[11].getNumReforges-1).each do |f2|
  721.                                                         # @slots[11].setReforge(f2)
  722.                                                         # (0..@slots[12].getNumReforges-1).each do |t1|
  723.                                                             # @slots[12].setReforge(t1)
  724.                                                             # (0..@slots[13].getNumReforges-1).each do |t2|
  725.                                                                 # @slots[13].setReforge(t2)
  726.                                                                 # (0..@slots[14].getNumReforges-1).each do |mh|
  727.                                                                     # @slots[14].setReforge(mh)
  728.                                                                     # (0..@slots[15].getNumReforges-1).each do |oh|
  729.                                                                         # @slots[15].setReforge(oh)
  730.                                                                         # @reforgebonus = Hash["spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  731.                                                                         # (0..15).each do |s|
  732.                                                                             # ref = @slots[s].getReforge
  733.                                                                             # if ref != nil then
  734.                                                                                 # @reforgebonus[ref[0]] -= ref[2]
  735.                                                                                 # @reforgebonus[ref[1]] += ref[2]
  736.                                                                             # end
  737.                                                                         # end
  738.                                                                         # if self.getSpiHit < $maxhit then
  739.                                                                             # tempval = self.getValue
  740.                                                                             # if tempval > maxval then
  741.                                                                                 # maxval = tempval
  742.                                                                                 # maxref = [he,ne,sh,ba,ch,wr,ha,wa,le,fe,f1,f2,t1,t2,mh,oh]
  743.                                                                                 # maxrefbonus = @reforgebonus
  744.                                                                             # end
  745.                                                                         # end
  746.                                                                     # end
  747.                                                                 # end
  748.                                                             # end
  749.                                                         # end
  750.                                                     # end
  751.                                                 # end
  752.                                             # end
  753.                                         # end
  754.                                     # end
  755.                                 # end
  756.                             # end
  757.                         # end
  758.                     # end
  759.                 # end
  760.             # end
  761.         # end
  762.         if @refmaxref == nil then
  763.             #puts "#{Time.now-$t_start} can't reforge set to below #$maxhit hit"
  764.         else
  765.             (0..@slots.length-1).each do |s|
  766.                 @slots[s].setReforge(@refmaxref[s])
  767.             end
  768.             @reforgebonus = @refmaxrefbonus
  769.         end
  770.         if $debug then
  771.             mend = Time.now
  772.             dur = mend - mstart
  773.             puts "ItemSet::reforge took #{dur} seconds"
  774.         end
  775.     end
  776.    
  777.     def getStats()
  778.         totalStats = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  779.         @slots.each do |s|
  780.             # puts s
  781.             itemStats = s.getStats
  782.             totalStats.keys.each do |k|
  783.                 totalStats[k] += itemStats[k]
  784.             end
  785.         end
  786.         @reforgebonus.keys.each do |k|
  787.             totalStats[k] += @reforgebonus[k]
  788.         end
  789.         out = totalStats
  790.     end
  791.    
  792.     def getValue()
  793.         # if $debug then mstart = Time.now end
  794.         totalStats = Hash["int" => 0, "splpwr" => 0, "spi" => 0, "hit" => 0, "haste" => 0, "mastery" => 0, "crit" => 0]
  795.         @slots.each do |s|
  796.             # puts s
  797.             itemStats = s.getStats
  798.             totalStats.keys.each do |k|
  799.                 totalStats[k] += itemStats[k]
  800.             end
  801.         end
  802.         @reforgebonus.keys.each do |k|
  803.             totalStats[k] += @reforgebonus[k]
  804.         end
  805.         value = 0
  806.         if (totalStats["spi"] + totalStats["hit"]).between?(5100,$maxhit) then
  807.             totalStats.keys.each do |s|
  808.                 if (s != "spi") and (s != "hit") then
  809.                     value += totalStats[s] * $w[s]
  810.                 end
  811.             end
  812.         end
  813.        
  814.         # if totalStats["spi"] + totalStats["hit"] > 5100 then
  815.             # value -= (totalStats["spi"] + totalStats["hit"] - 5100) * $w["spi"]
  816.         # end
  817.         # if $debug then
  818.             # mend = Time.now
  819.             # dur = mend - mstart
  820.             # puts "ItemSet::getValue took #{dur} seconds"
  821.         # end
  822.         out = value
  823.     end
  824. end
  825.  
  826.  
  827. #--------------------------------------------------------------------------------
  828. #
  829. # load itembase from file and update it if necessary
  830. #
  831. #--------------------------------------------------------------------------------
  832. timedMsg("setting up item base")
  833. if File.exist?($infile) then
  834.     # load existing data
  835.     $itemBase = YAML::load(File.read($infile))
  836. else
  837.     # create empty filebase
  838.     $itemBase = Hash.new
  839. end
  840. # add new items
  841. if $addItems.length > 0 then
  842.     timedMsg("adding #{$addItems.length} items from wowhead")
  843.     bonusTrans = {
  844.         "Intellect" => "int",
  845.         "Hit" => "hit",
  846.         "Spirit" => "spi",
  847.         "Haste" => "haste",
  848.         "Mastery" => "mastery",
  849.         "Critical Strike" => "crit"
  850.     }
  851.     socketTrans = {1 => 3, 2 => 0, 4 => 1, 8 => 2}
  852.     slotTrans = {
  853.         1 => "head",
  854.         2 => "neck",
  855.         3 => "shoulders",
  856.         16 => "back",
  857.         5 => "chest",
  858.         9 => "wrists",
  859.         10 => "hands",
  860.         6 => "waist",
  861.         7 => "legs",
  862.         8 => "feet",
  863.         11 => "finger",
  864.         12 => "trinket",
  865.         14 => "off_hand",
  866.         23 => "off_hand",
  867.         13 => "main_hand",
  868.         17 => "two_hand"
  869.     }
  870.     $addItems.each do |itemID|
  871.         #check if item already exists
  872.         itemExists = false
  873.         $itemBase.keys.each do |key|
  874.             $itemBase[key].each do |i|
  875.                 if i.getID == itemID then
  876.                     itemExists = true
  877.                     timedMsg("Item #{itemID} already exists")
  878.                 end
  879.             end
  880.         end
  881.        
  882.         if itemExists == false then
  883.             timedMsg("adding #{itemID}")
  884.             # uri = URI("http://www.wowhead.com/item=#{itemID}&xml=1")
  885.             # file = File.new("out.txt")
  886.                    
  887.             doc = REXML::Document.new(Net::HTTP.get(URI("http://www.wowhead.com/item=#{itemID}&xml=1")))
  888.             root = doc.root
  889.  
  890.             str = root.elements[1].elements["jsonEquip"].to_s
  891.             str = str[20..-16]
  892.             str.gsub!("\"","")
  893.             arr = str.split(/[,:]/)
  894.             #puts str + "\n"
  895.             #puts arr.to_s
  896.             hsh = Hash[*arr]
  897.             #puts hsh.to_s
  898.             #hit = hsh["hitrtng"].to_i
  899.  
  900.             tooltip = root.elements[1].elements["htmlTooltip"].to_s
  901.             strSocketBonus = tooltip.match(/Socket Bonus: \+[0-9]+ [A-za-z ]+/).to_s
  902.             bonusValue = strSocketBonus.match(/[0-9]+/).to_s
  903.             bonusStat = strSocketBonus.match(/[0-9] [A-za-z ]+/).to_s[2..-1]
  904.             #puts bonusValue
  905.             #puts bonusStat
  906.             #puts bonusTrans[bonusStat]
  907.  
  908.             id = itemID
  909.             puts name = root.elements[1].elements["name"].to_s[15..-11]
  910.             slot = root.elements[1].elements["inventorySlot"].attributes["id"].to_i
  911.             slotName = slotTrans[slot]
  912.             int = hsh["int"].to_i
  913.             splpwr = hsh["splpwr"].to_i
  914.             spi = hsh["spi"].to_i
  915.             hit = hsh["hitrtng"].to_i
  916.             haste = hsh["hastertng"].to_i
  917.             mastery = hsh["mastrtng"].to_i
  918.             crit = hsh["critstrkrtng"].to_i
  919.             sockets = []
  920.             if hsh["socket1"] != nil then sockets.push(socketTrans[hsh["socket1"].to_i].to_i) end
  921.             if hsh["socket2"] != nil then sockets.push(socketTrans[hsh["socket2"].to_i].to_i) end
  922.             if hsh["socket3"] != nil then sockets.push(socketTrans[hsh["socket3"].to_i].to_i) end
  923.             if slotName == "waist" then
  924.                 sockets.push(4)
  925.             elsif slotName == "hands" then
  926.                 if $profs["bla"] == 1 then
  927.                     sockets.push(4)
  928.                 end
  929.             elsif slotName == "wrists" then
  930.                 if $profs["bla"] == 1 then
  931.                     sockets.push(4)
  932.                 end
  933.             elsif (slotName == "main_hand") or (slotName == "two_hand") then
  934.                 if $wrathion_weapon_socket then
  935.                     sockets.push(4)
  936.                 end
  937.             end
  938.             if bonusValue != "" then
  939.                 sockets.push(bonusValue.to_i)
  940.                 sockets.push(bonusTrans[bonusStat])
  941.             end
  942.             if sockets.length == 1 then
  943.                 sockets.push(0)
  944.                 sockets.push("int")
  945.             end
  946.             if sockets.length == 0 then sockets = nil end
  947.             # if we just added a socket to an item that had none, add a dummy socket bonus to avoid errors
  948.             #puts "sockets: #{sockets}"
  949.            
  950.             if not ($itemBase.key?(slotName)) then $itemBase[slotName] = Array.new end
  951.             if slotName == "two_hand" then
  952.                 simcSlotName = "main_hand"
  953.             else
  954.                 simcSlotName = slotName
  955.             end
  956.             $itemBase[slotName].push(Item.new(id,name,simcSlotName,int,splpwr,spi,hit,haste,mastery,crit,sockets))
  957.         end
  958.     end
  959. end
  960. # remove old items
  961. if $remItems.length > 0 then
  962.     timedMsg("removing #{$remItems.length} items")
  963.     $remItems.each do |remID|
  964.         timedMsg("removing #{remID}")
  965.         $itemBase.keys.each do |key|
  966.             $itemBase[key].delete_if{ |a| a.getID == remID }
  967.         end
  968.     end
  969. end
  970. # remove duplicates
  971. $itemBase.keys.each do |key|
  972.     $itemBase[key].uniq!
  973. end
  974. # update gems, enchants and reforges in case profs or stat weights changed
  975. $itemBase.keys.each do |key|
  976.     $itemBase[key].each do |item|
  977.         item.enchant
  978.         item.getRefs
  979.         item.gem
  980.     end
  981. end
  982. # write new itemBase to file
  983. timedMsg("writing updated item base to file")
  984. outFile = File.open($infile,"w")
  985. outFile.syswrite($itemBase.to_yaml)
  986. outFile.close
  987.  
  988.  
  989.  
  990. #--------------------------------------------------------------------------------
  991. #
  992. # build setslots array: head, shoulders, chest, hands, legs with at least 4t15
  993. #
  994. #--------------------------------------------------------------------------------
  995. timedMsg("building setslots array")
  996. $setslots = Array.new
  997. $itemBase["head"].each do |he|
  998.     $itemBase["shoulders"].each do |sh|
  999.         $itemBase["chest"].each do |ch|
  1000.             $itemBase["hands"].each do |ha|
  1001.                 $itemBase["legs"].each do |le|
  1002.                     numset = 0
  1003.                     he.getName.include?("Witch Doctor") ? numset += 1 : nil
  1004.                     sh.getName.include?("Witch Doctor") ? numset += 1 : nil
  1005.                     ch.getName.include?("Witch Doctor") ? numset += 1 : nil
  1006.                     ha.getName.include?("Witch Doctor") ? numset += 1 : nil
  1007.                     le.getName.include?("Witch Doctor") ? numset += 1 : nil
  1008.                     numset >= 4 ? $setslots.push([he,sh,ch,ha,le]) : nil
  1009.                 end
  1010.             end
  1011.         end
  1012.     end
  1013. end
  1014.  
  1015.  
  1016. #--------------------------------------------------------------------------------
  1017. #
  1018. # build fingers array: all combinations of non-identical rings
  1019. #
  1020. #--------------------------------------------------------------------------------
  1021. timedMsg("building fingers array")
  1022. $fingers = Array.new
  1023. (0..$itemBase["finger"].length-2).each do |f1|
  1024.     (f1+1..$itemBase["finger"].length-1).each do |f2|
  1025.         $fingers.push([$itemBase["finger"][f1],$itemBase["finger"][f2]])
  1026.     end
  1027. end
  1028.  
  1029.  
  1030. #--------------------------------------------------------------------------------
  1031. #
  1032. # build trinkets array: all combinations of non-identical trinkets
  1033. #
  1034. #--------------------------------------------------------------------------------
  1035. timedMsg("building trinkets array")
  1036. $trinkets = Array.new
  1037. (0..$itemBase["trinket"].length-2).each do |t1|
  1038.     (t1+1..$itemBase["trinket"].length-1).each do |t2|
  1039.         $trinkets.push([$itemBase["trinket"][t1],$itemBase["trinket"][t2]])
  1040.     end
  1041. end
  1042.  
  1043.  
  1044. #--------------------------------------------------------------------------------
  1045. #
  1046. # build main/off-hand array
  1047. #
  1048. #--------------------------------------------------------------------------------
  1049. timedMsg("building main-/off-hand array")
  1050. $mohand = Array.new
  1051. (0..$itemBase["main_hand"].length-1).each do |mh|
  1052.     (0..$itemBase["off_hand"].length-1).each do |oh|
  1053.         $mohand.push([$itemBase["main_hand"][mh],$itemBase["off_hand"][oh]])
  1054.     end
  1055. end
  1056. (0..$itemBase["two_hand"].length-1).each do |th|
  1057.     $mohand.push($itemBase["two_hand"][th])
  1058. end
  1059.  
  1060.  
  1061.  
  1062. #--------------------------------------------------------------------------------
  1063. #
  1064. # main loop: recursively build, filter, optimize and value sets
  1065. #
  1066. #--------------------------------------------------------------------------------
  1067. def buildSets(items, set)
  1068.     if items.length == 1 then
  1069.         items[0].each do |i|
  1070.             if $num >= $startid then
  1071.                 curSet = set.dup
  1072.                 curSet.push(i)
  1073.                 testset = ItemSet.new(curSet)
  1074.                 temphit = testset.getSpiHit
  1075.                 temprefhit = testset.getReforgableSpiHit
  1076.                 if (temphit - 0.4 * temprefhit < $maxhit) then
  1077.                     #puts "#{Time.now-$t_start} set #$num has reforgable amount of spirit (#{temphit})"
  1078.                     testset.reforge
  1079.                     tempval = testset.getValue
  1080.                     if tempval > $maxval then
  1081.                         timedMsg("set #{"%06d" % $num} is new best at #{"%.4f" % tempval}, ~#{"%d" % estRemaining($num)}sec left")
  1082.                         $maxval = tempval
  1083.                         $maxset = testset
  1084.                         outFile = File.open("#{$outfolder}\\#{tempval}.txt","w")
  1085.                         outFile.syswrite("name=set#{$num}\n")
  1086.                         outFile.syswrite(testset.getSimc)
  1087.                         outFile.syswrite("\##{testset.getStats.to_s}")
  1088.                         outFile.close
  1089.                     else
  1090.                         timedMsg("set #{"%06d" % $num} valued #{"%.4f" % tempval} (max: #{"%.4f" % $maxval}), ~#{"%d" % estRemaining($num)}sec left")
  1091.                     end
  1092.                 end            
  1093.             end
  1094.             $num += 1
  1095.         end
  1096.     else
  1097.         curItems = items.dup
  1098.         curSlot = curItems.pop
  1099.         curSlot.each do |i|
  1100.             curSet = set.dup
  1101.             curSet.push(i)
  1102.             buildSets(curItems, curSet)
  1103.         end
  1104.     end
  1105. end
  1106.  
  1107. # build array of available items, sorted by value
  1108. timedMsg("sorting slot arrays by value")
  1109. $itemBase["neck"].sort!{|a,b| b.getValue <=> a.getValue}
  1110. $itemBase["back"].sort!{|a,b| b.getValue <=> a.getValue}
  1111. $itemBase["wrists"].sort!{|a,b| b.getValue <=> a.getValue}
  1112. $itemBase["waist"].sort!{|a,b| b.getValue <=> a.getValue}
  1113. $itemBase["feet"].sort!{|a,b| b.getValue <=> a.getValue}
  1114. $itemBase["main_hand"].sort!{|a,b| b.getValue <=> a.getValue}
  1115. $itemBase["off_hand"].sort!{|a,b| b.getValue <=> a.getValue}
  1116. #$mohand.sort!{|a,b| b[0].getValue + (b[1].getValue or 0) <=> a[0].getValue + (a[1].getValue or 0)}
  1117. $mohand.sort!{
  1118.     |a,b|
  1119.     if a.class == Array then
  1120.         ta = 0
  1121.         a.each do |x|
  1122.             ta += x.getValue
  1123.         end
  1124.     else
  1125.         ta = a.getValue
  1126.     end
  1127.     if b.class == Array then
  1128.         tb = 0
  1129.         b.each do |x|
  1130.             tb += x.getValue
  1131.         end
  1132.     else
  1133.         tb = b.getValue
  1134.     end
  1135.     tb <=> ta
  1136. }
  1137. $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}
  1138. $fingers.sort!{|a,b| b[0].getValue + b[1].getValue <=> a[0].getValue + a[1].getValue}
  1139. $trinkets.sort!{|a,b| b[0].getValue + b[1].getValue <=> a[0].getValue + a[1].getValue}
  1140. $items = [$setslots, $itemBase["neck"], $itemBase["back"], $itemBase["wrists"], $itemBase["waist"], $itemBase["feet"], $fingers, $trinkets, $mohand]
  1141.  
  1142. #--------------------------------------------------------------------------------
  1143. #
  1144. # establish number of possible sets for estimating remaining time
  1145. #
  1146. #--------------------------------------------------------------------------------
  1147. $numPosSets = $itemBase["neck"].length * $itemBase["back"].length * $itemBase["wrists"].length * $itemBase["waist"].length * $itemBase["feet"].length * $mohand.length * $setslots.length * $fingers.length * $trinkets.length
  1148. timedMsg("setup finished, #{$numPosSets} possible sets will be analyzed")
  1149. def estRemaining(num)
  1150.     remaining = (Time.now - $t_start) * ($numPosSets - num) / num
  1151. end
  1152.  
  1153.  
  1154. # main program
  1155. timedMsg("starting main loop")
  1156. #puts $trinket[2].to_s
  1157. #puts $trinket[2].getRefs.to_s
  1158. $num = 0
  1159. $maxval = $startmax
  1160. $maxset = nil
  1161. buildSets($items, [])
Add Comment
Please, Sign In to add comment