d3_mpq 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. data/lib/d3_mpq/commands.rb +3 -0
  2. data/lib/d3_mpq/core_data/game_balance/monster_affixes.rb +11 -2
  3. data/lib/d3_mpq/core_data/game_balance/monster_levels.rb +15 -0
  4. data/lib/d3_mpq/core_data/game_balance/monster_names.rb +2 -2
  5. data/lib/d3_mpq/core_data/game_balance/power_formula_tables.rb +1 -1
  6. data/lib/d3_mpq/core_data/game_balance/rare_names.rb +15 -0
  7. data/lib/d3_mpq/core_data/game_balance.rb +2 -0
  8. data/lib/d3_mpq/csv_generator/base.rb +23 -15
  9. data/lib/d3_mpq/csv_generator/experience_table.rb +32 -0
  10. data/lib/d3_mpq/csv_generator/monster_affixes.rb +39 -0
  11. data/lib/d3_mpq/csv_generator/monster_levels.rb +14 -0
  12. data/lib/d3_mpq/csv_generator/monster_names.rb +16 -0
  13. data/lib/d3_mpq/csv_generator/power_formula_tables.rb +17 -0
  14. data/lib/d3_mpq/csv_generator/rare_names.rb +15 -0
  15. data/lib/d3_mpq/csv_generator.rb +6 -0
  16. data/lib/d3_mpq/mod_code.rb +196 -0
  17. data/lib/d3_mpq/mod_codes.rb +6 -0
  18. data/lib/d3_mpq/version.rb +1 -1
  19. data/lib/d3_mpq/version.rb~ +1 -1
  20. data/lib/d3_mpq.rb +2 -0
  21. data/spec/bindata_ext/mod_code_spec.rb +1 -1
  22. data/spec/unit/bindata_ext/mod_code_spec.rb +1 -1
  23. data/spec/unit/core_data/game_balance/affix_list_spec.rb +1 -1
  24. data/spec/unit/core_data/game_balance/monster_levels_spec.rb +14 -0
  25. data/spec/unit/core_data/game_balance/rare_names_spec.rb +14 -0
  26. data/spec/unit/csv_generator/experience_table_spec.rb +11 -0
  27. data/spec/unit/csv_generator/monster_affixes.rb +11 -0
  28. data/spec/unit/csv_generator/monster_levels_spec.rb +11 -0
  29. data/spec/unit/csv_generator/monster_names_spec.rb +11 -0
  30. data/spec/unit/csv_generator/power_formula_spec.rb +11 -0
  31. data/spec/unit/csv_generator/rare_names_spec.rb +11 -0
  32. metadata +39 -15
  33. data/lib/bindata_ext/mod_code.rb +0 -194
  34. data/lib/bindata_ext/mod_codes.rb +0 -4
@@ -86,6 +86,9 @@ Example: d3_mpq --csv-input extracted_mpqs/StringList/ csv StringList
86
86
  * Items
87
87
  * ItemEnhancements
88
88
  * ItemTypes
89
+ * MonsterNames
90
+ * PowerFormulaTables
91
+ * RareNames
89
92
  * Recipes
90
93
  * RecipeDetails
91
94
  * SetItemBonuses
@@ -13,9 +13,18 @@ module D3MPQ::CoreData::GameBalance
13
13
  uint32 :ui3
14
14
  uint32 :ui4
15
15
  uint32 :ui5
16
+ uint32 :ui6
17
+ uint32 :ui7
18
+ uint32 :ui8
19
+ uint32 :ui9
20
+
21
+ mod_codes :mod_codes, :initial_length => 20
22
+
23
+ uint32 :ref1
24
+ uint32 :ref2
25
+ uint32 :ref3
26
+ uint32 :ref4
16
27
 
17
- # TODO
18
- skip :length => 0x210 - 16
19
28
  end
20
29
  end
21
30
  end
@@ -0,0 +1,15 @@
1
+ module D3MPQ::CoreData::GameBalance
2
+ class MonsterLevels < Base
3
+ self.struct_size = 0x230
4
+
5
+ content do
6
+ ffs
7
+ zeroes :length => 4
8
+
9
+ 135.times do |i|
10
+ float "fp_a_#{i}"
11
+ end
12
+ end
13
+ end
14
+ end
15
+
@@ -4,13 +4,13 @@ module D3MPQ::CoreData::GameBalance
4
4
 
5
5
  content do
6
6
  zeroes
7
- string :name,
7
+ string :affix_name,
8
8
  :read_length => 0x100,
9
9
  :trim_padding => true
10
10
 
11
11
  uint32 :is_suffix
12
12
 
13
- string :name2,
13
+ string :name,
14
14
  :read_length => 0x80,
15
15
  :trim_padding => true
16
16
 
@@ -10,7 +10,7 @@ module D3MPQ::CoreData::GameBalance
10
10
  zeroes :length => 192
11
11
 
12
12
  61.times do |i|
13
- float "fp#{i}".intern
13
+ float "level_#{i}".intern
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,15 @@
1
+ module D3MPQ::CoreData::GameBalance
2
+ class RareNames < Base
3
+ self.struct_size = 0x110
4
+
5
+ content do
6
+ zeroes
7
+ string :name, :length => 0x100, :trim_padding => true
8
+
9
+ uint32 :unknown
10
+ uint32 :stl_key_hash
11
+ unknown
12
+ end
13
+ end
14
+ end
15
+
@@ -14,8 +14,10 @@ module D3MPQ::CoreData
14
14
  require "d3_mpq/core_data/game_balance/item_types"
15
15
  require "d3_mpq/core_data/game_balance/labels_global"
16
16
  require "d3_mpq/core_data/game_balance/monster_affixes"
17
+ require "d3_mpq/core_data/game_balance/monster_levels"
17
18
  require "d3_mpq/core_data/game_balance/monster_names"
18
19
  require "d3_mpq/core_data/game_balance/power_formula_tables"
20
+ require "d3_mpq/core_data/game_balance/rare_names"
19
21
  require "d3_mpq/core_data/game_balance/recipes"
20
22
  require "d3_mpq/core_data/game_balance/set_item_bonuses"
21
23
  require "d3_mpq/core_data/game_balance/socketed_effects"
@@ -23,23 +23,21 @@ module D3MPQ::CSVGenerator
23
23
  class << self
24
24
  # TODO: refactor
25
25
  def map_to_csv(options = nil)
26
- if options
27
- if options.is_a?(Array)
28
- @map_to_csv = {}
29
- options.each do |e|
30
- if e.is_a?(String) || e.is_a?(Symbol)
31
- @map_to_csv[e.intern] = e.intern
32
- else
33
- @map_to_csv[e.to_a[0].intern] = e.to_a[1]
34
- end
26
+ return @map_to_csv unless options
27
+
28
+ if options.is_a?(Array)
29
+ @map_to_csv = {}
30
+ options.each do |e|
31
+ if e.is_a?(String) || e.is_a?(Symbol)
32
+ @map_to_csv[e.intern] = e.intern
33
+ else
34
+ @map_to_csv[e.to_a[0].intern] = e.to_a[1]
35
35
  end
36
- elsif options.is_a?(Hash)
37
- @map_to_csv = options
38
- else
39
- raise "Options must be an Array or Hash."
40
36
  end
37
+ elsif options.is_a?(Hash)
38
+ @map_to_csv = options
41
39
  else
42
- @map_to_csv
40
+ raise "Options must be an Array or Hash."
43
41
  end
44
42
  end
45
43
  end
@@ -99,9 +97,18 @@ module D3MPQ::CSVGenerator
99
97
  end
100
98
 
101
99
  def csv_keys
102
- map_to_csv.keys.join(SEPERATOR)
100
+ if map_to_csv
101
+ map_to_csv.keys.join(SEPERATOR)
102
+ else
103
+ raise "Not Implemented"
104
+ end
103
105
  end
104
106
 
107
+ # def fields_from_mpq_reader
108
+ # fields = MPQ_READER.fields.fields.map { |e| e.name }
109
+ # if fields.include?
110
+ # end
111
+
105
112
 
106
113
  def subject_to_csv_line(subject, filename, base = nil, index = nil)
107
114
  line = []
@@ -114,6 +121,7 @@ module D3MPQ::CSVGenerator
114
121
  entry = subject.send(opt)
115
122
  end
116
123
 
124
+ entry = entry.to_s if entry.is_a?(BinData::String)
117
125
  if entry.is_a?(String)
118
126
  entry.gsub!('"', '\"')
119
127
  entry = "\"#{entry}\""
@@ -0,0 +1,32 @@
1
+ module D3MPQ::CSVGenerator
2
+ class ExperienceTable < Base
3
+ MPQ_READER = D3MPQ::CoreData::GameBalance::ExperienceTable
4
+
5
+ map = [
6
+ :xp1,
7
+ :fp1,
8
+ :xp_given_1,
9
+ :xp_given_2,
10
+ :xp_given_3,
11
+ :xp_given_4,
12
+ :xp_given_5,
13
+ :ui1,
14
+ :ui2,
15
+ :ui3,
16
+ :ui4,
17
+ :ui5,
18
+ :ui1a,
19
+ :ui2a,
20
+ :ui3a,
21
+ :ui4a,
22
+ :ui5a
23
+ ]
24
+
25
+ 40.times do |i|
26
+ map << "u#{i}".intern
27
+ end
28
+
29
+ map_to_csv(map)
30
+ end
31
+ end
32
+
@@ -0,0 +1,39 @@
1
+ module D3MPQ::CSVGenerator
2
+ class MonsterAffixes < Base
3
+ MPQ_READER = D3MPQ::CoreData::GameBalance::MonsterAffixes
4
+
5
+ map = {
6
+ :name => :name,
7
+ :name_hash => Proc.new { |subject| subject.name.to_d3_hash },
8
+ :ui1 => :ui1,
9
+ :ui2 => :ui2,
10
+ :ui3 => :ui3,
11
+ :ui4 => :ui4,
12
+ :ui5 => :ui5,
13
+ :ui6 => :ui6,
14
+ :ui7 => :ui7,
15
+ :ui8 => :ui8,
16
+ :ui9 => :ui9,
17
+ }
18
+
19
+ 21.times do |i|
20
+ m = "modcode#{i}"
21
+ map["#{m}_mod_id".intern] = Proc.new { |subject| subject.mod_codes[i].mod_code }
22
+ map["#{m}_param1".intern] = Proc.new { |subject| subject.mod_codes[i].mod_param1 }
23
+ map["#{m}_param2".intern] = Proc.new { |subject| subject.mod_codes[i].mod_param2 }
24
+ map["#{m}_param3".intern] = Proc.new { |subject| subject.mod_codes[i].mod_param3 }
25
+ map["#{m}_opcode".intern] = Proc.new { |subject| subject.mod_codes[i].trace.join("|") }
26
+ map["#{m}_value_min".intern] = Proc.new { |subject| subject.mod_codes[i].min }
27
+ map["#{m}_value_max".intern] = Proc.new { |subject| subject.mod_codes[i].max }
28
+ end
29
+ map = map.merge({
30
+ :ref1 => :ref1,
31
+ :ref2 => :ref2,
32
+ :ref3 => :ref3,
33
+ :ref4 => :ref4
34
+ })
35
+
36
+ map_to_csv(map)
37
+ end
38
+ end
39
+
@@ -0,0 +1,14 @@
1
+ module D3MPQ::CSVGenerator
2
+ class MonsterLevels < Base
3
+ MPQ_READER = D3MPQ::CoreData::GameBalance::MonsterLevels
4
+
5
+ map = {}
6
+
7
+ 135.times do |i|
8
+ map["fp_a_#{i}".intern] = "fp_a_#{i}".intern
9
+ end
10
+
11
+ map_to_csv(map)
12
+ end
13
+ end
14
+
@@ -0,0 +1,16 @@
1
+ module D3MPQ::CSVGenerator
2
+ class MonsterNames < Base
3
+ MPQ_READER = D3MPQ::CoreData::GameBalance::MonsterNames
4
+
5
+ map = {
6
+ :affix_name => :affix_name,
7
+ :affix_name_hash => Proc.new { |subject| subject.affix_name.to_d3_hash },
8
+ :is_suffix => :is_suffix,
9
+ :name => :name,
10
+ :name_hash => Proc.new { |subject| subject.name.to_d3_hash }
11
+ }
12
+
13
+ map_to_csv(map)
14
+ end
15
+ end
16
+
@@ -0,0 +1,17 @@
1
+ module D3MPQ::CSVGenerator
2
+ class PowerFormulaTables < Base
3
+ MPQ_READER = D3MPQ::CoreData::GameBalance::PowerFormulaTables
4
+
5
+ map = {
6
+ :name => :name,
7
+ :hash => Proc.new { |subject| subject.name.to_d3_hash }
8
+ }
9
+
10
+ 61.times do |i|
11
+ map["level_#{i}".intern] = "level_#{i}".intern
12
+ end
13
+
14
+ map_to_csv(map)
15
+ end
16
+ end
17
+
@@ -0,0 +1,15 @@
1
+ module D3MPQ::CSVGenerator
2
+ class RareNames < Base
3
+ MPQ_READER = D3MPQ::CoreData::GameBalance::RareNames
4
+
5
+ map = {
6
+ :name => :name,
7
+ :hash => Proc.new { |subject| subject.name.to_d3_hash },
8
+ :unknown => :unknown,
9
+ :stl_key_hash => :stl_key_hash
10
+ }
11
+
12
+ map_to_csv(map)
13
+ end
14
+ end
15
+
@@ -4,9 +4,15 @@ module D3MPQ
4
4
 
5
5
  require 'd3_mpq/csv_generator/actor'
6
6
  require 'd3_mpq/csv_generator/affix_list'
7
+ require 'd3_mpq/csv_generator/experience_table'
7
8
  require 'd3_mpq/csv_generator/item_enhancements'
8
9
  require 'd3_mpq/csv_generator/items'
9
10
  require 'd3_mpq/csv_generator/item_types'
11
+ require 'd3_mpq/csv_generator/monster_affixes'
12
+ require 'd3_mpq/csv_generator/monster_levels'
13
+ require 'd3_mpq/csv_generator/monster_names'
14
+ require 'd3_mpq/csv_generator/power_formula_tables'
15
+ require 'd3_mpq/csv_generator/rare_names'
10
16
  require 'd3_mpq/csv_generator/recipe_details'
11
17
  require 'd3_mpq/csv_generator/recipes'
12
18
  require 'd3_mpq/csv_generator/set_item_bonuses'
@@ -0,0 +1,196 @@
1
+ module D3MPQ
2
+ class ModCode < BinData::Record
3
+ endian :little
4
+
5
+ uint32 :mod_code
6
+
7
+ uint32 :mod_param1
8
+ uint32 :mod_param2
9
+ uint32 :mod_param3
10
+
11
+ uint32 :mod_offset
12
+ uint32 :mod_length
13
+
14
+ # Returns: nil if mod_code is 0xFFFFFFFF, mod_code otherwise
15
+ def id
16
+ self.mod_code == 0xFFFFFFFF ? nil : self.mod_code.to_i
17
+ end
18
+
19
+ # HACK
20
+ # Returns: Instance of BinData::Record that respond to :variable_content
21
+ def base
22
+ parent.parent.parent.parent
23
+ end
24
+
25
+ def index
26
+ (mod_offset - base.data_num_bytes - base.data_offset) / 4
27
+ end
28
+
29
+ def count
30
+ mod_length / 4
31
+ end
32
+
33
+ def data
34
+ base.variable_content[index, count]
35
+ end
36
+
37
+ def empty?
38
+ mod_length == 0
39
+ end
40
+
41
+ def min
42
+ stack.min || 0.0
43
+ end
44
+
45
+ def max
46
+ stack.max || 0.0
47
+ end
48
+
49
+ def trace
50
+ stack.trace
51
+ end
52
+
53
+ def stack
54
+ @stack ||= Stack.new(data)
55
+ end
56
+
57
+ private
58
+
59
+ # Pseudo-Stack to compute min/max of current ModCode
60
+ class Stack
61
+ attr_reader :value, :trace
62
+
63
+ def initialize(data)
64
+ @stack = []
65
+ @trace = []
66
+ @data = *data
67
+ @value = nil
68
+ parse
69
+ end
70
+
71
+ def min
72
+ @value ? @value.min : nil
73
+ end
74
+
75
+ def max
76
+ @value ? @value.max : nil
77
+ end
78
+
79
+ def push(item)
80
+ @stack.push item
81
+ end
82
+
83
+ def pop
84
+ @stack.pop
85
+ end
86
+
87
+ def peek
88
+ @stack.last
89
+ end
90
+
91
+ def count
92
+ @stack.length
93
+ end
94
+
95
+ def empty?
96
+ count == 0
97
+ end
98
+
99
+ # Lets go
100
+ def parse
101
+ return @value if @value
102
+ return nil if @data.empty?
103
+
104
+ next_op = true
105
+ @data.each_with_index do |dword, index|
106
+ next_op = true and next unless next_op
107
+
108
+ case dword.bytes.first
109
+ when 0x00
110
+ # return the value at the top of the stack
111
+ raise "Return found, but Stack not empty!" if @data[index+1]
112
+ @value = pop
113
+ return @value
114
+ when 0x01
115
+ # call the function of the next op-code (just pass here)
116
+ when 0x03
117
+ # rand1(A,B); pop 2 numbers and push a random value between A and A+B
118
+ op { |a, b| ["rand", a, a + b] }
119
+ when 0x04
120
+ # rand2(A,B); pop 2 numbers and push a random value between A and B
121
+ op { |a, b| ["rand2", a, b] }
122
+ when 0x06
123
+ # push the next DWord onto the stack
124
+ v = @data[index+1].unpack('F').first
125
+ push(StackValue.new(v))
126
+ @trace << "#{v}"
127
+ next_op = false
128
+ when 0x0B
129
+ # add(A,B); pop 2 numbers and push the sum
130
+ op { |a, b| ["add", (a + b)] }
131
+ when 0x0C
132
+ # sub(A,B); pop 2 numbers and push the difference
133
+ op { |a, b| ["sub", (a - b)] }
134
+ when 0x0D
135
+ # mul(A,B); pop 2 numbers and push the product
136
+ op { |a, b| ["mul", (a * b)] }
137
+ when 0x0E
138
+ # div(A,B); pop 2 numbers and push the quotient
139
+ op { |a, b| ["div", (a / b)] }
140
+ else
141
+ raise "OP-Code not found: #{op} | #{@data.inspect}"
142
+ end
143
+ end
144
+
145
+ raise "No return found: #{@data.inspect}"
146
+ end
147
+
148
+ # Perform OP-Code
149
+ def op(&blk)
150
+ b = pop
151
+ a = pop
152
+
153
+ formula, min, max = blk.call(a, b)
154
+
155
+ push(StackValue.random(min, max || min))
156
+ @trace << formula
157
+ end
158
+
159
+ def inspect
160
+ { :value => @value, :trace => @trace}
161
+ end
162
+
163
+ # Wrapper for a Float that handles: current_value, min_value, max_value
164
+ class StackValue
165
+ attr_accessor :value, :min_max
166
+
167
+ def self.random(min, max)
168
+ StackValue.new(MinMax.new(min.min, max.max).random, min.min, max.max)
169
+ end
170
+
171
+ def initialize(value, min = nil, max = nil)
172
+ @value = value
173
+ min ||= @value
174
+ @min_max = MinMax.new(min, max)
175
+ end
176
+
177
+ [:min, :max].each { |m| define_method(m) { min_max.send(m) } }
178
+ ["-", "+", "*", "/"].each do |m|
179
+ define_method(m) { |sv| with_other(sv){ |a, b| a.send(m, b) } }
180
+ end
181
+
182
+ def to_s
183
+ (min == max) ? "#{min}" : "#{min}..#{max}"
184
+ end
185
+
186
+ private
187
+ def with_other(oth, &block)
188
+ mm = block.call(min_max, oth.min_max)
189
+ v = block.call(value, oth.value)
190
+ StackValue.new(v, mm.min, mm.max)
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+
@@ -0,0 +1,6 @@
1
+ module D3MPQ
2
+ class ModCodes < BinData::Array
3
+ default_parameters :type => :mod_code, :initial_length => 1
4
+ end
5
+ end
6
+
@@ -1,4 +1,4 @@
1
1
  module D3MPQ
2
- VERSION = "0.0.11"
2
+ VERSION = "0.0.13"
3
3
  end
4
4
 
@@ -1,4 +1,4 @@
1
1
  module D3MPQ
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.12"
3
3
  end
4
4
 
data/lib/d3_mpq.rb CHANGED
@@ -9,6 +9,8 @@ require 'core_ext/string'
9
9
  module D3MPQ
10
10
  require 'd3_mpq/analyzer'
11
11
  require 'd3_mpq/attributes'
12
+ require 'd3_mpq/mod_code'
13
+ require 'd3_mpq/mod_codes'
12
14
  require 'd3_mpq/mod_code_analyzer'
13
15
  require 'd3_mpq/mpq'
14
16
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ModCode do
3
+ describe D3MPQ::ModCode do
4
4
  subject { ModCode.new }
5
5
 
6
6
  specify { subject.respond_to?(:mod_code).should be_true }
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ModCode do
3
+ describe D3MPQ::ModCode do
4
4
  io = File.open("spec/fixtures/CoreData/GameBalance/AffixList.gam")
5
5
 
6
6
  # TODO: We use Affixes as example ModCodes, change this
@@ -13,7 +13,7 @@ describe D3MPQ::CoreData::GameBalance::AffixList do
13
13
  its(:rest) { should == "" }
14
14
 
15
15
  describe "content#mod_codes" do
16
- specify { mod_codes.should be_kind_of(ModCodes) }
16
+ specify { mod_codes.should be_kind_of(D3MPQ::ModCodes) }
17
17
  end
18
18
  end
19
19
 
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CoreData::GameBalance::MonsterLevels do
4
+ let(:io) { File.open("spec/fixtures/CoreData/GameBalance/MonsterLevels.gam") }
5
+
6
+ before(:all) do
7
+ subject.read(io)
8
+ # BinData::trace_reading { subject.read(io) }
9
+ end
10
+
11
+ its(:variable_content) { subject.size.should == 0 }
12
+ its(:rest) { should == "" }
13
+ end
14
+
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CoreData::GameBalance::RareNames do
4
+ let(:io) { File.open("spec/fixtures/CoreData/GameBalance/RareNames.gam") }
5
+
6
+ before(:all) do
7
+ subject.read(io)
8
+ # BinData::trace_reading { subject.read(io) }
9
+ end
10
+
11
+ its(:variable_content) { subject.size.should == 0 }
12
+ its(:rest) { should == "" }
13
+ end
14
+
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CSVGenerator::ExperienceTable do
4
+ let(:dir) { "spec/fixtures/CoreData/GameBalance/ExperienceTable.gam" }
5
+
6
+ specify "#write" do
7
+ subject.files = dir
8
+ subject.write
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CSVGenerator::MonsterAffixes do
4
+ let(:dir) { "spec/fixtures/CoreData/GameBalance/MonsterAffixes.gam" }
5
+
6
+ specify "#write" do
7
+ subject.files = dir
8
+ subject.write
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CSVGenerator::MonsterLevels do
4
+ let(:dir) { "spec/fixtures/CoreData/GameBalance/MonsterLevels.gam" }
5
+
6
+ specify "#write" do
7
+ subject.files = dir
8
+ subject.write
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CSVGenerator::MonsterNames do
4
+ let(:dir) { "spec/fixtures/CoreData/GameBalance/MonsterNames.gam" }
5
+
6
+ specify "#write" do
7
+ subject.files = dir
8
+ subject.write
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CSVGenerator::PowerFormulaTables do
4
+ let(:dir) { "spec/fixtures/CoreData/GameBalance/PowerFormulaTables.gam" }
5
+
6
+ specify "#write" do
7
+ subject.files = dir
8
+ subject.write
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe D3MPQ::CSVGenerator::RareNames do
4
+ let(:dir) { "spec/fixtures/CoreData/GameBalance/RareNames.gam" }
5
+
6
+ specify "#write" do
7
+ subject.files = dir
8
+ subject.write
9
+ end
10
+ end
11
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: d3_mpq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.13
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-05-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bindata
16
- requirement: &69007620 !ruby/object:Gem::Requirement
16
+ requirement: &78792250 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *69007620
24
+ version_requirements: *78792250
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nokogiri
27
- requirement: &69007210 !ruby/object:Gem::Requirement
27
+ requirement: &78792030 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *69007210
35
+ version_requirements: *78792030
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &69006860 !ruby/object:Gem::Requirement
38
+ requirement: &78791800 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *69006860
46
+ version_requirements: *78791800
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: guard
49
- requirement: &69006500 !ruby/object:Gem::Requirement
49
+ requirement: &78791480 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *69006500
57
+ version_requirements: *78791480
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard-rspec
60
- requirement: &69006110 !ruby/object:Gem::Requirement
60
+ requirement: &78791160 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *69006110
68
+ version_requirements: *78791160
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: libnotify
71
- requirement: &69005780 !ruby/object:Gem::Requirement
71
+ requirement: &78790910 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *69005780
79
+ version_requirements: *78790910
80
80
  description: Parsing data out of Diablo 3.
81
81
  email:
82
82
  - deradon87@gmail.com
@@ -88,6 +88,7 @@ files:
88
88
  - bin/d3_mpq
89
89
  - lib/d3_mpq/commands/csv.rb
90
90
  - lib/d3_mpq/commands/extract.rb
91
+ - lib/d3_mpq/mod_codes.rb
91
92
  - lib/d3_mpq/csv_generator.rb
92
93
  - lib/d3_mpq/core_data/game_balance.rb
93
94
  - lib/d3_mpq/core_data/game_balance/item_types.rb
@@ -101,9 +102,11 @@ files:
101
102
  - lib/d3_mpq/core_data/game_balance/monster_names.rb
102
103
  - lib/d3_mpq/core_data/game_balance/elite_modifiers.rb
103
104
  - lib/d3_mpq/core_data/game_balance/affix_list.rb
105
+ - lib/d3_mpq/core_data/game_balance/monster_levels.rb
104
106
  - lib/d3_mpq/core_data/game_balance/labels_global.rb
105
107
  - lib/d3_mpq/core_data/game_balance/set_item_bonuses.rb
106
108
  - lib/d3_mpq/core_data/game_balance/monster_affixes.rb
109
+ - lib/d3_mpq/core_data/game_balance/rare_names.rb
107
110
  - lib/d3_mpq/core_data/game_balance/power_formula_tables.rb
108
111
  - lib/d3_mpq/core_data/game_balance/items.rb
109
112
  - lib/d3_mpq/core_data/actor.rb
@@ -122,16 +125,21 @@ files:
122
125
  - lib/d3_mpq/csv_generator/recipes.rb
123
126
  - lib/d3_mpq/csv_generator/socketed_effects.rb
124
127
  - lib/d3_mpq/csv_generator/string_list.rb
128
+ - lib/d3_mpq/csv_generator/experience_table.rb
125
129
  - lib/d3_mpq/csv_generator/base.rb
130
+ - lib/d3_mpq/csv_generator/monster_names.rb
126
131
  - lib/d3_mpq/csv_generator/affix_list.rb
132
+ - lib/d3_mpq/csv_generator/monster_levels.rb
127
133
  - lib/d3_mpq/csv_generator/set_item_bonuses.rb
134
+ - lib/d3_mpq/csv_generator/monster_affixes.rb
128
135
  - lib/d3_mpq/csv_generator/actor.rb
129
136
  - lib/d3_mpq/csv_generator/recipe_details.rb
137
+ - lib/d3_mpq/csv_generator/rare_names.rb
138
+ - lib/d3_mpq/csv_generator/power_formula_tables.rb
130
139
  - lib/d3_mpq/csv_generator/items.rb
131
140
  - lib/d3_mpq/version.rb~
141
+ - lib/d3_mpq/mod_code.rb
132
142
  - lib/bindata_ext/dsl.rb
133
- - lib/bindata_ext/mod_codes.rb
134
- - lib/bindata_ext/mod_code.rb
135
143
  - lib/d3_mpq.rb
136
144
  - lib/core_ext/min_max.rb
137
145
  - lib/core_ext/string.rb
@@ -6919,6 +6927,8 @@ files:
6919
6927
  - spec/unit/core_data/game_balance/monster_names_spec.rb
6920
6928
  - spec/unit/core_data/game_balance/elite_modifiers_spec.rb
6921
6929
  - spec/unit/core_data/game_balance/labels_global_spec.rb
6930
+ - spec/unit/core_data/game_balance/rare_names_spec.rb
6931
+ - spec/unit/core_data/game_balance/monster_levels_spec.rb
6922
6932
  - spec/unit/core_data/game_balance/item_enhancements_spec.rb
6923
6933
  - spec/unit/bindata_ext/mod_code_spec.rb
6924
6934
  - spec/unit/string_list_spec.rb
@@ -6928,9 +6938,15 @@ files:
6928
6938
  - spec/unit/csv_generator/item_types_spec.rb
6929
6939
  - spec/unit/csv_generator/set_item_bonuses_spec.rb
6930
6940
  - spec/unit/csv_generator/recipe_details_spec.rb
6941
+ - spec/unit/csv_generator/experience_table_spec.rb
6942
+ - spec/unit/csv_generator/power_formula_spec.rb
6931
6943
  - spec/unit/csv_generator/string_list_spec.rb
6944
+ - spec/unit/csv_generator/monster_names_spec.rb
6945
+ - spec/unit/csv_generator/monster_affixes.rb
6932
6946
  - spec/unit/csv_generator/item_spec.rb
6947
+ - spec/unit/csv_generator/rare_names_spec.rb
6933
6948
  - spec/unit/csv_generator/csv_generator_spec.rb
6949
+ - spec/unit/csv_generator/monster_levels_spec.rb
6934
6950
  - spec/unit/csv_generator/item_enhancements_spec.rb
6935
6951
  - spec/unit/analyzer_spec.rb
6936
6952
  - spec/unit/recipe_spec.rb
@@ -13743,6 +13759,8 @@ test_files:
13743
13759
  - spec/unit/core_data/game_balance/monster_names_spec.rb
13744
13760
  - spec/unit/core_data/game_balance/elite_modifiers_spec.rb
13745
13761
  - spec/unit/core_data/game_balance/labels_global_spec.rb
13762
+ - spec/unit/core_data/game_balance/rare_names_spec.rb
13763
+ - spec/unit/core_data/game_balance/monster_levels_spec.rb
13746
13764
  - spec/unit/core_data/game_balance/item_enhancements_spec.rb
13747
13765
  - spec/unit/bindata_ext/mod_code_spec.rb
13748
13766
  - spec/unit/string_list_spec.rb
@@ -13752,9 +13770,15 @@ test_files:
13752
13770
  - spec/unit/csv_generator/item_types_spec.rb
13753
13771
  - spec/unit/csv_generator/set_item_bonuses_spec.rb
13754
13772
  - spec/unit/csv_generator/recipe_details_spec.rb
13773
+ - spec/unit/csv_generator/experience_table_spec.rb
13774
+ - spec/unit/csv_generator/power_formula_spec.rb
13755
13775
  - spec/unit/csv_generator/string_list_spec.rb
13776
+ - spec/unit/csv_generator/monster_names_spec.rb
13777
+ - spec/unit/csv_generator/monster_affixes.rb
13756
13778
  - spec/unit/csv_generator/item_spec.rb
13779
+ - spec/unit/csv_generator/rare_names_spec.rb
13757
13780
  - spec/unit/csv_generator/csv_generator_spec.rb
13781
+ - spec/unit/csv_generator/monster_levels_spec.rb
13758
13782
  - spec/unit/csv_generator/item_enhancements_spec.rb
13759
13783
  - spec/unit/analyzer_spec.rb
13760
13784
  - spec/unit/recipe_spec.rb
@@ -1,194 +0,0 @@
1
- class ModCode < BinData::Record
2
- endian :little
3
-
4
- uint32 :mod_code
5
-
6
- uint32 :mod_param1
7
- uint32 :mod_param2
8
- uint32 :mod_param3
9
-
10
- uint32 :mod_offset
11
- uint32 :mod_length
12
-
13
- # Returns: nil if mod_code is 0xFFFFFFFF, mod_code otherwise
14
- def id
15
- self.mod_code == 0xFFFFFFFF ? nil : self.mod_code.to_i
16
- end
17
-
18
- # HACK
19
- # Returns: Instance of BinData::Record that respond to :variable_content
20
- def base
21
- parent.parent.parent.parent
22
- end
23
-
24
- def index
25
- (mod_offset - base.data_num_bytes - base.data_offset) / 4
26
- end
27
-
28
- def count
29
- mod_length / 4
30
- end
31
-
32
- def data
33
- base.variable_content[index, count]
34
- end
35
-
36
- def empty?
37
- mod_length == 0
38
- end
39
-
40
- def min
41
- stack.min || 0.0
42
- end
43
-
44
- def max
45
- stack.max || 0.0
46
- end
47
-
48
- def trace
49
- stack.trace
50
- end
51
-
52
- def stack
53
- @stack ||= Stack.new(data)
54
- end
55
-
56
- private
57
-
58
- # Pseudo-Stack to compute min/max of current ModCode
59
- class Stack
60
- attr_reader :value, :trace
61
-
62
- def initialize(data)
63
- @stack = []
64
- @trace = []
65
- @data = *data
66
- @value = nil
67
- parse
68
- end
69
-
70
- def min
71
- @value ? @value.min : nil
72
- end
73
-
74
- def max
75
- @value ? @value.max : nil
76
- end
77
-
78
- def push(item)
79
- @stack.push item
80
- end
81
-
82
- def pop
83
- @stack.pop
84
- end
85
-
86
- def peek
87
- @stack.last
88
- end
89
-
90
- def count
91
- @stack.length
92
- end
93
-
94
- def empty?
95
- count == 0
96
- end
97
-
98
- # Lets go
99
- def parse
100
- return @value if @value
101
- return nil if @data.empty?
102
-
103
- next_op = true
104
- @data.each_with_index do |dword, index|
105
- next_op = true and next unless next_op
106
-
107
- case dword.bytes.first
108
- when 0x00
109
- # return the value at the top of the stack
110
- raise "Return found, but Stack not empty!" if @data[index+1]
111
- @value = pop
112
- return @value
113
- when 0x01
114
- # call the function of the next op-code (just pass here)
115
- when 0x03
116
- # rand1(A,B); pop 2 numbers and push a random value between A and A+B
117
- op { |a, b| ["rand", a, a + b] }
118
- when 0x04
119
- # rand2(A,B); pop 2 numbers and push a random value between A and B
120
- op { |a, b| ["rand2", a, b] }
121
- when 0x06
122
- # push the next DWord onto the stack
123
- v = @data[index+1].unpack('F').first
124
- push(StackValue.new(v))
125
- @trace << "#{v}"
126
- next_op = false
127
- when 0x0B
128
- # add(A,B); pop 2 numbers and push the sum
129
- op { |a, b| ["add", (a + b)] }
130
- when 0x0C
131
- # sub(A,B); pop 2 numbers and push the difference
132
- op { |a, b| ["sub", (a - b)] }
133
- when 0x0D
134
- # mul(A,B); pop 2 numbers and push the product
135
- op { |a, b| ["mul", (a * b)] }
136
- when 0x0E
137
- # div(A,B); pop 2 numbers and push the quotient
138
- op { |a, b| ["div", (a / b)] }
139
- else
140
- raise "OP-Code not found: #{op} | #{@data.inspect}"
141
- end
142
- end
143
-
144
- raise "No return found: #{@data.inspect}"
145
- end
146
-
147
- # Perform OP-Code
148
- def op(&blk)
149
- b = pop
150
- a = pop
151
-
152
- formula, min, max = blk.call(a, b)
153
-
154
- push(StackValue.random(min, max || min))
155
- @trace << formula
156
- end
157
-
158
- def inspect
159
- { :value => @value, :trace => @trace}
160
- end
161
-
162
- # Wrapper for a Float that handles: current_value, min_value, max_value
163
- class StackValue
164
- attr_accessor :value, :min_max
165
-
166
- def self.random(min, max)
167
- StackValue.new(MinMax.new(min.min, max.max).random, min.min, max.max)
168
- end
169
-
170
- def initialize(value, min = nil, max = nil)
171
- @value = value
172
- min ||= @value
173
- @min_max = MinMax.new(min, max)
174
- end
175
-
176
- [:min, :max].each { |m| define_method(m) { min_max.send(m) } }
177
- ["-", "+", "*", "/"].each do |m|
178
- define_method(m) { |sv| with_other(sv){ |a, b| a.send(m, b) } }
179
- end
180
-
181
- def to_s
182
- (min == max) ? "#{min}" : "#{min}..#{max}"
183
- end
184
-
185
- private
186
- def with_other(oth, &block)
187
- mm = block.call(min_max, oth.min_max)
188
- v = block.call(value, oth.value)
189
- StackValue.new(v, mm.min, mm.max)
190
- end
191
- end
192
- end
193
- end
194
-
@@ -1,4 +0,0 @@
1
- class ModCodes < BinData::Array
2
- default_parameters :type => :mod_code, :initial_length => 1
3
- end
4
-