Differences From
Artifact [67a4930ba7]:
1 1 -- a rune is an abstract object created by a runeforge, which can be
2 2 -- applied to an amulet in order to imbue that amulet with unique
3 3 -- and fearsome powers. the specific spell depends on the stone the
4 4 -- rune is applied to, and not all runes can necessarily be applied
5 5 -- to all stones.
6 6
7 +local L = sorcery.lib
7 8 local sparkle_region = function(s)
8 9 s.spell.visual_subjects {
9 10 amount = s.amt, time = s.time, -- attached = s;
10 11 minpos = s.minpos;
11 12 maxpos = s.maxpos;
12 13 minvel = { x = -0.4, y = -0.2, z = -0.4 };
13 14 maxvel = { x = 0.4, y = 0.2, z = 0.4 };
................................................................................
122 123 sorcery.spell.disjoin{target=target}
123 124 end
124 125
125 126 return {
126 127 translocate = {
127 128 name = 'Translocate';
128 129 tone = {0,235,233};
129 - minpower = 3;
130 - rarity = 7;
130 + minpower = 2;
131 + rarity = 8;
131 132 amulets = {
132 133 amethyst = {
133 134 name = 'Joining';
134 135 desc = 'Give this amulet to another and with a snap of their fingers they can arrive safely at your side from anywhere in the world — though returning whence they came may be a more difficult matter';
135 136 apply = function(ctx)
136 137 local maker = ctx.user:get_player_name()
137 138 ctx.meta:set_string('rune_join_target',maker)
................................................................................
408 409 };
409 410 };
410 411 };
411 412 disjoin = {
412 413 name = 'Disjoin';
413 414 tone = {159,235,0};
414 415 minpower = 4;
415 - rarity = 34;
416 + rarity = 10;
416 417 amulets = {
417 418 sapphire = {
418 419 name = 'Unsealing';
419 420 desc = 'Wielding this amulet, a touch of your hand will unravel even the mightiest protective magics, leaving doors unsealed and walls free to tear down';
421 + sound = 'sorcery_disjoin';
420 422 cast = function(ctx)
421 423 if ctx.target.type ~= 'node' then return false end
422 424 local r = 2 + math.floor(ctx.stats.power / 2)
423 425 local cast = false
424 426 for x = -r,r do
425 427 for y = -r,r do
426 428 for z = -r,r do
................................................................................
442 444 end
443 445 return cast
444 446 end;
445 447 };
446 448 amethyst = {
447 449 name = 'Purging';
448 450 desc = 'Free yourself from the grip of any malicious spellwork with a snap of your fingers — interrupting all of your own active spells in the process, including impending translocations';
451 + sound = 'sorcery_disjoin';
449 452 cast = function(ctx) purge(ctx.caster) end;
450 453 };
451 454 emerald = {
452 455 name = 'Disjunction Field';
453 456 desc = 'Render an area totally opaque to spellwork for a period of time, disrupting any existing spells and preventing further spellcasting therein';
457 + sound = 'sorcery_disjoin';
454 458 };
455 459 ruby = {
456 460 name = 'Disjunction';
457 461 desc = 'Wield this amulet against a spellcaster to disrupt and abort all their spells in progress, perhaps to trap a foe intent on translocating away, or unleash its force upon the victim of a malign hex to free them from its clutches';
458 462 mingrade = 3;
463 + sound = 'sorcery_disjoin';
459 464 cast = function(ctx)
460 465 if ctx.target.type == 'object'
461 466 then purge(ctx.target.ref)
462 467 else return false
463 468 end
464 469 end;
465 470 frame = {
................................................................................
469 474 desc = 'Not only will your victim\'s spells be nullified, but all enchanted objects they carry will be stripped of their power — or possibly even destroyed outright';
470 475 };
471 476 };
472 477 };
473 478 luxite = {
474 479 name = 'Disjunctive Aura';
475 480 desc = 'For a time, all magic undertaken in your vicinity will fail totally — including your own';
481 + sound = 'sorcery_disjoin';
476 482 cast = function(ctx)
477 483 local h = ctx.heading.eyeheight*1.1
478 484 sorcery.spell.cast {
479 485 name = 'sorcery:disjunctive-aura';
480 486 caster = ctx.caster, attach = 'caster';
481 487 subjects = {{player=ctx.caster}};
482 488 disjunction = true, range = 4 + ctx.stats.power;
................................................................................
510 516 minpos = { x = 0-range, y = -0.5, z = 0-range };
511 517 maxpos = { x = range, y = h, z = range };
512 518 img = sorcery.lib.image('sorcery_flicker.png'):glow(sorcery.lib.color(120,255,30));
513 519 }
514 520 end;
515 521 };
516 522 sounds = {
517 - [0.00] = {sound='sorcery_disjoin', where='caster'};
523 + -- [0.00] = {sound='sorcery_disjoin', where='caster'};
518 524 [{whence=0,secs=0.8}] = {
519 525 sound='sorcery_disjoin_bg', where='subjects';
520 526 gain=0.5, stop = {whence=1,secs=-1.5}
521 527 };
522 528 [1.00] = {sound='sorcery_powerdown', where='caster'};
523 529 };
524 530 }
525 531 end
526 532 };
527 533 diamond = {
528 534 name = 'Mundanity';
529 535 desc = 'Strip away the effects of all active potions and spells in your immediate vicinity, leaving adversaries without their magicks to enhance and protect them, and allies free of any curses they may be hobbled by -- and, of course, vice versa';
536 + sound = 'sorcery_disjoin';
530 537 cast = function(ctx)
531 538 local where = ctx.caster:get_pos()
532 539 local what = minetest.get_objects_inside_radius(where, 3 + (2*ctx.stats.power))
533 540 local who = {}
534 541 local pfac = math.min(1, ctx.stats.power/8)
535 542 for _, w in pairs(what) do
536 543 if w:is_player() and w ~= ctx.caster then
................................................................................
623 630 };
624 631 }
625 632 end;
626 633 frame = {
627 634 iridium = {
628 635 name = 'Spellshatter';
629 636 desc = 'Blast out a tidal wave of anti-magic that will nullify active spells, but also disenchant or destroy all magical items in range of its violently mundane grip';
637 + sound = 'sorcery_disjoin';
630 638 cast = function(ctx)
631 639 local where = ctx.caster:get_pos()
632 640 local radius = 3 + (2*ctx.stats.power)
633 641 local what = minetest.get_objects_inside_radius(where, radius)
634 642 local who = {}
635 643 local pfac = math.min(1, ctx.stats.power/8)
636 644 for _, w in pairs(what) do
................................................................................
685 693 minsize = 0.7, maxsize = 2;
686 694 animation = {
687 695 type = 'vertical_frames', length = (21/6) + 0.1;
688 696 aspect_w = 16, aspect_h = 16;
689 697 }
690 698 }
691 699 end;
700 + };
701 + sounds = {
702 + [{whence=0,secs=0.8}] = {
703 + sound='sorcery_disjoin_bg', where=where;
704 + gain=0.5, stop = {whence=1,secs=-0.6}
705 + };
692 706 };
693 707 intervals = {
694 708 {period = 0.1, after = 0.15, fn = function(c)
695 709 for i = 1,80 do
696 710 local life = 0.2 + math.random() * 2
697 711 local dir = vector.new(math.random()-0.5,0,math.random()-0.5):normalize()
698 712 local pos = epicenter + (dir * (math.random()*radius))
................................................................................
709 723 }
710 724 }
711 725 end
712 726 if next(wreck) then
713 727 local k,p = sorcery.lib.tbl.pick(wreck)
714 728
715 729 minetest.add_particle {
716 - texture = sorcery.lib.image('sorcery_sparking.png'):glow(sorcery.lib.color(255,0,0)):render();
730 + texture = L.image('sorcery_sparking.png'):glow(L.color(0,255,0)):render();
717 731 pos = vector.offset(p,math.random(),math.random(),math.random());
718 732 expirationtime = 1;
719 733 size = 5 + math.random() * 4;
720 734 glow = 14;
721 735 animation = {
722 736 type = 'vertical_frames', length = 0.3;
723 737 aspect_w = 64, aspect_h = 64;
724 738 }
725 739 }
726 740 minetest.add_particle {
727 - texture = sorcery.lib.image('sorcery_crackle.png'):glow(sorcery.lib.color(255,0,0)):render();
741 + texture = L.image('sorcery_crackle.png'):glow(L.color(0,255,0)):render();
728 742 pos = vector.offset(p,math.random(),math.random(),math.random());
729 743 expirationtime = 1;
730 744 size = 4 + math.random() * 6;
731 745 glow = 14;
732 746 animation = {
733 - type = 'vertical_frames', length = 0.6;
747 + type = 'vertical_frames', length = 1.1;
734 748 aspect_w = 64, aspect_h = 64;
735 749 }
736 750 }
751 + if math.random(1,7) == 1 then
752 + minetest.sound_play('sorcery_' .. (math.random(1,2)==1 and 'rip' or 'crunch'), {
753 + pos = p;
754 + gain = math.random(5,13)*0.1;
755 + }, true)
756 + minetest.after(0.2, function() minetest.remove_node(p) end)
757 + sorcery.vfx.show {
758 + amount = 120, time = 0.3;
759 + kind = 'flicker', color = L.color(80,255,10);--(255,12,0);
760 + pos = p, radius = 0.4;
761 + velrange = 1, accrange = vector.new(0.0,0.2,0.0);
762 + minsize = 5, maxsize = 20;
763 + life = 0.6, varylife = 0.1;
764 + }
765 + sorcery.vfx.show {
766 + amount = 80, time = 0.2;
767 + minsize = 0.1, maxsize = 0.8;
768 + pos = p, radius = 0.6;
769 + node = minetest.get_node(p);
770 + vel = vector.new(0,7,0);
771 + velrange = vector.new(2, 4, 2);
772 + acc = vector.new(0,-9,0);
773 + life = 3, varylife = 0.4;
774 + }
775 + -- minetest.add_particlespawner {
776 + -- amount = 60, time = 0.2;
777 + -- texture = L.image('sorcery_flicker.png'):glow():render();
778 + -- minpos = vector.offset(p, -0.5, -0.5, -0.5);
779 + -- maxpos = vector.offset(p, 0.5, 0.5, 0.5);
780 + -- minacc = vector.new(0.0, -0.2, 0.0);
781 + -- maxacc = vector.new(0.0, 0.2, 0.0);
782 + -- minvel = vector.new(-1,-1,-1);
783 + -- maxvel = vector.new(1,1,1);
784 + -- minsize = 0.5, maxsize = 4;
785 + -- minexptime = 0.6, maxexptime = 0.7;
786 + -- animation = {
787 + -- type = 'vertical_frames';
788 + -- aspect_w = 16, aspect_h = 16;
789 + -- length = 0.8;
790 + -- }
791 + -- }
792 + table.remove(wreck,k)
793 + end
737 794 end
738 795 end};
739 796 };
740 797 }
741 798 end;
742 799 };
743 800 };
................................................................................
744 801 };
745 802 }
746 803 };
747 804 repulse = {
748 805 name = 'Repulse';
749 806 tone = {0,180,235};
750 807 minpower = 1;
751 - rarity = 5;
808 + rarity = 7;
752 809 amulets = {
753 810 amethyst = {
754 811 name = 'Hurling';
755 812 desc = 'Wielding this amulet, a mere flick of your fingers will lift any target of your choice bodily into the air and press upon them with tremendous repulsive force, throwing them like a hapless ragdoll out of your path';
756 813 cast = function(ctx)
757 814 if not (ctx.target and ctx.target.type == 'object') then return false end
758 815 local tgt = ctx.target.ref
759 816 local line = vector.subtract(ctx.caster:get_pos(), tgt:get_pos())
760 817 -- direction vector from target to caster
761 818 local dir,mag = sorcery.lib.math.vsep(line)
762 819 if mag > 6 then return false end -- no cheating!
763 820 local force = 20 + (ctx.stats.power * 2.5)
764 - minetest.sound_play('sorcery_hurl',{pos=tgt:get_pos()},true)
765 - local immortal = tgt:get_luaentity():get_armor_groups().immortal or 0
821 + minetest.sound_play('sorcery_slide',{pos=tgt:get_pos()},true)
822 + local immortal = 0
823 + -- if tgt and tgt.get_armor_groups then
824 + immortal = tgt:get_armor_groups().immortal or 0
825 + -- end
766 826 if minetest.is_player(tgt) or immortal == 0 then
767 827 tgt:punch(ctx.caster, 1, {
768 828 full_punch_interval = 1;
769 829 damage_groups = { fleshy = force / 10 };
770 830 })
771 831 end
772 832 sparktrail(nil,tgt,sorcery.lib.color(101,226,255))
................................................................................
798 858 end;
799 859 [{whence=0, secs=1}] = function(s)
800 860 s.affect {
801 861 duration = power * 0.50;
802 862 raise = 0.5;
803 863 -- fall = (power * 0.25) * 0.3;
804 864 impacts = {
805 - gravity = 0.1;
865 + gravity = 0.2;
806 866 };
807 867 }
808 868 end;
809 869 };
810 870 intervals = {
811 871 {period = 0.2, after = {whence=0, secs=2}; fn = function(c)
812 872 -- return gravity to normal once they touch down
................................................................................
864 924 for _,sub in pairs(s.subjects) do
865 925 sub.player:add_velocity{y=-power*2;x=0,z=0}
866 926 end
867 927 end or nil;
868 928 };
869 929 sounds = {
870 930 [0.3] = {
871 - sound = 'sorcery_hurl';
931 + sound = 'sorcery_slide';
872 932 where = 'subjects';
873 933 ephemeral = true;
874 934 };
875 935 [1] = (ctx.amulet.frame == 'cobalt') and {
876 936 sound = 'sorcery_hurl';
877 937 where = 'subjects';
878 938 ephemeral = true;
................................................................................
904 964 desc = 'Unleash a tidal wave of force in every direction, blasting friends and foes alike away from you with enough violence to sprain and fracture bone';
905 965 };
906 966 };
907 967 };
908 968 obliterate = {
909 969 name = 'Obliterate';
910 970 tone = {255,0,10};
911 - minpower = 5;
912 - rarity = 30;
971 + minpower = 4;
972 + rarity = 10;
913 973 amulets = {
914 974 amethyst = {
915 975 name = 'Sapping';
916 976 desc = 'Punch a hole in enemy fortifications big enough to slip through but small enough to avoid immediate attention';
917 977 };
918 978 ruby = {
919 979 name = 'Shattering';
................................................................................
963 1023 };
964 1024 };
965 1025 };
966 1026 };
967 1027 excavate = {
968 1028 name = 'Excavate';
969 1029 tone = {0,68,235};
970 - minpower = 3;
971 - rarity = 17;
1030 + minpower = 2;
1031 + rarity = 9;
972 1032 amulets = {
973 1033 luxite = {
974 1034 name = 'Stonestride';
975 1035 desc = 'Rock walls will open up before you when you brandish this amulet before them, closing up again behind you without leaving a trace of your passage';
976 1036 };
977 1037 sapphire = {
978 1038 name = 'Tunnelling';
................................................................................
1091 1151 desc = 'Cut a wide shaft up into the ceiling of a cavern';
1092 1152 };
1093 1153 };
1094 1154 };
1095 1155 genesis = {
1096 1156 name = 'Genesis';
1097 1157 tone = {235,0,175};
1098 - minpower = 5;
1099 - rarity = 23;
1158 + minpower = 3;
1159 + rarity = 12;
1100 1160 amulets = {
1101 1161 amethyst = {
1102 1162 name = 'Shelter';
1103 1163 desc = 'Pour the power of this amulet into the soil or sand and out will grow a warm and well-lit place of shelter, no matter how far you may be from civilization.';
1104 1164 cast = function(ctx)
1105 1165 local ctr = ctx.caster:get_pos()
1106 1166 local dim = { rmax = 2 + 6 * (ctx.stats.power*0.1) }
................................................................................
1710 1770 };
1711 1771 };
1712 1772 };
1713 1773 };
1714 1774 dominate = {
1715 1775 name = 'Dominate';
1716 1776 tone = {235,0,228};
1717 - minpower = 4;
1718 - rarity = 13;
1777 + minpower = 3;
1778 + rarity = 12;
1719 1779 amulets = {
1720 1780 amethyst = {
1721 1781 name = 'Suffocation';
1722 1782 desc = 'Wrap this spell tightly around your victim\'s throat, cutting off their oxygen until you release them.';
1723 1783 };
1724 1784 emerald = {
1725 1785 name = 'Caging';