Differences From
Artifact [3a290dc995]:
- File
data/runes.lua
— part of check-in
[15f176a7fe]
at
2020-10-31 19:49:49
on branch trunk
— add background noise for condensers (temporary hack, need to write a proper environment sound framework as the fucking env_sounds module is completely impossible to extend), fix a couple of really stupid bugs, make higher-quality phials increase the chance of getting good runes so it's not a complete waste to burn iridium or levitanium powder on making them, add targeted disjunction and some other amulet spells
(user:
lexi,
size: 42828)
[annotate]
[blame]
[check-ins using]
97 97 sounds = {
98 98 [0] = { sound = 'sorcery_stutter', pos = 'subjects' };
99 99 };
100 100 }
101 101 end
102 102 end
103 103 end
104 +
105 +local purge = function(target)
106 + local h = target:get_properties().eye_height * 1.1
107 + minetest.add_particlespawner {
108 + time = 0.2, amount = math.random(200,250), attached = target;
109 + glow = 14, texture = sorcery.vfx.glowspark(sorcery.lib.color(156,255,10)):render();
110 + minpos = {x = -0.3, y = -0.5, z = -0.3};
111 + maxpos = {x = 0.3, y = h, z = 0.3};
112 + minvel = {x = -1.8, y = -1.8, z = -1.8};
113 + maxvel = {x = 1.8, y = 1.8, z = 1.8};
114 + minsize = 0.2, maxsize = 5;
115 + animation = {
116 + type = 'vertical_frames', length = 4.1;
117 + aspect_w = 16, aspect_h = 16;
118 + };
119 + minexptime = 2, maxexptime = 4;
120 + }
121 + minetest.sound_play('sorcery_disjoin',{object=target},true)
122 + sorcery.spell.disjoin{target=target}
123 +end
124 +
104 125 return {
105 126 translocate = {
106 127 name = 'Translocate';
107 128 tone = {0,235,233};
108 129 minpower = 3;
109 130 rarity = 7;
110 131 amulets = {
................................................................................
133 154 else
134 155 ctx.sparkle = false
135 156 end
136 157 end;
137 158 frame = {
138 159 tungsten = {
139 160 name = 'Quick Joining';
140 - desc = 'Give this amulet to another and they can arrive safely at your side almost instantaneously from anywhere in the world — though returning whence they came may be a more difficult matter';
161 + desc = 'Give this amulet to another and they can arrive safely at your side almost instantaneously from anywhere at all in the world — though returning whence they came may be a more difficult matter';
141 162 };
142 163 gold = {
143 164 name = 'Exchange';
144 165 desc = 'Give this amulet to another and they will be able to trade places with you no matter where in the world each of you might be.';
145 166 };
146 167 cobalt = {
147 168 name = 'Sending';
................................................................................
161 182 end;
162 183 cast = function(ctx)
163 184 if not ctx.meta:contains('rune_return_dest') then
164 185 local pos = ctx.caster:get_pos()
165 186 ctx.meta:set_string('rune_return_dest',minetest.pos_to_string(pos))
166 187 return true -- play effects but do not break spell
167 188 else
189 + if ctx.caster:get_attach() ~= nil then return false end
168 190 local pos = minetest.string_to_pos(ctx.meta:get_string('rune_return_dest'))
169 191 ctx.meta:set_string('rune_return_dest','')
170 192 local subjects = { ctx.caster }
171 193 local center = ctx.caster:get_pos()
172 194 ctx.sparkle = false
173 195 local delay = math.max(3,10 - ctx.stats.power) + 3*(math.random()*2-1)
174 196 teleport(ctx,{{ref=ctx.caster}},delay,pos)
................................................................................
194 216 desc = 'Use this amulet once to bind it to a particular point in the world, then use it again to seize up everyone surrounding you in the grip of a fearsome magic that will deport them all in the blink of an eye to whatever destination you have chosen';
195 217 };
196 218 };
197 219 };
198 220 ruby = minetest.get_modpath('beds') and {
199 221 name = 'Escape';
200 222 desc = 'Immediately transport yourself out of a dangerous situation back to the last place you slept, before anyone has time to net you in a disjunction';
223 + mingrade = 4;
201 224 cast = function(ctx)
202 225 -- if not beds.spawns then beds.read_spawns() end
203 226 local subjects = {ctx.caster}
204 227 for _,s in pairs(subjects) do
205 228 local spp = beds.spawn[ctx.caster:get_player_name()]
206 229 if spp then
207 230 local oldpos = s:get_pos()
................................................................................
389 412 sapphire = {
390 413 name = 'Unsealing';
391 414 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';
392 415 };
393 416 amethyst = {
394 417 name = 'Purging';
395 418 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';
396 - cast = function(ctx)
397 - local h = ctx.heading.eyeheight * 1.1
398 - minetest.add_particlespawner {
399 - time = 0.2, amount = math.random(200,250), attached = ctx.caster;
400 - glow = 14, texture = sorcery.vfx.glowspark(sorcery.lib.color(156,255,10)):render();
401 - minpos = {x = -0.3, y = -0.5, z = -0.3};
402 - maxpos = {x = 0.3, y = h, z = 0.3};
403 - minvel = {x = -1.8, y = -1.8, z = -1.8};
404 - maxvel = {x = 1.8, y = 1.8, z = 1.8};
405 - minsize = 0.2, maxsize = 5;
406 - animation = {
407 - type = 'vertical_frames', length = 4.1;
408 - aspect_w = 16, aspect_h = 16;
409 - };
410 - minexptime = 2, maxexptime = 4;
411 - }
412 - minetest.sound_play('sorcery_disjoin',{object=ctx.caster},true)
413 - sorcery.spell.disjoin{target=ctx.caster}
414 - end;
419 + cast = function(ctx) purge(ctx.caster) end;
415 420 };
416 421 emerald = {
417 422 name = 'Disjunction Field';
418 423 desc = 'Render an area totally opaque to spellwork for a period of time, disrupting any existing spells and preventing further spellcasting therein';
419 424 };
420 425 ruby = {
421 426 name = 'Disjunction';
422 427 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';
428 + mingrade = 3;
429 + cast = function(ctx)
430 + if ctx.target.type == 'object'
431 + then purge(ctx.target.ref)
432 + else return false
433 + end
434 + end;
423 435 frame = {
424 436 iridium = {
425 437 name = 'Nullification';
438 + mingrade = 5;
426 439 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';
427 440 };
428 441 };
429 442 };
430 443 luxite = {
431 444 name = 'Disjunctive Aura';
432 445 desc = 'For a time, all magic undertaken in your vicinity will fail totally — including your own';
................................................................................
851 864 mingrade = 4;
852 865 name = 'Duplication';
853 866 desc = 'Bring an exact twin of any object or item into existence, no matter how common or rare it might be';
854 867 cast = function(ctx)
855 868 local color = sorcery.lib.color(255,61,205)
856 869 local dup, sndpos, anchor, sbj, ty
857 870 if ctx.target.type == 'object' and ctx.target.ref:get_luaentity().name == '__builtin:item' then
858 - sorcery.vfx.imbue(color, ctx.target.ref)
871 + -- sorcery.vfx.imbue(color, ctx.target.ref) -- causes graphics card problems???
859 872 sndpos = 'subjects'
860 873 sbj = {{player = ctx.target.ref}}
861 874 local item = ItemStack(ctx.target.ref:get_luaentity().itemstring)
862 875 local r = function() return math.random() * 2 - 1 end
863 876 local putpos = vector.offset(ctx.target.ref:get_pos(), r(), 1, r())
864 877 dup = function()
865 878 item:set_count(1) -- nice try bouge-san
................................................................................
881 894 vp[#vp+1] = sum
882 895 end
883 896 end
884 897 if #vp > 0 then npos=vp[math.random(#vp)] end
885 898 end
886 899 if npos then
887 900 minetest.set_node(npos, minetest.get_node(ctx.target.under))
901 + if minetest.registered_nodes[ty].on_construct then
902 + minetest.registered_nodes[ty].on_construct(npos)
903 + end
888 904 minetest.get_meta(npos):from_table(origmeta)
889 905 return npos, true
890 906 else
891 907 local nstack = ItemStack(ty)
892 908 nstack:get_meta():from_table(origmeta)
893 909 local leftover = ctx.caster:get_inventory():add_item('main',nstack)
894 910 if leftover and not leftover.is_empty() then
................................................................................
972 988 tone = {255,194,0};
973 989 minpower = 1;
974 990 rarity = 5;
975 991 amulets = {
976 992 luxite = {
977 993 name = 'Glow';
978 994 desc = 'Swathe yourself in an aura of sparkling radiance, casting light upon all the dark places where you voyage';
995 + cast = function(ctx)
996 + local fac = (ctx.stats.power * 0.1)
997 + local radius = 2 + 5*fac
998 + local period = 0.4 - 0.3*fac
999 + local glowduration = 5 + 50*fac
1000 + sorcery.spell.cast {
1001 + name = "sorcery:glow";
1002 + caster = ctx.caster;
1003 + subjects = {{player=ctx.caster}};
1004 + duration = 40 + 120*fac;
1005 + nodes = {};
1006 + disjoin = function(self)
1007 + for _,n in pairs(self.nodes) do
1008 + if sorcery.lib.str.beginswith(minetest.get_node(n).name,'sorcery:air_glimmer_') then
1009 + minetest.remove_node(n)
1010 + end
1011 + end
1012 + end;
1013 + intervals = {
1014 + {period = period, after = {whence=0,secs=0.7}, fn = function(c)
1015 + print('cycling!')
1016 + for _,sub in pairs(c.spell.subjects) do
1017 + local ox, oy, oz = math.random(-radius,radius),
1018 + math.random(-radius,radius),
1019 + math.random(-radius,radius)
1020 + local pos = vector.offset(sub.player:get_pos(), ox,oy,oz)
1021 + print('pos',minetest.pos_to_string(pos),'player',minetest.pos_to_string(sub.player:get_pos()))
1022 + if sorcery.lib.node.is_air(pos) then
1023 + print('is air!')
1024 + local power = math.random(4,minetest.LIGHT_MAX)
1025 + minetest.set_node(pos, {
1026 + name = 'sorcery:air_glimmer_' .. tostring(power);
1027 + })
1028 + c.spell.nodes[#c.spell.nodes + 1] = pos
1029 + local d = glowduration * (0.5 + math.random()*0.5)
1030 + local m = minetest.get_meta(pos)
1031 + m:set_float('duration', d)
1032 + m:set_float('timeleft', d)
1033 + m:set_int('power', power)
1034 + else
1035 + print('not air!', dump(minetest.get_node(pos)))
1036 + end
1037 + end
1038 + end};
1039 + };
1040 + }
1041 + end;
979 1042 iridium = {
980 1043 name = 'Aura';
981 1044 desc = 'Dazzling golden luminance emanates from the bodies of all those around you, and you walk in light even amid the darkest depths of the earth';
982 1045 };
983 1046 };
984 1047 diamond = {
985 1048 name = 'Radiance';
986 1049 desc = 'Set the air around you alight with a mystic luminance, letting you see clearly a great distance in every direction for several minutes';
987 1050 frame = {
988 1051 iridium = {
989 1052 name = 'Sunshine';
990 1053 mingrade = 5;
991 1054 desc = 'Unleash the power of this amulet to seize ultimate control over the forces of nature and summon the Sun high into the nighttime sky';
1055 + cast = function(ctx)
1056 + local time = minetest.get_timeofday()
1057 + if not (time < 0.3 or time > 0.7) then return false end
1058 + local diff = 0.5 - time
1059 + local frames = 40
1060 + local duration = 1.5
1061 + local delta = diff / frames
1062 + local tl = {}
1063 + for i=1,frames do
1064 + local wh = {whence=0, secs=duration*(i/frames)}
1065 + tl[wh] = function(s)
1066 + minetest.set_timeofday(time + delta*i)
1067 + end
1068 + end
1069 + sorcery.spell.cast {
1070 + name = 'sorcery:sunshine';
1071 + caster = ctx.caster;
1072 + timeline = tl;
1073 + duration = duration;
1074 + }
1075 + end;
992 1076 };
993 1077 };
994 1078 };
995 1079 };
996 1080 };
997 1081 dominate = {
998 1082 name = 'Dominate';