1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
-- TODO make some kind of disposable "filter" tool that runeforges require
-- to generate runes and that wears down over time, to make amulets more
-- expensive than they currently are? the existing system is neat but
-- i think amulets are a little overpowered for something that just
-- passively consumes ley-current
local constants = {
rune_mine_interval = 250;
-- how often a powered forge rolls for new runes
rune_cache_max = 4;
-- how many runes a runeforge can hold at a time
rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'};
-- how many grades of rune quality/power there are
................................................................................
great = {grade = 3; name = 'Great'; infusion = 'sorcery:powder_gold'};
splendid = {grade = 4; name = 'Splendid'; infusion = 'sorcery:powder_electrum'};
exalted = {grade = 5; name = 'Exalted'; infusion = 'sorcery:powder_levitanium'};
supreme = {grade = 6; name = 'Supreme'; infusion = 'sorcery:essence_force'};
};
}
local calc_phial_props = function(phial) --> mine interval: float, time factor: float
local g = phial:get_definition()._proto.grade
local i = constants.rune_mine_interval
local fac = (g-1) / 5
return i - ((i*0.5) * fac), 0.5 * fac
end
sorcery.register.runes.foreach('sorcery:generate',{},function(name,rune)
local id = 'sorcery:rune_' .. name
rune.image = rune.image or string.format('sorcery_rune_%s.png',name)
................................................................................
};
_proto = { id = name, data = rune; };
})
end)
for name,p in pairs(constants.phial_kinds) do
local f = string.format
local color = sorcery.lib.color(255,27,188)
local fac = p.grade / 6
local id = f('phial_%s', name);
sorcery.register_potion_tbl {
name = id;
label = f('%s Phial',p.name);
desc = "A powerful liquid consumed in the operation of a rune forge. Its quality determines how fast new runes can be constructed.";
color = color:brighten(1 + fac*0.5);
imgvariant = (fac >= 5) and 'sparkle' or 'dull';
glow = 5+p.grade;
extra = {
groups = { sorcery_phial = p.grade };
_proto = { id = name, data = p };
};
}
sorcery.register.infusions.link {
infuse = p.infusion;
into = 'sorcery:potion_subtle';
output = id;
}
end
local register_rune_wrench = function(w)
local mp = sorcery.data.metals[w.metal].parts
minetest.register_tool(w.name, {
description = w.desc;
................................................................................
};
})
minetest.register_craft {
output = w.name;
recipe = {
{'', mp.fragment,''};
{'', mp.ingot, mp.fragment};
{'sorcery:vidrium_fragment','', ''};
};
}
end
register_rune_wrench {
name = 'sorcery:rune_wrench', desc = 'Rune Wrench';
img = 'sorcery_rune_wrench.png', metal = 'brass';
................................................................................
if rune then
local rp = rune:get_definition()._proto
local rg = rune:get_meta():get_int('rune_grade')
m:set_string('amulet_rune', rp.id)
m:set_int('amulet_rune_grade', rg)
local spell = sorcery.amulet.getspell(stack)
if not spell then return nil end
local name = string.format('Amulet of %s %s', constants.amulet_grades[rg], spell.name)
m:set_string('description', sorcery.lib.ui.tooltip {
title = name;
color = spell.tone;
desc = spell.desc;
})
if spell.apply then spell.apply {
................................................................................
local proto = stack:get_definition()._sorcery.amulet
if not m:contains('amulet_rune') then return nil end
local rune = m:get_string('amulet_rune')
local rg = m:get_string('amulet_rune_grade')
local rd = sorcery.data.runes[rune]
local spell = rd.amulets[proto.base]
if not spell then return nil end
local title,desc,cast,apply,remove = spell.name, spell.desc, spell.cast, spell.apply, spell.remove -- FIXME in serious need of refactoring
local base_spell = true
if proto.frame and spell.frame and spell.frame[proto.frame] then
local sp = spell.frame[proto.frame]
title = sp.name or title
desc = sp.desc or desc
cast = sp.desc or cast
apply = sp.apply or apply
remove = sp.remove or remove
base_spell = false
end
return {
rune = rune;
grade = rg;
spell = spell;
name = title, desc = desc;
cast = cast, apply = apply, remove = remove;
frame = proto.frame;
framestats = proto.frame and sorcery.data.metals[proto.frame].amulet;
tone = sorcery.lib.color(rd.tone);
base_spell = base_spell;
}
................................................................................
local l = sorcery.ley.netcaps(pos,time or 1)
local pow_min = l.self.powerdraw >= l.self.minpower
local pow_max = l.self.powerdraw >= l.self.maxpower
local has_phial = function() return not i:is_empty('phial') end
if time and has_phial() and pow_min then -- roll for runes
local rolls = math.floor(time/calc_phial_props(i:get_stack('phial',1)))
local newrunes = {}
for _=1,rolls do
local choices = {}
for name,rune in pairs(sorcery.data.runes) do
if rune.minpower*time <= l.self.powerdraw and math.random(rune.rarity) == 1 then
local n = ItemStack(rune.item)
choices[#choices + 1] = n
end
end
if #choices > 0 then newrunes[#newrunes + 1] = choices[math.random(#choices)] end
end
for _,r in pairs(newrunes) do
if i:room_for_item('cache',r) and has_phial() then
local qual = math.random(#constants.rune_grades)
rune_set(r,{grade = qual})
i:add_item('cache',r)
................................................................................
allow_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user)
local inv = minetest.get_meta(pos):get_inventory()
local wrench if not inv:is_empty('wrench') then
wrench = inv:get_stack('wrench',1):get_definition()._proto
end
if fl == 'cache' then
if tl == 'cache' then return 1 end
if tl == 'active' then
print(dump(wrench))
if wrench and wrench.powers.imbue and not inv:is_empty('amulet') then
local amulet = inv:get_stack('amulet',1)
local rune = inv:get_stack(fl,fi)
if sorcery.data.runes[rune:get_definition()._proto.id].amulets[amulet:get_definition()._sorcery.amulet.base] then
return 1
end
end
end
end
if fl == 'active' then
if tl == 'cache' and wrench and (wrench.powers.extract or wrench.powers.purge) then return 1 end
end
|
|
|
|
|
|
|
<
>
>
>
>
|
>
|
>
<
|
|
>
|
>
>
|
>
>
|
>
>
|
>
>
>
>
>
>
>
>
|
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
...
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
|
-- TODO make some kind of disposable "filter" tool that runeforges require
-- to generate runes and that wears down over time, to make amulets more
-- expensive than they currently are? the existing system is neat but
-- i think amulets are a little overpowered for something that just
-- passively consumes ley-current
local constants = {
rune_mine_interval = 240;
-- how often a powered forge rolls for new runes
rune_cache_max = 4;
-- how many runes a runeforge can hold at a time
rune_grades = {'Fragile', 'Weak', 'Ordinary', 'Pristine', 'Sublime'};
-- how many grades of rune quality/power there are
................................................................................
great = {grade = 3; name = 'Great'; infusion = 'sorcery:powder_gold'};
splendid = {grade = 4; name = 'Splendid'; infusion = 'sorcery:powder_electrum'};
exalted = {grade = 5; name = 'Exalted'; infusion = 'sorcery:powder_levitanium'};
supreme = {grade = 6; name = 'Supreme'; infusion = 'sorcery:essence_force'};
};
}
local calc_phial_props = function(phial) --> mine interval: float, time factor: float
local g = phial:get_definition()._proto.data.grade
local i = constants.rune_mine_interval
local fac = (g-1) / 5
return i - ((i*0.5) * fac), 0.5 * fac
end
sorcery.register.runes.foreach('sorcery:generate',{},function(name,rune)
local id = 'sorcery:rune_' .. name
rune.image = rune.image or string.format('sorcery_rune_%s.png',name)
................................................................................
};
_proto = { id = name, data = rune; };
})
end)
for name,p in pairs(constants.phial_kinds) do
local f = string.format
local color = sorcery.lib.color(204,38,235)
local fac = p.grade / 6
local id = f('phial_%s', name);
sorcery.register_potion_tbl {
name = id;
label = f('%s Phial',p.name);
desc = "A powerful liquid consumed in the operation of a rune forge. Its quality determines how fast new runes can be constructed and how much energy is required by the process.";
color = color:brighten(1 + fac*0.5);
imgvariant = (fac >= 5) and 'sparkle' or 'dull';
glow = 5+p.grade;
extra = {
groups = { sorcery_phial = p.grade };
_proto = { id = name, data = p };
};
}
sorcery.register.infusions.link {
infuse = p.infusion;
into = 'sorcery:potion_subtle';
output = 'sorcery:'..id;
}
end
local register_rune_wrench = function(w)
local mp = sorcery.data.metals[w.metal].parts
minetest.register_tool(w.name, {
description = w.desc;
................................................................................
};
})
minetest.register_craft {
output = w.name;
recipe = {
{'', mp.fragment,''};
{'', mp.ingot, mp.fragment};
{'sorcery:fragment_vidrium','', ''};
};
}
end
register_rune_wrench {
name = 'sorcery:rune_wrench', desc = 'Rune Wrench';
img = 'sorcery_rune_wrench.png', metal = 'brass';
................................................................................
if rune then
local rp = rune:get_definition()._proto
local rg = rune:get_meta():get_int('rune_grade')
m:set_string('amulet_rune', rp.id)
m:set_int('amulet_rune_grade', rg)
local spell = sorcery.amulet.getspell(stack)
if not spell then return nil end
local name
if spell.minrune then -- indicating quality makes less sense if it's restricted
name = string.format('Amulet of %s', spell.name)
else
name = string.format('Amulet of %s %s', constants.amulet_grades[rg], spell.name)
end
m:set_string('description', sorcery.lib.ui.tooltip {
title = name;
color = spell.tone;
desc = spell.desc;
})
if spell.apply then spell.apply {
................................................................................
local proto = stack:get_definition()._sorcery.amulet
if not m:contains('amulet_rune') then return nil end
local rune = m:get_string('amulet_rune')
local rg = m:get_string('amulet_rune_grade')
local rd = sorcery.data.runes[rune]
local spell = rd.amulets[proto.base]
if not spell then return nil end
local title,desc,cast,apply,remove,mingrade = spell.name, spell.desc, spell.cast, spell.apply, spell.remove, spell.mingrade -- FIXME in serious need of refactoring
local base_spell = true
if proto.frame and spell.frame and spell.frame[proto.frame] then
local sp = spell.frame[proto.frame]
title = sp.name or title
desc = sp.desc or desc
cast = sp.desc or cast
apply = sp.apply or apply
remove = sp.remove or remove
mingrade = sp.mingrade or remove
base_spell = false
end
return {
rune = rune, grade = rg;
spell = spell, mingrade = mingrade;
name = title, desc = desc;
cast = cast, apply = apply, remove = remove;
frame = proto.frame;
framestats = proto.frame and sorcery.data.metals[proto.frame].amulet;
tone = sorcery.lib.color(rd.tone);
base_spell = base_spell;
}
................................................................................
local l = sorcery.ley.netcaps(pos,time or 1)
local pow_min = l.self.powerdraw >= l.self.minpower
local pow_max = l.self.powerdraw >= l.self.maxpower
local has_phial = function() return not i:is_empty('phial') end
if time and has_phial() and pow_min then -- roll for runes
local int, powerfac = calc_phial_props(i:get_stack('phial',1))
local rolls = math.floor(time/int)
local newrunes = {}
for _=1,rolls do
local choices = {}
for name,rune in pairs(sorcery.data.runes) do
print('considering',name)
print('-- power',rune.minpower,(rune.minpower*powerfac)*time,'//',l.self.powerdraw,l.self.powerdraw/time,'free',l.freepower,'max',l.maxpower)
if (rune.minpower*powerfac)*time <= l.self.powerdraw and math.random(rune.rarity) == 1 then
local n = ItemStack(rune.item)
choices[#choices + 1] = n
end
end
if #choices > 0 then newrunes[#newrunes + 1] = choices[math.random(#choices)] end
print('rune choices:',dump(choices))
print('me',dump(l.self))
end
for _,r in pairs(newrunes) do
if i:room_for_item('cache',r) and has_phial() then
local qual = math.random(#constants.rune_grades)
rune_set(r,{grade = qual})
i:add_item('cache',r)
................................................................................
allow_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user)
local inv = minetest.get_meta(pos):get_inventory()
local wrench if not inv:is_empty('wrench') then
wrench = inv:get_stack('wrench',1):get_definition()._proto
end
if fl == 'cache' then
if tl == 'cache' then return 1 end
if tl == 'active' and inv:is_empty('active') then
print(dump(wrench))
if wrench and wrench.powers.imbue and not inv:is_empty('amulet') then
local amulet = inv:get_stack('amulet',1)
local rune = inv:get_stack(fl,fi)
local runeid = rune:get_definition()._proto.id
local runegrade = rune:get_meta():get_int('rune_grade')
if sorcery.data.runes[runeid].amulets[amulet:get_definition()._sorcery.amulet.base] then
local spell do -- haaaack
local i=ItemStack(amulet:get_name())
local im = i:get_meta()
im:set_string('amulet_rune',runeid)
im:set_int('amulet_rune_grade',runegrade)
spell = sorcery.amulet.getspell(i)
end
if not spell.mingrade or runegrade >= spell.mingrade then
return 1
end
end
end
end
end
if fl == 'active' then
if tl == 'cache' and wrench and (wrench.powers.extract or wrench.powers.purge) then return 1 end
end
|