mgmg 1.5.1 → 1.5.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/mgmg/cuisine.rb +49 -49
- data/lib/mgmg/equip.rb +181 -171
- data/lib/mgmg/ir.rb +114 -108
- data/lib/mgmg/optimize.rb +9 -9
- data/lib/mgmg/option.rb +19 -4
- data/lib/mgmg/poly.rb +68 -61
- data/lib/mgmg/recipe.rb +9 -9
- data/lib/mgmg/reinforce.rb +34 -35
- data/lib/mgmg/search.rb +10 -10
- data/lib/mgmg/system_equip.rb +2 -4
- data/lib/mgmg/utils.rb +3 -4
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +71 -62
- data/reference.md +27 -25
- metadata +2 -2
data/lib/mgmg/ir.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Mgmg
|
2
2
|
using Refiner
|
3
3
|
class IR
|
4
|
+
Cache = Hash.new
|
4
5
|
class Const
|
5
6
|
def initialize(value)
|
6
7
|
@value = value
|
@@ -94,44 +95,44 @@ module Mgmg
|
|
94
95
|
def to_s
|
95
96
|
@body.map(&:to_s).join('+')
|
96
97
|
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
98
|
+
class << self
|
99
|
+
def sum(a, b)
|
100
|
+
unconsts, const = [], Const.new(0)
|
101
|
+
case a
|
102
|
+
when Multi
|
103
|
+
if a.body[0].kind_of?(Const)
|
104
|
+
const.value += a.body[0].value
|
105
|
+
unconsts = a.body[1..(-1)]
|
106
|
+
else
|
107
|
+
unconsts = a.body.dup
|
108
|
+
end
|
109
|
+
when Const
|
110
|
+
const.value += a.value
|
106
111
|
else
|
107
|
-
unconsts
|
112
|
+
unconsts << a
|
108
113
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
114
|
+
case b
|
115
|
+
when Multi
|
116
|
+
if b.body[0].kind_of?(Const)
|
117
|
+
const.value += b.body[0].value
|
118
|
+
unconsts.concat(b.body[1..(-1)])
|
119
|
+
else
|
120
|
+
unconsts.concat(b.body)
|
121
|
+
end
|
122
|
+
when Const
|
123
|
+
const.value += b.value
|
119
124
|
else
|
120
|
-
unconsts
|
125
|
+
unconsts << b
|
126
|
+
end
|
127
|
+
body = ( const.value == 0 ? unconsts : [const, *unconsts] )
|
128
|
+
case body.size
|
129
|
+
when 0
|
130
|
+
const
|
131
|
+
when 1
|
132
|
+
body[0]
|
133
|
+
else
|
134
|
+
new(body)
|
121
135
|
end
|
122
|
-
when Const
|
123
|
-
const.value += b.value
|
124
|
-
else
|
125
|
-
unconsts << b
|
126
|
-
end
|
127
|
-
body = ( const.value == 0 ? unconsts : [const, *unconsts] )
|
128
|
-
case body.size
|
129
|
-
when 0
|
130
|
-
const
|
131
|
-
when 1
|
132
|
-
body[0]
|
133
|
-
else
|
134
|
-
new(body)
|
135
136
|
end
|
136
137
|
end
|
137
138
|
end
|
@@ -315,87 +316,92 @@ module Mgmg
|
|
315
316
|
end
|
316
317
|
Zero = self.new(28, Vec.new(6, 0).freeze, 12, 12, Array.new(9){Const.new(0)}.freeze)
|
317
318
|
Zero.rein.freeze; Zero.freeze
|
318
|
-
end
|
319
|
-
class << IR
|
320
|
-
def build(str, left_associative: true, reinforcement: [])
|
321
|
-
str = Mgmg.check_string(str)
|
322
|
-
stack, str = build_sub0([], str)
|
323
|
-
build_sub(stack, str, left_associative).add_reinforcement(reinforcement)
|
324
|
-
end
|
325
|
-
private def build_sub0(stack, str)
|
326
|
-
SystemEquip.each do |k, v|
|
327
|
-
if SystemEquipRegexp[k].match(str)
|
328
|
-
stack << from_equip(v)
|
329
|
-
str = str.gsub(k, "<#{stack.length-1}>")
|
330
|
-
end
|
331
|
-
end
|
332
|
-
[stack, str]
|
333
|
-
end
|
334
|
-
private def build_sub(stack, str, lassoc)
|
335
|
-
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
336
|
-
stack << build_sub(stack, m[2], lassoc)
|
337
|
-
build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
338
|
-
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
339
|
-
compose(build_sub(stack, m[1], lassoc), build_sub(stack, m[2], lassoc))
|
340
|
-
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
341
|
-
stack[m[1].to_i]
|
342
|
-
else
|
343
|
-
smith(str)
|
344
|
-
end
|
345
|
-
end
|
346
319
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
main.para[i]
|
361
|
-
else
|
362
|
-
Mgmg::IR::Compose.new(main.para[i], sub.para[i], Equip9[main_k][i], coef[i], den)
|
320
|
+
class << self
|
321
|
+
def build(str, left_associative: true, reinforcement: [], include_system_equips: true)
|
322
|
+
str = Mgmg.check_string(str)
|
323
|
+
stack = []
|
324
|
+
stack, str = build_sub0(stack, str) if include_system_equips
|
325
|
+
build_sub(stack, str, left_associative).add_reinforcement(reinforcement)
|
326
|
+
end
|
327
|
+
private def build_sub0(stack, str)
|
328
|
+
SystemEquip.each do |k, v|
|
329
|
+
if SystemEquipRegexp[k].match(str)
|
330
|
+
stack << from_equip(v)
|
331
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
332
|
+
end
|
363
333
|
end
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
unless kind
|
375
|
-
raise InvalidEquipClassError.new(m[1])
|
376
|
-
end
|
377
|
-
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
378
|
-
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
379
|
-
sa = ( Mgmg::EquipPosition[kind] == 0 ? :s : :a )
|
380
|
-
|
381
|
-
coef = Equip9[kind].dup
|
382
|
-
coef.e_mul!(Main9[main_m]).e_div!(100)
|
383
|
-
den = ( main_mc==sub_mc ? 200 : 100 )
|
384
|
-
para = Array.new(9) do |i|
|
385
|
-
if coef[i] == 0
|
386
|
-
Mgmg::IR::Const.new(0)
|
334
|
+
[stack, str]
|
335
|
+
end
|
336
|
+
private def build_sub(stack, str, lassoc)
|
337
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
338
|
+
stack << build_sub(stack, m[2], lassoc)
|
339
|
+
build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
340
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
341
|
+
compose(build_sub(stack, m[1], lassoc), build_sub(stack, m[2], lassoc))
|
342
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
343
|
+
stack[m[1].to_i]
|
387
344
|
else
|
388
|
-
|
345
|
+
smith(str)
|
389
346
|
end
|
390
347
|
end
|
391
348
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
349
|
+
def compose(main, sub)
|
350
|
+
main_k, sub_k = main.kind, sub.kind
|
351
|
+
main_s, sub_s = main.star, sub.star
|
352
|
+
main_main, sub_main = main.main, sub.main
|
353
|
+
main_sub, sub_sub = main.sub, sub.sub
|
354
|
+
|
355
|
+
coef = Equip9[main_k].dup
|
356
|
+
coef.sub!(Equip9[sub_k])
|
357
|
+
coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
|
358
|
+
coef.add!(Material9[main_main]).sub!(Material9[sub_main])
|
359
|
+
den = ( main_k==sub_k ? 200 : 100 )
|
360
|
+
para = Array.new(9) do |i|
|
361
|
+
if EquipFilter[main_k][i] == 0
|
362
|
+
main.para[i]
|
363
|
+
else
|
364
|
+
Mgmg::IR::Compose.new(main.para[i], sub.para[i], Equip9[main_k][i], coef[i], den)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
new(main_k, main_s+sub_s, main_sub, sub_main, para)
|
369
|
+
end
|
370
|
+
def smith(str)
|
371
|
+
str = Mgmg.check_string(str)
|
372
|
+
return Cache[str].dup if Cache.has_key?(str)
|
373
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
374
|
+
raise InvalidSmithError.new(str)
|
375
|
+
end
|
376
|
+
kind = EquipIndex[m[1].to_sym]
|
377
|
+
unless kind
|
378
|
+
raise InvalidEquipClassError.new(m[1])
|
379
|
+
end
|
380
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
381
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
382
|
+
sa = ( Mgmg::EquipPosition[kind] == 0 ? :s : :a )
|
383
|
+
|
384
|
+
coef = Equip9[kind].dup
|
385
|
+
coef.e_mul!(Main9[main_m]).e_div!(100)
|
386
|
+
den = ( main_mc==sub_mc ? 200 : 100 )
|
387
|
+
para = Array.new(9) do |i|
|
388
|
+
if coef[i] == 0
|
389
|
+
Mgmg::IR::Const.new(0)
|
390
|
+
else
|
391
|
+
Mgmg::IR::Smith.new(Sub9[sub_m][i], coef[i], den, sa)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
ret = new(kind, (main_s+sub_s).div(2), main_mc, sub_mc, para)
|
396
|
+
Cache.store(str, ret.freeze)
|
397
|
+
ret.dup
|
398
|
+
end
|
399
|
+
def from_equip(equip)
|
400
|
+
para = equip.para.map do |value|
|
401
|
+
Mgmg::IR::Const.new(value)
|
402
|
+
end
|
403
|
+
new(equip.kind, equip.star, equip.main, equip.sub, para)
|
397
404
|
end
|
398
|
-
new(equip.kind, equip.star, equip.main, equip.sub, para)
|
399
405
|
end
|
400
406
|
end
|
401
407
|
end
|
data/lib/mgmg/optimize.rb
CHANGED
@@ -4,9 +4,9 @@ module Mgmg
|
|
4
4
|
InvList = [%w|帽子 フード サンダル|.freeze, %w|宝1 骨1 木1 木2 骨2|.freeze, %w|宝1 骨1 木1|.freeze].freeze
|
5
5
|
def phydef_optimize(str, smith, comp=smith, opt: Option.new)
|
6
6
|
best = if smith.nil? then
|
7
|
-
[str, str.poly(:phydef, opt:
|
7
|
+
[str, str.poly(:phydef, opt:), str.poly(:magdef, opt:), str.poly(:cost, opt:)]
|
8
8
|
else
|
9
|
-
[str, str.build(smith, comp, opt:
|
9
|
+
[str, str.build(smith, comp, opt:)]
|
10
10
|
end
|
11
11
|
str = Mgmg.check_string(str)
|
12
12
|
ai = 0
|
@@ -23,7 +23,7 @@ module Mgmg
|
|
23
23
|
m = /([^\+]*\([^\(]+[綿皮]1\))\]*\Z/.match(str)
|
24
24
|
if m
|
25
25
|
if smith
|
26
|
-
if m[1].sub(/綿1\)/, '皮1)').build(smith, opt:
|
26
|
+
if m[1].sub(/綿1\)/, '皮1)').build(smith, opt:).weight == m[1].sub(/皮1\)/, '綿1)').build(smith, opt:).weight
|
27
27
|
skin = true
|
28
28
|
end
|
29
29
|
else
|
@@ -40,9 +40,9 @@ module Mgmg
|
|
40
40
|
while b
|
41
41
|
r = pd_apply_idx(str, a, b)
|
42
42
|
best = if smith.nil? then
|
43
|
-
pd_better(best, [r, r.poly(:phydef, opt:
|
43
|
+
pd_better(best, [r, r.poly(:phydef, opt:), r.poly(:magdef, opt:), r.poly(:cost, opt:)], opt.magdef_maximize)
|
44
44
|
else
|
45
|
-
pd_better(best, [r, r.build(smith, comp, opt:
|
45
|
+
pd_better(best, [r, r.build(smith, comp, opt:)], opt.magdef_maximize)
|
46
46
|
end
|
47
47
|
b = pd_next_b(b)
|
48
48
|
end
|
@@ -58,9 +58,9 @@ module Mgmg
|
|
58
58
|
while b
|
59
59
|
r = pd_apply_idx(str, a, b)
|
60
60
|
best = if smith.nil? then
|
61
|
-
pd_better(best, [r, r.poly(:phydef, opt:
|
61
|
+
pd_better(best, [r, r.poly(:phydef, opt:), r.poly(:magdef, opt:), r.poly(:cost, opt:)], opt.magdef_maximize)
|
62
62
|
else
|
63
|
-
pd_better(best, [r, r.build(smith, comp, opt:
|
63
|
+
pd_better(best, [r, r.build(smith, comp, opt:)], opt.magdef_maximize)
|
64
64
|
end
|
65
65
|
b = pd_next_b(b)
|
66
66
|
end
|
@@ -159,7 +159,7 @@ module Mgmg
|
|
159
159
|
|
160
160
|
MwList = %w|綿 皮 骨 木 水|.freeze
|
161
161
|
def buster_optimize(str, smith, comp=smith, opt: Option.new)
|
162
|
-
best = ( smith.nil? ? [str, str.poly(:mag_das, opt:
|
162
|
+
best = ( smith.nil? ? [str, str.poly(:mag_das, opt:)] : [str, str.build(smith, comp, opt:)] )
|
163
163
|
str = Mgmg.check_string(str)
|
164
164
|
ai = -1
|
165
165
|
org = nil
|
@@ -174,7 +174,7 @@ module Mgmg
|
|
174
174
|
a = Array.new(ai){ [0, 0, 0] }
|
175
175
|
while a
|
176
176
|
r = bus_apply_idx(str, a)
|
177
|
-
best = bus_better(best, ( smith.nil? ? [r, r.poly(:mag_das, opt:
|
177
|
+
best = bus_better(best, ( smith.nil? ? [r, r.poly(:mag_das, opt:)] : [r, r.build(smith, comp, opt:)] ))
|
178
178
|
a = bus_next_a(a)
|
179
179
|
end
|
180
180
|
best[0]
|
data/lib/mgmg/option.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
module Mgmg
|
2
2
|
class Option
|
3
|
+
Defaults = {
|
4
|
+
left_associative: true, include_system_equips: true,
|
5
|
+
smith_max: 10000, armor_max: 10000, comp_max: 10000
|
6
|
+
}
|
3
7
|
def initialize(
|
4
|
-
left_associative:
|
5
|
-
smith_min: nil, armor_min:nil, comp_min: nil, smith_max:
|
8
|
+
left_associative: Defaults[:left_associative],
|
9
|
+
smith_min: nil, armor_min:nil, comp_min: nil, smith_max: Defaults[:smith_max], armor_max: Defaults[:armor_max], comp_max: Defaults[:comp_max],
|
6
10
|
step: 1, magdef_maximize: true,
|
7
11
|
target_weight: 0, reinforcement: [], buff: nil,
|
8
|
-
irep: nil, cut_exp: Float::INFINITY
|
12
|
+
irep: nil, cut_exp: Float::INFINITY,
|
13
|
+
include_system_equips: Defaults[:include_system_equips]
|
9
14
|
)
|
10
15
|
@left_associative = left_associative
|
11
16
|
@smith_min = smith_min
|
@@ -27,9 +32,10 @@ module Mgmg
|
|
27
32
|
end
|
28
33
|
@irep = irep
|
29
34
|
@cut_exp = cut_exp
|
35
|
+
@include_system_equips = include_system_equips
|
30
36
|
end
|
31
37
|
attr_accessor :left_associative, :smith_min, :armor_min, :comp_min, :smith_max, :armor_max, :comp_max
|
32
|
-
attr_accessor :step, :magdef_maximize, :target_weight, :reinforcement, :irep, :cut_exp
|
38
|
+
attr_accessor :step, :magdef_maximize, :target_weight, :reinforcement, :irep, :cut_exp, :include_system_equips
|
33
39
|
def initialize_copy(other)
|
34
40
|
@left_associative = other.left_associative
|
35
41
|
@smith_min = other.smith_min
|
@@ -44,6 +50,7 @@ module Mgmg
|
|
44
50
|
@reinforcement = other.reinforcement.dup
|
45
51
|
@irep = other.irep
|
46
52
|
@cut_exp = other.cut_exp
|
53
|
+
@include_system_equips = other.include_system_equips
|
47
54
|
end
|
48
55
|
def update_sa_min(recipe, force=true)
|
49
56
|
case recipe
|
@@ -69,9 +76,11 @@ module Mgmg
|
|
69
76
|
self
|
70
77
|
end
|
71
78
|
def set_default(recipe, force: false)
|
79
|
+
@include_system_equips = false if @include_system_equips && !Mgmg::SystemEquipRegexp.values.any?{|re| re.match(recipe)}
|
72
80
|
update_sa_min(recipe, force)
|
73
81
|
@comp_min = recipe.min_comp(opt: self) if force || @comp_min.nil?
|
74
82
|
@irep = recipe.ir(opt: self) if force || @irep.nil?
|
83
|
+
|
75
84
|
self
|
76
85
|
end
|
77
86
|
def buff
|
@@ -81,4 +90,10 @@ module Mgmg
|
|
81
90
|
@reinforcement = v
|
82
91
|
end
|
83
92
|
end
|
93
|
+
|
94
|
+
module_function def option(recipe=nil, **kw)
|
95
|
+
ret = Option.new(**kw)
|
96
|
+
ret.set_default(recipe) unless recipe.nil?
|
97
|
+
ret
|
98
|
+
end
|
84
99
|
end
|
data/lib/mgmg/poly.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Mgmg
|
2
2
|
using Refiner
|
3
3
|
class TPolynomial
|
4
|
+
Cache = Hash.new
|
4
5
|
def initialize(mat, kind, star, main_m, sub_m)
|
5
6
|
@mat, @kind, @star, @main, @sub = mat, kind, star, main_m, sub_m
|
6
7
|
end
|
@@ -285,71 +286,77 @@ module Mgmg
|
|
285
286
|
1
|
286
287
|
end
|
287
288
|
end
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
end
|
296
|
-
def from_equip(equip, para)
|
297
|
-
new(Mat.new(1, 1, equip.para[ParamIndex[para]]), equip.kind, equip.star, equip.main, equip.sub)
|
298
|
-
end
|
299
|
-
def smith(str, para)
|
300
|
-
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
301
|
-
raise ArgumentError.new("given string `#{str}' is unparsable as a smithing recipe")
|
289
|
+
|
290
|
+
class << self
|
291
|
+
ParamIndex = Hash.new
|
292
|
+
%i|attack phydef magdef hp mp str dex speed magic|.each.with_index do |s, i|
|
293
|
+
ParamIndex.store(s, i)
|
294
|
+
ParamIndex.store(i, i)
|
295
|
+
ParamIndex.store(Equip::ParamList[i], i)
|
302
296
|
end
|
303
|
-
|
304
|
-
|
305
|
-
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
306
|
-
para = ParamIndex[para]
|
307
|
-
|
308
|
-
c = ( Equip9[kind][para] * Main9[main_m][para] ).cdiv(100).quo( main_mc==sub_mc ? 200 : 100 )
|
309
|
-
new(Mat.v_array(c*Sub9[sub_m][para], c), kind, (main_s+sub_s).div(2), main_mc, sub_mc)
|
310
|
-
end
|
311
|
-
def compose(main, sub, para)
|
312
|
-
main_k, sub_k = main.kind, sub.kind
|
313
|
-
main_s, sub_s = main.star, sub.star
|
314
|
-
main_main, sub_main = main.main, sub.main
|
315
|
-
main_sub, sub_sub = main.sub, sub.sub
|
316
|
-
para = ParamIndex[para]
|
317
|
-
|
318
|
-
if Equip9[main_k][para] == 0
|
319
|
-
c = 0.quo(1)
|
320
|
-
else
|
321
|
-
c = ( 100 + Equip9[main_k][para] - Equip9[sub_k][para] + Material9[main_main][para] - Material9[sub_main][para] +
|
322
|
-
(main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) ).quo( main_k==sub_k ? 40000 : 20000 )
|
297
|
+
def from_equip(equip, para)
|
298
|
+
new(Mat.new(1, 1, equip.para[ParamIndex[para]]), equip.kind, equip.star, equip.main, equip.sub)
|
323
299
|
end
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
300
|
+
def smith(str, para)
|
301
|
+
key = [str.freeze, para].freeze
|
302
|
+
return Cache[key].dup if Cache.has_key?(key)
|
303
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
304
|
+
raise ArgumentError.new("given string `#{str}' is unparsable as a smithing recipe")
|
305
|
+
end
|
306
|
+
kind = EquipIndex[m[1].to_sym]
|
307
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
308
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
309
|
+
para = ParamIndex[para]
|
310
|
+
|
311
|
+
c = ( Equip9[kind][para] * Main9[main_m][para] ).cdiv(100).quo( main_mc==sub_mc ? 200 : 100 )
|
312
|
+
ret = new(Mat.v_array(c*Sub9[sub_m][para], c), kind, (main_s+sub_s).div(2), main_mc, sub_mc)
|
313
|
+
Cache.store(key, ret.freeze)
|
314
|
+
ret.dup
|
332
315
|
end
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
316
|
+
def compose(main, sub, para)
|
317
|
+
main_k, sub_k = main.kind, sub.kind
|
318
|
+
main_s, sub_s = main.star, sub.star
|
319
|
+
main_main, sub_main = main.main, sub.main
|
320
|
+
main_sub, sub_sub = main.sub, sub.sub
|
321
|
+
para = ParamIndex[para]
|
322
|
+
|
323
|
+
if Equip9[main_k][para] == 0
|
324
|
+
c = 0.quo(1)
|
325
|
+
else
|
326
|
+
c = ( 100 + Equip9[main_k][para] - Equip9[sub_k][para] + Material9[main_main][para] - Material9[sub_main][para] +
|
327
|
+
(main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) ).quo( main_k==sub_k ? 40000 : 20000 )
|
328
|
+
end
|
329
|
+
mat = main.mat.padd(sub.mat.pprod(Mat.h_array(c*Equip9[main_k][para], c)))
|
330
|
+
new(mat, main_k, main_s+sub_s, main_sub, sub_main)
|
340
331
|
end
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
332
|
+
def build(str, para, left_associative: true, include_system_equips: true)
|
333
|
+
str = Mgmg.check_string(str)
|
334
|
+
_para = ParamIndex[para]
|
335
|
+
if _para.nil?
|
336
|
+
raise ArgumentError, "unknown parameter symbol `#{para.inspect}' given"
|
337
|
+
end
|
338
|
+
stack = []
|
339
|
+
stack, str = build_sub0(stack, str, _para) if include_system_equips
|
340
|
+
build_sub(stack, str, _para, left_associative)
|
341
|
+
end
|
342
|
+
private def build_sub0(stack, str, para)
|
343
|
+
SystemEquip.each do |k, v|
|
344
|
+
stack << from_equip(v, para)
|
345
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
346
|
+
end
|
347
|
+
[stack, str]
|
348
|
+
end
|
349
|
+
private def build_sub(stack, str, para, lassoc)
|
350
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
351
|
+
stack << build_sub(stack, m[2], para, lassoc)
|
352
|
+
build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", para, lassoc)
|
353
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
354
|
+
compose(build_sub(stack, m[1], para, lassoc), build_sub(stack, m[2], para, lassoc), para)
|
355
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
356
|
+
stack[m[1].to_i]
|
357
|
+
else
|
358
|
+
smith(str, para)
|
359
|
+
end
|
353
360
|
end
|
354
361
|
end
|
355
362
|
end
|
data/lib/mgmg/recipe.rb
CHANGED
@@ -30,7 +30,7 @@ module Mgmg
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
def option(**kw)
|
33
|
-
@option = temp_opt(
|
33
|
+
@option = temp_opt(**kw)
|
34
34
|
@option
|
35
35
|
end
|
36
36
|
def option=(new_option)
|
@@ -70,9 +70,9 @@ module Mgmg
|
|
70
70
|
smith, armor, comp = opt.smith_min, opt.armor_min, opt.comp_min if smith.nil?
|
71
71
|
case @recipe
|
72
72
|
when String
|
73
|
-
recipe.build(smith, comp, opt:
|
73
|
+
recipe.build(smith, comp, opt:)
|
74
74
|
when Enumerable
|
75
|
-
recipe.build(smith, armor, comp, opt:
|
75
|
+
recipe.build(smith, armor, comp, opt:)
|
76
76
|
else
|
77
77
|
raise BrokenRecipeError
|
78
78
|
end
|
@@ -82,16 +82,16 @@ module Mgmg
|
|
82
82
|
smith, armor, comp = opt.smith_min, opt.armor_min, opt.comp_min if smith.nil?
|
83
83
|
case @recipe
|
84
84
|
when String
|
85
|
-
recipe.show(smith, comp, para
|
85
|
+
recipe.show(smith, comp, para:, opt:)
|
86
86
|
when Enumerable
|
87
|
-
recipe.show(smith, armor, comp, para
|
87
|
+
recipe.show(smith, armor, comp, para:, opt:)
|
88
88
|
else
|
89
89
|
raise BrokenRecipeError
|
90
90
|
end
|
91
91
|
end
|
92
92
|
def search(target, para: @para, **kw)
|
93
93
|
opt = temp_opt(**kw)
|
94
|
-
@recipe.search(para, target, opt:
|
94
|
+
@recipe.search(para, target, opt:)
|
95
95
|
end
|
96
96
|
private def correct_level(s, ac, x, opt)
|
97
97
|
if s.nil?
|
@@ -147,7 +147,7 @@ module Mgmg
|
|
147
147
|
def poly(para=@para, **kw)
|
148
148
|
opt = temp_opt(**kw)
|
149
149
|
if @recipe.kind_of?(String)
|
150
|
-
@recipe.poly(para, opt:
|
150
|
+
@recipe.poly(para, opt:)
|
151
151
|
else
|
152
152
|
raise InvalidRecipeError, "Mgmg::Recipe#poly is available only for String recipes."
|
153
153
|
end
|
@@ -155,7 +155,7 @@ module Mgmg
|
|
155
155
|
def phydef_optimize(smith=nil, comp=smith, **kw)
|
156
156
|
opt = temp_opt(**kw)
|
157
157
|
if @recipe.kind_of?(String)
|
158
|
-
@recipe.phydef_optimize(smith, comp, opt:
|
158
|
+
@recipe.phydef_optimize(smith, comp, opt:)
|
159
159
|
else
|
160
160
|
raise InvalidRecipeError, "Mgmg::Recipe#phydef_optimize is available only for String recipes."
|
161
161
|
end
|
@@ -163,7 +163,7 @@ module Mgmg
|
|
163
163
|
def buster_optimize(smith=nil, comp=smith, **kw)
|
164
164
|
opt = temp_opt(**kw)
|
165
165
|
if @recipe.kind_of?(String)
|
166
|
-
@recipe.buster_optimize(smith, comp, opt:
|
166
|
+
@recipe.buster_optimize(smith, comp, opt:)
|
167
167
|
else
|
168
168
|
raise InvalidRecipeError, "Mgmg::Recipe#buster_optimize is available only for String recipes."
|
169
169
|
end
|
data/lib/mgmg/reinforce.rb
CHANGED
@@ -12,46 +12,45 @@ module Mgmg
|
|
12
12
|
'(' + @vec.map.with_index{|e, i| e==0 ? nil : "#{Equip::ParamList[i]}:#{e}"}.compact.join(', ') + ')'
|
13
13
|
end
|
14
14
|
alias :inspect :to_s
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
15
|
+
|
16
|
+
# スキル名 攻 物 防 HP MP 腕 器 速 魔
|
17
|
+
Skill = {
|
18
|
+
'物防御UP' => Reinforcement.new( Vec[ 0, 10, 0, 0, 0, 0, 0, 0, 0] ),
|
19
|
+
'魔防御UP' => Reinforcement.new( Vec[ 0, 0, 10, 0, 0, 0, 0, 0, 0] ),
|
20
|
+
'腕力UP' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 10, 0, 0, 0] ),
|
21
|
+
'メンテナンス' => Reinforcement.new( Vec[ 50, 0, 0, 0, 0, 0, 0, 0, 0] ),
|
22
|
+
'ガードアップ' => Reinforcement.new( Vec[ 0, 50, 0, 0, 0, 0, 0, 0, 0] ),
|
23
|
+
'パワーアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 50, 0, 0, 0] ),
|
24
|
+
'デックスアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 50, 0, 0] ),
|
25
|
+
'スピードアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 0, 50, 0] ),
|
26
|
+
'マジックアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 0, 0, 50] ),
|
27
|
+
'オールアップ' => Reinforcement.new( Vec[ 0, 50, 0, 0, 0, 50, 50, 50, 50] ),
|
28
|
+
}
|
29
|
+
|
30
|
+
class << self
|
31
|
+
def cuisine(c)
|
32
|
+
Reinforcement.new( Vec[*(c.vec), *Array.new(6, 0)] )
|
33
|
+
end
|
34
|
+
def compile(arg)
|
35
|
+
case arg
|
36
|
+
when Reinforcement
|
37
|
+
arg
|
38
|
+
when Cuisine
|
39
|
+
cuisine(arg)
|
40
|
+
when String
|
41
|
+
if Skill.has_key?(arg)
|
42
|
+
Skill[arg]
|
43
|
+
elsif SystemCuisine.has_key?(arg)
|
44
|
+
cuisine(SystemCuisine[arg])
|
45
|
+
else
|
46
|
+
raise InvalidReinforcementNameError, arg
|
47
|
+
end
|
46
48
|
else
|
47
|
-
raise
|
49
|
+
raise ArgumentError, "The argument should be Mgmg::Cuisine or skill name String. (`#{arg}' is given)"
|
48
50
|
end
|
49
|
-
else
|
50
|
-
raise ArgumentError, "The argument should be Mgmg::Cuisine or skill name String. (`#{arg}' is given)"
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
55
54
|
class Equip
|
56
55
|
def reinforce(*arg)
|
57
56
|
arg.each do |r|
|