Differences From
Artifact [720c3d8102]:
32 32 name = 'Arrival';
33 33 desc = "Give this amulet to another and they will be able to arrive at your side in a flash from anywhere in the world, carrying others with them in the spell's grip";
34 34 };
35 35 };
36 36 };
37 37 sapphire = {
38 38 name = 'Return';
39 - desc = 'Use this amulet once to bind it to a particular point in the world, then discharge its spell to return instantly to that point.';
39 + desc = 'Use this amulet once to bind it to a particular place, then discharge its spell to translocate yourself back to that point from anywhere in the world.';
40 40 remove = function(ctx)
41 41 ctx.meta:set_string('rune_return_dest','')
42 42 end;
43 43 cast = function(ctx)
44 44 if not ctx.meta:contains('rune_return_dest') then
45 45 local pos = ctx.caster:get_pos()
46 46 ctx.meta:set_string('rune_return_dest',minetest.pos_to_string(pos))
................................................................................
47 47 return true -- play effects but do not break spell
48 48 else
49 49 local pos = minetest.string_to_pos(ctx.meta:get_string('rune_return_dest'))
50 50 ctx.meta:set_string('rune_return_dest','')
51 51 local subjects = { ctx.caster }
52 52 local center = ctx.caster:get_pos()
53 53 ctx.sparkle = false
54 + local delay = math.max(3,10 - ctx.stats.power) + 3*(math.random()*2-1)
55 + print('teledelay',delay,ctx.stats.power)
54 56 for _,s in pairs(subjects) do
55 57 local offset = vector.subtract(s:get_pos(), center)
56 58 local pt = sorcery.lib.node.get_arrival_point(vector.add(pos,offset))
57 59 if pt then
58 - sorcery.vfx.body_sparkle(s,sorcery.lib.color(20,120,255),2)
59 - sorcery.vfx.body_sparkle(nil,sorcery.lib.color(20,255,120),2,pt)
60 - s:set_pos(pt)
60 + minetest.sound_play('sorcery_stutter', {
61 + object = s, gain = 0.8;
62 + },true)
63 + local windup = minetest.sound_play('sorcery_windup',{
64 + object = s, gain = 0.4;
65 + })
66 + local mydelay = delay + math.random(-10,10)*.1;
67 + local spark = sorcery.lib.image('sorcery_spark.png')
68 + local sh = s:get_properties().eye_height
69 + local sparkle = function(amt,time,minsize,maxsize)
70 + minetest.add_particlespawner {
71 + amount = amt, time = time, attached = s;
72 + minpos = { x = -0.3, y = -0.5, z = -0.3 };
73 + maxpos = { x = 0.3, y = sh*1.1, z = 0.3 };
74 + minvel = { x = -0.4, y = -0.2, z = -0.4 };
75 + maxvel = { x = 0.4, y = 0.2, z = 0.4 };
76 + minacc = { x = -0.5, y = -0.4, z = -0.5 };
77 + maxacc = { x = 0.5, y = 0.4, z = 0.5 };
78 + minexptime = 1.0, maxexptime = 2.0;
79 + minsize = minsize, maxsize = maxsize, glow = 14;
80 + texture = spark:blit(spark:multiply(sorcery.lib.color(29,205,247))):render();
81 + animation = {
82 + type = 'vertical_frames';
83 + aspect_w = 16, aspect_h = 16;
84 + };
85 + }
86 + end
87 + sparkle(mydelay*100,mydelay,0.3,1.3)
88 + minetest.after(mydelay*0.4, function()
89 + local timeleft = mydelay - (mydelay*0.4)
90 + sparkle(timeleft*150, timeleft, 0.6,1.8)
91 + end)
92 + minetest.after(mydelay*0.7, function()
93 + local timeleft = mydelay - (mydelay*0.7)
94 + sparkle(timeleft*80, timeleft, 2,4)
95 + end)
96 + sorcery.lib.node.preload(pt,s)
97 + minetest.after(mydelay, function()
98 + minetest.sound_stop(windup)
99 + minetest.sound_play('sorcery_zap', { pos = pt, gain = 0.4 },true)
100 + minetest.sound_play('sorcery_zap', { pos = s:get_pos(), gain = 0.4 },true)
101 + sorcery.vfx.body_sparkle(nil,sorcery.lib.color(20,255,120),2,s:get_pos())
102 + s:set_pos(pt)
103 + sorcery.vfx.body_sparkle(s,sorcery.lib.color(20,120,255),2)
104 + end)
61 105 end
62 106 end
63 107 end
64 108 end;
65 109 frame = {
66 110 iridium = {
67 111 name = 'Mass Return';
68 - desc = 'Use this amulet once to bind it to a particular point in the world, then carry yourself and everyone around you back to that point in a flash simply by using it again';
112 + desc = 'Use this amulet once to bind it to a particular place, then carry yourself and everyone around you back to that point in a flash simply by using it again';
69 113 };
70 114 };
71 115 };
72 116 emerald = {
73 117 name = 'Banishment';
74 118 desc = 'Use this amulet once to bind it to a particular point in the world, then wield it against a foe to whisk them away immediately to your chosen prison';
75 119 frame = {
76 120 iridium = {
77 121 name = 'Mass Banishment';
78 122 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';
79 123 };
80 124 };
81 125 };
82 - ruby = {
126 + ruby = minetest.get_modpath('beds') and {
83 127 name = 'Escape';
84 128 desc = 'Immediately transport yourself out of a dangerous situation back to the last place you slept';
129 + cast = function(ctx)
130 + -- if not beds.spawns then beds.read_spawns() end
131 + local subjects = {ctx.caster}
132 + for _,s in pairs(subjects) do
133 + local spp = beds.spawn[ctx.caster:get_player_name()]
134 + if spp then
135 + local oldpos = s:get_pos()
136 + minetest.sound_play('sorcery_splunch', {pos=oldpos}, true)
137 + sorcery.vfx.body_sparkle(nil,sorcery.lib.color(244,38,131),2,oldpos)
138 + s:set_pos(spp)
139 + minetest.sound_play('sorcery_splunch', {pos=spp}, true)
140 + sorcery.vfx.body_sparkle(nil,sorcery.lib.color(244,38,89),2,spp)
141 + end
142 + -- TODO decide what happens to the people who don't have
143 + -- respawn points already set
144 + end
145 + end;
85 146 frame = {
86 147 cobalt = {
87 148 name = 'Vengeful Exit';
88 149 desc = 'Translocate away to the safety of your boudoir with a fearsome blast of dangerous radiance that will send bodies flying and deal heavy damage to those nearby';
89 150 };
90 151 iridium = {
91 152 name = 'Mass Escape';
................................................................................
121 182 minpower = 1;
122 183 rarity = 7;
123 184 amulets = {
124 185 amethyst = {
125 186 name = 'Hurling';
126 187 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';
127 188 };
128 - diamond = {
189 + sapphire = {
190 + name = 'Flinging';
191 + desc = 'Toss an enemy violently into the air, and allow the inevitable impact to do your dirty work for you';
192 + };
193 + emerald = {
129 194 name = 'Shockwave';
195 + desc = 'Let loose a stream of concussive force that slams into everything in your path and sends them hurtling away from you';
196 + };
197 + luxite = {
198 + name = 'Repulsive Aura';
199 + desc = 'For a period of time, anyone who approaches you will be violently thrust aside';
200 + };
201 + diamond = {
202 + name = 'Blastwave';
130 203 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';
131 204 };
132 205 };
133 206 };
134 207 obliterate = {
135 208 name = 'Obliterate';
136 209 tone = {255,0,10};
................................................................................
141 214 name = 'Sapping';
142 215 desc = 'Punch a hole in enemy fortifications big enough to slip through but small enough to avoid immediate attention';
143 216 };
144 217 ruby = {
145 218 name = 'Shattering';
146 219 desc = 'Tear a violent wound in the earth with the destructive force of this amulet';
147 220 };
221 + emerald = {
222 + name = 'Detonate';
223 + desc = 'Wielding this amulet, you can loose an extraordinarily powerful bolt of flame from your fingertips that will explode violently on impact, wreaking total havoc wherever it lands';
224 + cast = function(ctx)
225 + local speed = 40
226 + local radius = math.random(math.floor(ctx.stats.power*0.5),math.ceil(ctx.stats.power))
227 + local heading = ctx.heading
228 + heading.pos.y = heading.pos.y + heading.eyeheight*0.9
229 + local vel = vector.multiply(heading.yaw,speed)
230 + local bolt = minetest.add_entity(vector.add(heading.pos,vector.multiply(heading.yaw,2.5)),'sorcery:spell_projectile_flamebolt')
231 + bolt:set_rotation(heading.yaw)
232 + bolt:get_luaentity()._blastradius = radius
233 + bolt:set_velocity(vel)
234 + end;
235 + };
236 + luxite = {
237 + name = 'Lethal Aura';
238 + desc = 'For a time, anyone who approaches you, whether friend or foe, will suffer immediate retaliation as they are quickly sapped of their life force';
239 + };
148 240 diamond = {
149 241 name = 'Killing';
242 + mingrade = 4;
150 243 desc = 'Wield this amulet against a foe to instantly snuff the life out of their mortal form, regardless of their physical protections.';
151 244 cast = function(ctx)
152 245 if not (ctx.target and ctx.target.type == 'object') then return false end
153 246 local tgt = ctx.target.ref
154 247 if not minetest.is_player(obj) then return false end
155 248 local tgth = tgt:get_properties().eye_height
156 249 sorcery.vfx.bloodburst(vector.add(tgt:get_pos(),{x=0,y=tgth/2,z=0}),20)
................................................................................
206 299 };
207 300 diamond = {
208 301 name = 'Radiance';
209 302 desc = 'Set the air around you alight with a mystic luminance, letting you see clearly a great distance in every direction for several minutes';
210 303 frame = {
211 304 iridium = {
212 305 name = 'Sunshine';
306 + mingrade = 5;
213 307 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';
214 308 };
215 309 };
216 310 };
217 311 };
218 312 };
219 313 dominate = {
................................................................................
222 316 minpower = 4;
223 317 rarity = 40;
224 318 amulets = {
225 319 amethyst = {
226 320 name = 'Suffocation';
227 321 desc = 'Wrap this spell tightly around your victim\'s throat, cutting off their oxygen until you release them.';
228 322 };
323 + emerald = {
324 + name = 'Caging';
325 + desc = 'Trap your victim in an impenetrable field of force, leaving them with no way out but translocation or waiting for the field to release them';
326 + };
229 327 ruby = {
230 328 name = 'Exsanguination';
231 - desc = 'Rip the life force out of another, leaving them on the brink of death, and use it to mend your own wounds and invigorate your own being';
329 + desc = 'Rip the life force out of another, leaving them on the brink of death, and use it to mend your own wounds and invigorate your being';
232 330 cast = function(ctx)
233 331 if not (ctx.target and ctx.target.type == 'object') then return false end
234 332 local tgt = ctx.target.ref
235 333 local takefac = math.min(99,50 + (ctx.stats.power * 5)) / 100
236 334 local dmg = tgt:get_hp() * takefac
237 335 print("!!! dmg calc",takefac,dmg,tgt:get_hp())
238 336