1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
..
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
36
37
38
39
40
41
42
43
44
45
46
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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
227
228
229
230
231
232
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
258
259
260
261
262
263
264
265
|
local constants = {
rune_mine_interval = 90;
-- 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', 'Shoddy', 'Ordinary', 'Pristine'};
-- how many grades of rune quality/power there are
}
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)
rune.item = id
minetest.register_craftitem(id, {
description = sorcery.lib.color(rune.tone):readable():fmt(rune.name .. ' Rune');
short_description = rune.name .. ' Rune';
................................................................................
groups = {
sorcery_rune = 1;
not_in_creative_inventory = 1;
};
_proto = { id = name, data = rune; };
})
end)
local rune_set = function(stack,r)
local m = stack:get_meta()
local def = stack:get_definition()._proto.data
local grade
if r.grade then grade = r.grade
elseif m:contains('rune_grade') then grade = m:get_int('rune_grade') end
................................................................................
local title = sorcery.lib.color(def.tone):readable():fmt(string.format('%s %s Rune',qpfx,def.name))
m:set_int('rune_grade',grade)
m:set_string('description',title)
end
sorcery.amulet = {}
sorcery.amulet.setrune = function(stack,rune)
local m = stack:get_meta()
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', spell.name)
m:set_string('description', sorcery.lib.ui.tooltip {
title = name;
color = spell.tone;
desc = spell.desc;
})
else
m:set_string('description','')
m:set_string('amulet_rune','')
m:set_string('amulet_rune_grade','')
end
return stack
end
sorcery.amulet.getrune = function(stack)
local m = stack:get_meta()
if not m:contains('amulet_rune') then return nil end
local rune = m:get_string('amulet_rune')
local grade = m:get_int('amulet_rune_grade')
local rs = ItemStack(sorcery.data.runes[rune].item)
................................................................................
rune_set(rs, {grade = grade})
return rs
end
sorcery.amulet.getspell = function(stack)
local m = stack:get_meta()
local proto = stack:get_definition()._sorcery.amulet
local rune = m:get_string('amulet_rune')
local rd = sorcery.data.runes[rune]
local spell = rd.amulets[proto.base]
if not spell then return nil end
local title,desc,cast = spell.name, spell.desc, spell.cast
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
end
return {
rune = rune;
spell = spell;
name = title;
desc = desc;
cast = cast;
tone = sorcery.lib.color(rd.tone);
}
end
local runeforge_update = function(pos,time)
local m = minetest.get_meta(pos)
local i = m:get_inventory()
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
if time and pow_min then -- roll for runes
local rolls = math.floor(time/constants.rune_mine_interval)
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
print('rolled for runes, got', dump(newrunes))
for _,r in pairs(newrunes) do
if i:room_for_item('cache',r) then
local qual = math.random(#constants.rune_grades)
rune_set(r,{grade = qual})
i:add_item('cache',r)
end
end
end
local spec = string.format([[
formspec_version[3] size[10.25,8] real_coordinates[true]
list[context;cache;%f,0.25;%u,1;]
list[context;amulet;3.40,1.50;1,1;]
list[context;active;5.90,1.50;1,1;]
list[current_player;main;0.25,3;8,4;]
image[0.25,0.50;1,1;sorcery_statlamp_%s.png]
]], (10.5 - constants.rune_cache_max*1.25)/2, constants.rune_cache_max,
pow_max and 'green' or (pow_min and 'yellow') or 'off')
m:set_string('formspec',spec)
return true
end
local rfbox = {
type = 'fixed';
fixed = {
-0.5, -0.5, -0.5;
................................................................................
'default_copper_block.png';
};
_sorcery = {
ley = {
mode = 'consume';
affinity = {'praxic'};
power = function(pos,time)
local max,min = 0
for _,r in pairs(sorcery.data.runes) do
if r.minpower > max then max = r.minpower end
if min == nil or r.minpower < min then min = r.minpower end
end
return min*time,max*time
end;
};
on_leychange = runeforge_update;
recipe = {
note = 'Periodically creates runes when sufficiently powered and can be used to imbue them into an amulet, giving it a powerful magical effect';
};
};
on_construct = function(pos)
local m = minetest.get_meta(pos)
local i = m:get_inventory()
i:set_size('cache',constants.rune_cache_max)
i:set_size('amulet',1)
i:set_size('active',1)
m:set_string('infotext','Rune Forge')
runeforge_update(pos)
minetest.get_node_timer(pos):start(constants.rune_mine_interval)
end;
after_dig_node = sorcery.lib.node.purge_only {'amulet'};
on_timer = runeforge_update;
on_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user)
local inv = minetest.get_meta(pos):get_inventory()
if fl == 'active' then
inv:set_stack('amulet',1,sorcery.amulet.setrune(inv:get_stack('amulet',1)))
elseif tl == 'active' then
inv:set_stack('amulet',1,sorcery.amulet.setrune(inv:get_stack('amulet',1), inv:get_stack(tl,ti)))
end
end;
on_metadata_inventory_put = function(pos, list, idx, stack, user)
if list == 'amulet' then
local inv = minetest.get_meta(pos):get_inventory()
inv:set_stack('active',1,ItemStack(sorcery.amulet.getrune(stack)))
end
end;
on_metadata_inventory_take = function(pos, list, idx, stack, user)
if list == 'amulet' then
minetest.get_meta(pos):get_inventory():set_stack('active',1,ItemStack())
end
end;
allow_metadata_inventory_put = function(pos,list,idx,stack,user)
if list == 'amulet' then
if minetest.get_item_group(stack:get_name(), 'sorcery_amulet') ~= 0 then
return 1
end
end
return 0
end;
allow_metadata_inventory_take = function(pos,list,idx,stack,user)
if list == 'amulet' then return 1 end
return 0
end;
allow_metadata_inventory_move = function(pos, fl,fi, tl,ti, count, user)
if fl == 'cache' then
if tl == 'cache' then return 1 end
if tl == 'active' then
local inv = minetest.get_meta(pos):get_inventory()
if 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' then return 1 end
end
return 0
end;
})
do local m = sorcery.data.metals
-- temporary recipe until a fancier multi-part crafting path can be come up with
|
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
<
|
>
>
>
>
|
|
<
|
>
>
>
>
>
|
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
..
44
45
46
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
190
191
192
193
194
195
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
227
228
229
230
231
232
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
-- 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
amulet_grades = {'Slight', 'Minor', 'Major', 'Grand', 'Ultimate' };
-- what kind of amulet each rune grade translates to
phial_kinds = {
lesser = {grade = 1; name = 'Lesser'; infusion = 'sorcery:powder_brass'};
simple = {grade = 2; name = 'Simple'; infusion = 'sorcery:powder_silver'};
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)
rune.item = id
minetest.register_craftitem(id, {
description = sorcery.lib.color(rune.tone):readable():fmt(rune.name .. ' Rune');
short_description = rune.name .. ' Rune';
................................................................................
groups = {
sorcery_rune = 1;
not_in_creative_inventory = 1;
};
_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;
inventory_image = w.img;
groups = {
sorcery_magitech = 1;
sorcery_rune_wrench = 1;
crafttool = 50;
};
_proto = w;
_sorcery = {
recipe = { note = w.note };
};
})
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';
powers = { imbue = 30 };
note = 'A runeworking tool used to imbue amulets with enchantments';
}
register_rune_wrench {
name = 'sorcery:rune_wrench_iridium', desc = 'Iridium Rune Wrench';
img = 'sorcery_rune_wrench_iridium.png', metal = 'iridium';
powers = { imbue = 80, extract = 40 };
note = 'A rare and powerful runeworking tool used to imbue amulets with enchantments, or extract runes intact from enchanted amulets';
}
local rune_set = function(stack,r)
local m = stack:get_meta()
local def = stack:get_definition()._proto.data
local grade
if r.grade then grade = r.grade
elseif m:contains('rune_grade') then grade = m:get_int('rune_grade') end
................................................................................
local title = sorcery.lib.color(def.tone):readable():fmt(string.format('%s %s Rune',qpfx,def.name))
m:set_int('rune_grade',grade)
m:set_string('description',title)
end
sorcery.amulet = {}
sorcery.amulet.setrune = function(stack,rune,user)
local m = stack:get_meta()
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 {
stack = stack;
meta = m;
user = user;
self = spell;
} end
else
local spell = sorcery.amulet.getspell(stack)
m:set_string('description','')
m:set_string('amulet_rune','')
m:set_string('amulet_rune_grade','')
if spell and spell.remove then spell.remove {
stack = stack;
meta = m;
user = user;
self = spell;
} end
end
return stack
end
sorcery.amulet.stats = function(stack)
local spell = sorcery.amulet.getspell(stack)
if not spell then return nil end
local power = spell.grade
if spell.base_spell then
-- only consider the default effect of the frame metal
-- if the frame doesn't totally override the spell
power = power * (spell.framestats and spell.framestats.power or 1)
end
return {
power = power;
}
end
sorcery.amulet.getrune = function(stack)
local m = stack:get_meta()
if not m:contains('amulet_rune') then return nil end
local rune = m:get_string('amulet_rune')
local grade = m:get_int('amulet_rune_grade')
local rs = ItemStack(sorcery.data.runes[rune].item)
................................................................................
rune_set(rs, {grade = grade})
return rs
end
sorcery.amulet.getspell = function(stack)
local m = stack:get_meta()
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;
}
end
local runeforge_update = function(pos,time)
local m = minetest.get_meta(pos)
local i = m:get_inventory()
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)
-- consume a phial
local ph = i:get_stack('phial',1)
local n = ph:get_name()
ph:take_item(1) i:set_stack('phial',1,ph)
minetest.add_item(pos,i:add_item('refuse',ItemStack(sorcery.register.residue.db[n])))
else break end
end
end
has_phial = has_phial()
local spec = string.format([[
formspec_version[3] size[10.25,8] real_coordinates[true]
list[context;cache;%f,0.25;%u,1;]
list[context;amulet;3.40,1.50;1,1;]
list[context;active;5.90,1.50;1,1;]
list[context;wrench;1.25,1.75;1,1;]
list[context;phial;7.25,1.75;1,1;]
list[context;refuse;8.50,1.75;1,1;]
list[current_player;main;0.25,3;8,4;]
image[0.25,0.50;1,1;sorcery_statlamp_%s.png]
]], (10.5 - constants.rune_cache_max*1.25)/2, constants.rune_cache_max,
((has_phial and pow_max) and 'green' ) or
((has_phial and pow_min) and 'yellow') or 'off')
local ghost = function(slot,x,y,img)
if i:is_empty(slot) then spec = spec .. string.format([[
image[%f,%f;1,1;%s.png]
]], x,y,img) end
end
ghost('active',5.90,1.50,'sorcery_ui_ghost_rune')
ghost('amulet',3.40,1.50,'sorcery_ui_ghost_amulet')
ghost('wrench',1.25,1.75,'sorcery_ui_ghost_rune_wrench')
ghost('phial',7.25,1.75,'vessels_shelf_slot')
m:set_string('formspec',spec)
if i:is_empty('phial') then return false end
return true
end
local rfbox = {
type = 'fixed';
fixed = {
-0.5, -0.5, -0.5;
................................................................................
'default_copper_block.png';
};
_sorcery = {
ley = {
mode = 'consume';
affinity = {'praxic'};
power = function(pos,time)
local i = minetest.get_meta(pos):get_inventory()
if i:is_empty('phial') then return 0 end
local phial = i:get_stack('phial',1)
local max,min = 0
for _,r in pairs(sorcery.data.runes) do
if r.minpower > max then max = r.minpower end
if min == nil or r.minpower < min then min = r.minpower end
end
-- high-quality phials reduce power usage
local fac = select(2, calc_phial_props(phial))
min = min * fac max = max * fac
return min*time,max*time
end;
};
on_leychange = runeforge_update;
recipe = {
note = 'Periodically creates runes when sufficiently powered and can be used to imbue them into an amulet, giving it a powerful magical effect';
};
};
on_construct = function(pos)
local m = minetest.get_meta(pos)
local i = m:get_inventory()
i:set_size('cache',constants.rune_cache_max)
i:set_size('wrench',1) i:set_size('phial',1) i:set_size('refuse',1)
i:set_size('amulet',1) i:set_size('active',1)
m:set_string('infotext','Rune Forge')
runeforge_update(pos)
end;
after_dig_node = sorcery.lib.node.purge_only {'amulet'};
on_timer = runeforge_update;
on_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
local wwear = function(cap)
local s = inv:get_stack('wrench',1)
local wear = 65535 / wrench.powers[cap]
s:add_wear(wear)
inv:set_stack('wrench',1,s)
end
if fl == 'active' then
inv:set_stack('amulet',1,sorcery.amulet.setrune(inv:get_stack('amulet',1),nil,user))
-- only special wrenches can extract runes intact
if wrench.powers.extract then wwear('extract')
minetest.sound_play('sorcery_chime', { pos = pos, gain = 0.5 })
elseif wrench.powers.purge then wwear('purge')
inv:set_stack(tl,ti,ItemStack(nil))
minetest.sound_play('sorcery_disjoin', { pos = pos, gain = 0.5 })
end
elseif tl == 'active' and wrench.powers.imbue then
local amulet = sorcery.amulet.setrune(inv:get_stack('amulet',1), inv:get_stack(tl,ti), user)
local spell = sorcery.amulet.getspell(amulet)
sorcery.vfx.enchantment_sparkle({
under = pos;
above = vector.add(pos,{x=0,y=1,z=0});
}, spell.tone:brighten(1.2):hex())
minetest.sound_play('xdecor_enchanting', { pos = pos, gain = 0.5 })
inv:set_stack('amulet',1,amulet)
wwear('imbue')
end
-- trigger the update early to clean up the ghost image :/
-- minetest needs a cleaner way to handle these
runeforge_update(pos)
end;
on_metadata_inventory_put = function(pos, list, idx, stack, user)
local inv = minetest.get_meta(pos):get_inventory()
if list == 'amulet' then
inv:set_stack('active',1,ItemStack(sorcery.amulet.getrune(stack)))
end
runeforge_update(pos)
if not inv:is_empty('phial') then
minetest.get_node_timer(pos):start(calc_phial_props(inv:get_stack('phial',1)))
end
end;
on_metadata_inventory_take = function(pos, list, idx, stack, user)
if list == 'amulet' then
minetest.get_meta(pos):get_inventory():set_stack('active',1,ItemStack())
end
runeforge_update(pos)
end;
allow_metadata_inventory_put = function(pos,list,idx,stack,user)
if list == 'amulet' then
if minetest.get_item_group(stack:get_name(), 'sorcery_amulet') ~= 0 then
return 1
end
end
if list == 'phial' then
if minetest.get_item_group(stack:get_name(), 'sorcery_phial') ~= 0 then
return stack:get_count()
end
end
if list == 'wrench' then
if minetest.get_item_group(stack:get_name(), 'sorcery_rune_wrench') ~= 0 then
return 1
end
end
return 0
end;
allow_metadata_inventory_take = function(pos,list,idx,stack,user)
if list == 'amulet' or list == 'wrench' then return 1 end
if list == 'phial' or list == 'refuse' then return stack:get_count() end
return 0
end;
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
return 0
end;
})
do local m = sorcery.data.metals
-- temporary recipe until a fancier multi-part crafting path can be come up with
|