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
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
...
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
...
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
...
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
...
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
...
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
...
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
|
local cast_sparkle = function(ctx,color,strength,duration)
minetest.add_particlespawner {
amount = 70 * strength;
time = duration or 1.5;
attached = ctx.caster;
texture = sorcery.lib.image('sorcery_spark.png'):multiply(color):render();
minpos = { x = -0.1, z = 0.5, y = 1.2};
maxpos = { x = 0.1, z = 0.3, y = 1.6};
minvel = { x = -0.5, z = -0.5, y = -0.5};
maxvel = { x = 0.5, z = 0.5, y = 0.5};
minacc = { x = 0.0, z = 0.0, y = 0.5};
maxacc = { x = 0.0, z = 0.0, y = 0.5};
minsize = 0.4, maxsize = 0.8;
minexptime = 1, maxexptime = 1;
glow = 14;
animation = {
type = 'vertical_frames';
aspect_w = 16;
aspect_h = 16;
length = 1.1;
};
}
end
local enchantment_sparkle = function(ctx,color)
local minvel, maxvel
if minetest.get_node(vector.add(ctx.target.under,{y=1,z=0,x=0})).name == 'air' then
minvel = {x=0,z=0,y= 0.3} maxvel = {x=0,z=0,y= 1.5};
else
local dir = vector.subtract(ctx.target.under,ctx.target.above)
minvel = vector.multiply(dir, 0.3)
maxvel = vector.multiply(dir, 1.2)
end
return minetest.add_particlespawner {
amount = 50;
time = 0.5;
minpos = vector.subtract(ctx.target.under, 0.5);
maxpos = vector.add(ctx.target.under, 0.5);
minvel = minvel, maxvel = maxvel;
minexptime = 1, maxexptime = 2;
minsize = 0.5, maxsize = 2;
texture = sorcery.lib.image('sorcery_spark.png'):multiply(color):render();
animation = {
type = 'vertical_frames';
aspect_w = 16, aspect_h = 16;
length = 2;
};
glow = 14;
}
end
local anchorwand = function(aff,uses,recipe)
local affcolor = sorcery.lib.color(sorcery.data.affinities[aff].color)
return {
name = aff .. ' anchor';
desc = 'With an enchanter, anchor ' .. aff .. ' spells into an object to enable it to produce preternatural effects';
uses = uses;
affinity = recipe;
color = affcolor;
sound = 'xdecor_enchanting'; -- FIXME make own
cast = function(ctx)
if (not ctx.target) or ctx.target.type ~= 'node' then return false end
local node = minetest.get_node(ctx.target.under)
if node.name ~= 'sorcery:enchanter' then return false end
local inv = minetest.get_meta(ctx.target.under):get_inventory()
if inv:is_empty('item') then return false end
local subj = inv:get_stack('item',1)
-- now we have everything we need. this part is complex.
-- first, we need to check the item to see if it is in a
................................................................................
-- note: this was written before terminology was standardized,
-- and "leytype" corresponds to what is otherwise known as an
-- "affinity"; "affinity" after this comment is widely misused
return {
flame = {
name = 'flamebolt';
color = {255,89,16};
uses = 64;
affinity = {'acacia','blazing'};
leytype = 'praxic';
desc = 'Conjure a gout of fire to scorch your foes with a flick of this wand';
cast = function(ctx)
local speed = 30 -- TODO maybe amethyst tip increases speed?
local heading = ctx.heading
heading.pos.y = heading.pos.y + 1.5 -- TODO maths
local bolt = minetest.add_entity(heading.pos,'sorcery:spell_projectile_flamebolt')
bolt:set_rotation(heading.yaw)
local vel = {
x = heading.yaw.x * speed;
y = heading.yaw.y * speed;
z = heading.yaw.z * speed;
};
bolt:set_velocity(vel)
end;
};
seal = {
name = 'sealing';
color = {255,238,16};
uses = 32;
................................................................................
leytype = 'imperic';
affinity = {'pine','dark'};
cast = function(ctx)
if ctx.target == nil or ctx.target.type ~= 'node' then return false end
local meta = minetest.get_meta(ctx.target.under)
-- first we need to check if the wand has an identifying 'key' yet,
-- and set one if not.
local wandmode = ctx.base.gem == 'sapphire'
local keycode
if ctx.meta:contains('sorcery_wand_key') then
keycode = ctx.meta:get_string('sorcery_wand_key')
else
keycode = sorcery.lib.str.rand(32)
ctx.meta:set_string('sorcery_wand_key', keycode)
-- ctx.meta:mark_as_private('sorcery_wand_key')
end
if meta:contains('owner') then
-- owner is already set -- can we break the enchantment?
if meta:get_string('sorcery_wand_key') == keycode then
meta:set_string('owner','')
meta:set_string('sorcery_wand_key','')
meta:set_string('sorcery_seal_mode','')
enchantment_sparkle(ctx,sorcery.lib.color(101,255,142))
else return false end
else
meta:set_string('sorcery_wand_key',keycode)
meta:mark_as_private('sorcery_wand_key')
meta:set_string('owner',ctx.caster:get_player_name())
if wandmode then
meta:set_string('sorcery_seal_mode','wand')
end
enchantment_sparkle(ctx,sorcery.lib.color(255,201,27))
end
end;
};
leyspark = {
................................................................................
};
meld = {
name = 'melding';
uses = 48;
leytype = 'syncretic';
color = {172,65,255};
affinity = {'apple','verdant'};
desc = 'Meld the properties of three balanced items on an enchanter to create a new one with special properties, but destroying the old ones and losing two thirds of the mass in the process. The precise outcome is not always predictable.';
};
divide = {
name = 'division';
uses = 19;
leytype = 'syncretic';
color = {255,65,121};
affinity = {'apple','shimmering'};
desc = 'Shatter an item on an enchanter, dividing its essence equally into three parts and precipitating it into new items embodying various properties of the destroyed item. The outcome is not always predictable.';
};
obliterate = {
name = 'obliteration';
uses = 129;
color = {175,6,212};
affinity = {'aspen','dark'};
leytype = 'occlutic';
desc = 'Totally and irreversibly obliterate all items on an enchanter.';
cast = function(ctx)
if not ctx.target or ctx.target.type ~= 'node' then return false end
local tgt = minetest.get_node(ctx.target.under)
if tgt.name ~= 'sorcery:enchanter' then return false end
local inv = minetest.get_meta(ctx.target.under):get_inventory()
for _,name in pairs{'foci','item'} do
for i=1,inv:get_size(name) do
inv:set_stack(name,i,ItemStack(nil))
end
end
enchantment_sparkle(ctx,sorcery.lib.color(255,12,0))
enchantment_sparkle(ctx,sorcery.lib.color(85,18,35))
enchantment_sparkle(ctx,sorcery.lib.color(0,0,0))
end
................................................................................
};
transmute = {
name = 'transmutation';
uses = 7;
color = {255,90,18};
leytype = 'imperic';
affinity = {'aspen','shimmering','dark','blazing'};
desc = 'Transmute three ingots into one of a different metal, determined by chance and influenced by configuration of the wand';
};
disjoin = {
name = 'disjunction';
uses = 32;
color = {17,6,212};
leytype = 'occlutic';
affinity = {'jungle','silent'};
desc = 'With an enchanter, disjoin the anchor holding a spell into an object so a new spell can instead be bound in';
};
divine = {
name = 'divining';
desc = 'Steal away the secrets of the cosmos';
uses = 16;
color= {97,97,255};
sound = 'xdecor:enchanting';
................................................................................
cast = function(ctx)
local inks = {'black','red','white','violet','blue','green'}
local getcolor = function(stack)
if stack:is_empty() then return nil end
if minetest.get_item_group(stack:get_name(), 'dye') == 0 then return nil end
for _,ink in pairs(inks) do
if minetest.get_item_group(stack:get_name(), 'color_' ..ink) ~= 0
then print('found',ink,'ink') return ink end
end
end
if not ctx.target or ctx.target.type ~= 'node' then return false end
local tgt = minetest.get_node(ctx.target.under)
if tgt.name == 'sorcery:enchanter' then
local meta = minetest.get_meta(ctx.target.under)
local inv = meta:get_inventory()
................................................................................
and not inv:is_empty('foci') then
local ink1 = getcolor(inv:get_stack('foci',2))
local ink2 = getcolor(inv:get_stack('foci',3))
local restrict, kind, mod = {} do
local ms = inv:get_stack('foci',1)
if not ms:is_empty() then mod = ms:get_name() end
end
print(ink1,ink2,mod)
if ink1 == 'black' and ink2 == 'black' then kind = 'craft'
if mod then
if mod == sorcery.data.metals.cobalt.parts.powder then
restrict.group = 'sorcery_magitech'
elseif mod == sorcery.data.metals.vidrium.parts.powder then
restrict.group = 'sorcery_ley_device'
elseif mod == sorcery.data.metals.aluminum.parts.powder then
................................................................................
if mod == sorcery.data.metals.cobalt.parts.powder then
restrict.aff = 'praxic'
elseif mod == sorcery.data.metals.tungsten.parts.powder then
restrict.aff = 'counterpraxic'
elseif mod == sorcery.data.metals.aluminum.parts.powder then
restrict.aff = 'syncretic'
elseif mod == sorcery.data.metals.lithium.parts.powder then
-- restrict.aff = 'mandatic' -- no enchants yet, will cause infinite loop
elseif mod == sorcery.data.metals.iridium.parts.powder then
restrict.aff = 'entropic'
elseif mod == sorcery.data.metals.gold.parts.powder then
restrict.aff = 'cognic'
elseif mod == sorcery.data.metals.silver.parts.powder then
-- restrict.aff = 'occlutic'
elseif mod == sorcery.data.metals.electrum.parts.powder then
-- restrict.aff = 'imperic'
else return false end
end
elseif ink1 == 'red' and ink2 == 'yellow' then kind = 'cook';
-- elseif ink1 == 'red' and ink2 == 'orange' then kind = 'smelt';
end
print('result',kind,dump(restrict))
if kind then
print('found kind')
local rec = ItemStack('sorcery:recipe')
local m = rec:get_meta()
if ctx.base.gem == 'diamond' then
-- make recipe for thing in slot 1
else
sorcery.cookbook.setrecipe(rec,kind,nil,restrict)
end
................................................................................
color = {244,255,157};
affinity = {'acacia','shimmering','blazing'};
leytype = 'cognic';
cast = function(ctx)
local center = ctx.heading.pos
local maxpower = 20
local power = (ctx.base.gem == 'sapphire' and maxpower) or maxpower/2
local range = (ctx.base.gem == 'emerald' and 10) or 5
local duration = (ctx.base.gem == 'amethyst' and 60) or 30
if ctx.base.gem == 'diamond' then
power = power * (math.random()*2)
range = range * (math.random()*2)
duration = duration * (math.random()*2)
end
local lum = math.ceil((power/maxpower) * minetest.LIGHT_MAX)
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
>
>
|
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
>
|
<
|
|
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
|
<
<
|
|
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
...
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
...
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
...
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
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
...
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
...
579
580
581
582
583
584
585
586
587
588
589
590
591
592
...
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
...
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
|
local target_node = function(ctx,tgt)
if not ctx.target or ctx.target.type ~= 'node' then return false end
local node = minetest.get_node(ctx.target.under)
if node.name ~= tgt then return false end
return node
end;
local get_enchanter = function(ctx)
local ench = target_node(ctx, 'sorcery:enchanter')
if not ench then return false end
return minetest.get_meta(ctx.target.under):get_inventory()
end
local cast_sparkle = function(ctx,color,strength,duration)
sorcery.vfx.cast_sparkle(ctx.caster,color,strength,duration)
end
local enchantment_sparkle = function(ctx,color)
sorcery.vfx.enchantment_sparkle(ctx.target,color)
end
local anchorwand = function(aff,uses,recipe)
local affcolor = sorcery.lib.color(sorcery.data.affinities[aff].color)
return {
name = aff .. ' anchor';
desc = 'With an enchanter, anchor ' .. aff .. ' spells into an object to enable it to produce preternatural effects';
uses = uses;
affinity = recipe;
color = affcolor;
sound = 'xdecor_enchanting'; -- FIXME make own
cast = function(ctx)
local node = target_node(ctx, 'sorcery:enchanter')
if not node then return false end
local inv = minetest.get_meta(ctx.target.under):get_inventory()
if inv:is_empty('item') then return false end
local subj = inv:get_stack('item',1)
-- now we have everything we need. this part is complex.
-- first, we need to check the item to see if it is in a
................................................................................
-- note: this was written before terminology was standardized,
-- and "leytype" corresponds to what is otherwise known as an
-- "affinity"; "affinity" after this comment is widely misused
return {
flame = {
name = 'flamebolt';
color = {255,89,16};
uses = 32;
affinity = {'acacia','blazing'};
leytype = 'praxic';
desc = 'Conjure a gout of fire to scorch your foes with a flick of this wand';
cast = function(ctx)
local speed = 30 -- TODO maybe amethyst tip increases speed?
local radius
if ctx.base.gem == 'sapphire'
then radius = math.random(2,3)
else radius = math.random(1,2)
end
local heading = ctx.heading
heading.pos.y = heading.pos.y + heading.eyeheight*0.9
local bolt = minetest.add_entity(heading.pos,'sorcery:spell_projectile_flamebolt')
bolt:set_rotation(heading.yaw)
local vel = {
x = heading.yaw.x * speed;
y = heading.yaw.y * speed;
z = heading.yaw.z * speed;
};
bolt:get_luaentity()._blastradius = radius
bolt:set_velocity(vel)
end;
};
seal = {
name = 'sealing';
color = {255,238,16};
uses = 32;
................................................................................
leytype = 'imperic';
affinity = {'pine','dark'};
cast = function(ctx)
if ctx.target == nil or ctx.target.type ~= 'node' then return false end
local meta = minetest.get_meta(ctx.target.under)
-- first we need to check if the wand has an identifying 'key' yet,
-- and set one if not.
local modes = {
sapphire = 'lockdown';
diamond = 'steal';
}
local wandmode = modes[ctx.base.gem] or 'seal'
local keycode
if ctx.meta:contains('sorcery_wand_key') then
keycode = ctx.meta:get_string('sorcery_wand_key')
else
keycode = sorcery.lib.str.rand(32)
ctx.meta:set_string('sorcery_wand_key', keycode)
-- ctx.meta:mark_as_private('sorcery_wand_key')
end
if meta:contains('owner') then
-- owner is already set -- can we break the enchantment?
if wandmode == 'steal' then
if meta:get_string('owner') ~= ctx.caster:get_player_name() then
meta:set_string('owner',ctx.caster:get_player_name())
enchantment_sparkle(ctx,sorcery.lib.color(101,255,238))
end
return
end
if meta:get_string('sorcery_wand_key') == keycode then
meta:set_string('owner','')
meta:set_string('sorcery_wand_key','')
meta:set_string('sorcery_seal_mode','')
enchantment_sparkle(ctx,sorcery.lib.color(101,255,142))
else return false end
else
meta:set_string('sorcery_wand_key',keycode)
meta:mark_as_private('sorcery_wand_key')
meta:set_string('owner',ctx.caster:get_player_name())
if wandmode == 'lockdown' then
meta:set_string('sorcery_seal_mode','wand')
end
enchantment_sparkle(ctx,sorcery.lib.color(255,201,27))
end
end;
};
leyspark = {
................................................................................
};
meld = {
name = 'melding';
uses = 48;
leytype = 'syncretic';
color = {172,65,255};
affinity = {'apple','verdant'};
desc = 'Meld the properties of three balanced items on an enchanter to create a new one with special properties, but destroying the old ones and losing two thirds of the mass in the process. The precise outcome is not always predictable, and may vary with the moons and the stars.';
cast = function(ctx)
local e = get_enchanter(ctx)
if not e then return false end
for _,m in pairs(sorcery.data.resonance.meld) do
if m.restrict and not m.restrict(ctx)
then goto next_meld end
local g = {}
for i,set in ipairs(m.set) do
if type(set) == 'table' then
g[i] = set
else g[i] = { take = set; } end
local found = false
for j=1,e:get_size('foci') do
local match,res = sorcery.lib.item.groupmatch(g[i].take, e:get_stack('foci',j),false)
if match then
found = true
g[i].slot = j
g[i].leftover = res
break
end
end
if not found then goto next_meld end
end
-- we've made it past the tests; this meld
-- matches the spec
for _,t in pairs(g) do
if t.leftover and t.leftover:get_count() > 0 then
e:set_stack('foci',t.slot,t.leftover)
if t.replacement then
minetest.add_item(ctx.target.above, ItemStack(t.replacement))
end
else
e:set_stack('foci',t.slot,ItemStack(t.replacement))
end
end
local res
if type(m.results) == 'function' then
res = m.results(ctx)
elseif type(m.results) == 'table' and m.results[1] then -- haaaack
res = select(2,sorcery.lib.tbl.pick(m.results))
else
res = m.results
end
e:set_stack('item',1,ItemStack(res))
enchantment_sparkle(ctx,sorcery.lib.color(228,4,201))
::next_meld::end
end;
};
divide = {
name = 'division';
uses = 19;
leytype = 'syncretic';
color = {255,65,121};
affinity = {'apple','shimmering'};
desc = 'Shatter an item on an enchanter, dividing its essence equally into three parts and precipitating it into new items embodying various properties of the destroyed item. The outcome is not always predictable, and may vary with the moons and the stars.';
cast = function(ctx)
local e = get_enchanter(ctx)
if not e then return false end
local orig = e:get_stack('item',1)
local div = sorcery.data.resonance.divide[orig:get_name()]
if not div then return false end
local bitch = function(err)
sorcery.log('data/spells(divide)', err .. ' for ' .. orig:get_name())
return false
end
if not (div.mode and div.give) then
return bitch('improperly specified division')
end
if div.restrict and not div.restrict(ctx) then
return false
end
local dst
if div.mode == 'any' then
local lst = sorcery.lib.tbl.cshuf(div.give)
dst = function(i) return lst[i] end
elseif div.mode == 'random' then
dst = function() return sorcery.lib.tbl.pick(div.give) end
elseif div.mode == 'set' then
dst = function(i) return div.give[i] end
elseif div.mode == 'all' then
dst = function() return div.give end
elseif div.mode == 'fn' then
dst = function(i) return div.give(i,ctx) end
else return bitch('invalid division mode') end
for i=1,e:get_size('foci') do
e:set_stack('foci',i,ItemStack(dst(i)))
end
e:set_stack('item',1,ItemStack(div.replacement))
for _,color in pairs{{245,63,63},{63,245,178}} do
enchantment_sparkle(ctx, sorcery.lib.color(color))
end
end;
};
obliterate = {
name = 'obliteration';
uses = 129;
color = {175,6,212};
affinity = {'aspen','dark'};
leytype = 'occlutic';
desc = 'Incinerate all items on an enchanter, rendering them down to ash or obliterating them entirely.';
cast = function(ctx)
local tgt = target_node(ctx, 'sorcery:enchanter')
if not tgt then return false end
local inv = minetest.get_meta(ctx.target.under):get_inventory()
for _,name in pairs{'foci','item'} do
for i=1,inv:get_size(name) do
local stack = 'sorcery:ash'
if ctx.base.gem == 'sapphire' then
stack = nil
end
inv:set_stack(name,i,ItemStack(stack))
end
end
enchantment_sparkle(ctx,sorcery.lib.color(255,12,0))
enchantment_sparkle(ctx,sorcery.lib.color(85,18,35))
enchantment_sparkle(ctx,sorcery.lib.color(0,0,0))
end
................................................................................
};
transmute = {
name = 'transmutation';
uses = 7;
color = {255,90,18};
leytype = 'imperic';
affinity = {'aspen','shimmering','dark','blazing'};
desc = 'Transmute three ingots into one of a different metal, determined by chance, and influenced by configuration of the wand as well as the stars and the phase of the moon';
-- diamond = quantity varies between 1-3
};
disjoin = {
name = 'disjunction';
uses = 32;
color = {17,6,212};
leytype = 'occlutic';
affinity = {'jungle','silent'};
desc = 'With an enchanter, disjoin the anchor holding a spell into an object so a new spell can instead be bound in';
cast = function(ctx)
local ench = target_node(ctx, 'sorcery:enchanter')
if not ench then return false end
local ei = minetest.get_meta(ctx.target.under):get_inventory()
local item = ei:get_stack('item',1)
local e = sorcery.enchant.get(item)
if next(e.spells) == nil then return false end
if #e.spells == 1 then e = nil else
if ctx.base.gem == 'sapphire'
then e.spells = {} e.energy = 0
else table.remove(e.spells, math.random(#e.spells))
end
end
sorcery.enchant.set(item,e)
ei:set_stack('item',1,item)
enchantment_sparkle(ctx,sorcery.lib.color(255,154,44))
enchantment_sparkle(ctx,sorcery.lib.color(226,44,255))
end;
};
divine = {
name = 'divining';
desc = 'Steal away the secrets of the cosmos';
uses = 16;
color= {97,97,255};
sound = 'xdecor:enchanting';
................................................................................
cast = function(ctx)
local inks = {'black','red','white','violet','blue','green'}
local getcolor = function(stack)
if stack:is_empty() then return nil end
if minetest.get_item_group(stack:get_name(), 'dye') == 0 then return nil end
for _,ink in pairs(inks) do
if minetest.get_item_group(stack:get_name(), 'color_' ..ink) ~= 0
then return ink end
end
end
if not ctx.target or ctx.target.type ~= 'node' then return false end
local tgt = minetest.get_node(ctx.target.under)
if tgt.name == 'sorcery:enchanter' then
local meta = minetest.get_meta(ctx.target.under)
local inv = meta:get_inventory()
................................................................................
and not inv:is_empty('foci') then
local ink1 = getcolor(inv:get_stack('foci',2))
local ink2 = getcolor(inv:get_stack('foci',3))
local restrict, kind, mod = {} do
local ms = inv:get_stack('foci',1)
if not ms:is_empty() then mod = ms:get_name() end
end
if ink1 == 'black' and ink2 == 'black' then kind = 'craft'
if mod then
if mod == sorcery.data.metals.cobalt.parts.powder then
restrict.group = 'sorcery_magitech'
elseif mod == sorcery.data.metals.vidrium.parts.powder then
restrict.group = 'sorcery_ley_device'
elseif mod == sorcery.data.metals.aluminum.parts.powder then
................................................................................
if mod == sorcery.data.metals.cobalt.parts.powder then
restrict.aff = 'praxic'
elseif mod == sorcery.data.metals.tungsten.parts.powder then
restrict.aff = 'counterpraxic'
elseif mod == sorcery.data.metals.aluminum.parts.powder then
restrict.aff = 'syncretic'
elseif mod == sorcery.data.metals.lithium.parts.powder then
-- restrict.aff = 'mandatic' -- no enchants yet, will cause infinite loop 🙃
elseif mod == sorcery.data.metals.iridium.parts.powder then
restrict.aff = 'entropic'
elseif mod == sorcery.data.metals.gold.parts.powder then
restrict.aff = 'cognic'
elseif mod == sorcery.data.metals.silver.parts.powder then
-- restrict.aff = 'occlutic'
elseif mod == sorcery.data.metals.electrum.parts.powder then
-- restrict.aff = 'imperic'
else return false end
end
elseif ink1 == 'red' and ink2 == 'yellow' then kind = 'cook';
-- elseif ink1 == 'red' and ink2 == 'orange' then kind = 'smelt';
end
if kind then
local rec = ItemStack('sorcery:recipe')
local m = rec:get_meta()
if ctx.base.gem == 'diamond' then
-- make recipe for thing in slot 1
else
sorcery.cookbook.setrecipe(rec,kind,nil,restrict)
end
................................................................................
color = {244,255,157};
affinity = {'acacia','shimmering','blazing'};
leytype = 'cognic';
cast = function(ctx)
local center = ctx.heading.pos
local maxpower = 20
local power = (ctx.base.gem == 'sapphire' and maxpower) or maxpower/2
local range = (ctx.base.gem == 'emerald' and 6) or 3
local duration = (ctx.base.gem == 'amethyst' and 60) or 30
if ctx.base.gem == 'diamond' then
power = power * (math.random()*2)
range = range * (math.random()*2)
duration = duration * (math.random()*2)
end
local lum = math.ceil((power/maxpower) * minetest.LIGHT_MAX)
|