d3_mpq 0.0.11 → 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/d3_mpq/commands.rb +3 -0
- data/lib/d3_mpq/core_data/game_balance/monster_affixes.rb +11 -2
- data/lib/d3_mpq/core_data/game_balance/monster_levels.rb +15 -0
- data/lib/d3_mpq/core_data/game_balance/monster_names.rb +2 -2
- data/lib/d3_mpq/core_data/game_balance/power_formula_tables.rb +1 -1
- data/lib/d3_mpq/core_data/game_balance/rare_names.rb +15 -0
- data/lib/d3_mpq/core_data/game_balance.rb +2 -0
- data/lib/d3_mpq/csv_generator/base.rb +23 -15
- data/lib/d3_mpq/csv_generator/experience_table.rb +32 -0
- data/lib/d3_mpq/csv_generator/monster_affixes.rb +39 -0
- data/lib/d3_mpq/csv_generator/monster_levels.rb +14 -0
- data/lib/d3_mpq/csv_generator/monster_names.rb +16 -0
- data/lib/d3_mpq/csv_generator/power_formula_tables.rb +17 -0
- data/lib/d3_mpq/csv_generator/rare_names.rb +15 -0
- data/lib/d3_mpq/csv_generator.rb +6 -0
- data/lib/d3_mpq/mod_code.rb +196 -0
- data/lib/d3_mpq/mod_codes.rb +6 -0
- data/lib/d3_mpq/version.rb +1 -1
- data/lib/d3_mpq/version.rb~ +1 -1
- data/lib/d3_mpq.rb +2 -0
- data/spec/bindata_ext/mod_code_spec.rb +1 -1
- data/spec/unit/bindata_ext/mod_code_spec.rb +1 -1
- data/spec/unit/core_data/game_balance/affix_list_spec.rb +1 -1
- data/spec/unit/core_data/game_balance/monster_levels_spec.rb +14 -0
- data/spec/unit/core_data/game_balance/rare_names_spec.rb +14 -0
- data/spec/unit/csv_generator/experience_table_spec.rb +11 -0
- data/spec/unit/csv_generator/monster_affixes.rb +11 -0
- data/spec/unit/csv_generator/monster_levels_spec.rb +11 -0
- data/spec/unit/csv_generator/monster_names_spec.rb +11 -0
- data/spec/unit/csv_generator/power_formula_spec.rb +11 -0
- data/spec/unit/csv_generator/rare_names_spec.rb +11 -0
- metadata +39 -15
- data/lib/bindata_ext/mod_code.rb +0 -194
- data/lib/bindata_ext/mod_codes.rb +0 -4
data/lib/d3_mpq/commands.rb
CHANGED
@@ -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
|
@@ -4,13 +4,13 @@ module D3MPQ::CoreData::GameBalance
|
|
4
4
|
|
5
5
|
content do
|
6
6
|
zeroes
|
7
|
-
string :
|
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 :
|
13
|
+
string :name,
|
14
14
|
:read_length => 0x80,
|
15
15
|
:trim_padding => true
|
16
16
|
|
@@ -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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
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
|
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,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
|
+
|
data/lib/d3_mpq/csv_generator.rb
CHANGED
@@ -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
|
+
|
data/lib/d3_mpq/version.rb
CHANGED
data/lib/d3_mpq/version.rb~
CHANGED
data/lib/d3_mpq.rb
CHANGED
@@ -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
|
+
|
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.
|
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: &
|
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: *
|
24
|
+
version_requirements: *78792250
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: nokogiri
|
27
|
-
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: *
|
35
|
+
version_requirements: *78792030
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
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: *
|
46
|
+
version_requirements: *78791800
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: guard
|
49
|
-
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: *
|
57
|
+
version_requirements: *78791480
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: guard-rspec
|
60
|
-
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: *
|
68
|
+
version_requirements: *78791160
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: libnotify
|
71
|
-
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: *
|
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
|
data/lib/bindata_ext/mod_code.rb
DELETED
@@ -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
|
-
|