@@ -549,10 +549,10 @@ [0.3] = function(s,te,tl) s.visual_caster { amount = 100 * s.duration, time = s.duration, glow = 14; texture = sorcery.lib.image('sorcery_sputter.png'):glow(sorcery.lib.color(160,255,80)):render(); - minpos = { x = -0.1, y = 3.0, z = -0.1 }; - maxpos = { x = 0.1, y = 3.2, z = 0.1 }; + minpos = { x = -0.1, y = 4.0, z = -0.1 }; + maxpos = { x = 0.1, y = 4.2, z = 0.1 }; minvel = { x = -5.0, y = -0.5, z = -5.0 }; maxvel = { x = 5.0, y = 0.5, z = 5.0 }; minacc = { x = -0.4, y = 1.0, z = -0.4 }; maxacc = { x = 0.4, y = -1.0, z = 0.4 }; @@ -603,17 +603,119 @@ name = 'Spellshatter'; 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'; cast = function(ctx) local where = ctx.caster:get_pos() - local what = minetest.get_objects_inside_radius(where, 3 + (2*ctx.stats.power)) + local radius = 3 + (2*ctx.stats.power) + local what = minetest.get_objects_inside_radius(where, radius) local who = {} local pfac = math.min(1, ctx.stats.power/8) for _, w in pairs(what) do if w:is_player() and w ~= ctx.caster then who[#who+1] = {player = w} end end - if not next(who) then return false end + --if not next(who) then return false end + local h = ctx.heading.eyeheight*1.1 + local tex = sorcery.lib.image('sorcery_sputter.png'):glow(sorcery.lib.color(160,255,80)):render(); + local epicenter = ctx.caster:get_pos() + vector.new(0, h/2, 0) + local maxima = vector.new(radius, radius, radius) + local potential_targets = minetest.find_nodes_in_area(epicenter - maxima, epicenter + maxima, {'group:sorcery_magical', 'group:sorcery_magitech'}) + local wreck = {} + for _, pos in pairs(potential_targets) do + if sorcery.lib.math.vdcomp(radius,epicenter,pos) then + print('got wreckable at',pos) + wreck[#wreck+1] = pos + end + end + sorcery.spell.cast { + name = 'sorcery:spellshatter'; + caster = ctx.caster; + anchor = epicenter; + --disjunction = true; + --range = radius; + duration = 10; + timeline = { + [0] = function(s) + s.visual_caster { + texture = tex; + amount = 100, time = 0.2; + minpos = { x = -0.1, y = -0.5, z = -0.1 }; + maxpos = { x = 0.1, y = h, z = 0.1 }; + minvel = { x = -10.0, y = -0.0, z = -10.0 }; + maxvel = { x = 10.0, y = 0.0, z = 10.0 }; + minexptime = 3, maxexptime = 3; + minsize = 5, maxsize = 8; + animation = { + type = 'vertical_frames', length = (21/6) + 0.1; + aspect_w = 16, aspect_h = 16; + } + } + s.visual_caster { + texture = tex; + amount = 5000, time = 2; + minpos = { x = -0.1, y = -0.5, z = -0.1 }; + maxpos = { x = 0.1, y = h, z = 0.1 }; + minvel = { x = -10.0, y = -0.0, z = -10.0 }; + maxvel = { x = 10.0, y = 0.0, z = 10.0 }; + minexptime = 3, maxexptime = 3; + minsize = 0.7, maxsize = 2; + animation = { + type = 'vertical_frames', length = (21/6) + 0.1; + aspect_w = 16, aspect_h = 16; + } + } + end; + }; + intervals = { + {period = 0.1, after = 0.15, fn = function(c) + print('interval running') + for i = 1,80 do + local life = 0.2 + math.random() * 2 + local dir = vector.new(math.random()-0.5,0,math.random()-0.5):normalize() + local pos = epicenter + (dir * (math.random()*radius)) + print('setting particle at',pos) + minetest.add_particle { + texture = tex; + pos = pos; + expirationtime = life; + velocity = {x = 0, y = math.random() * 0.3 + 0.1, z = 0}; + size = 0.4 + math.random() * 3; + glow = 14; + animation = { + type = 'vertical_frames', length = math.random(1,3)/10; + aspect_w = 16, aspect_h = 16; + } + } + end + if next(wreck) then + local k,p = sorcery.lib.tbl.pick(wreck) + + minetest.add_particle { + texture = sorcery.lib.image('sorcery_sparking.png'):glow(sorcery.lib.color(255,0,0)):render(); + pos = vector.offset(p,math.random(),math.random(),math.random()); + expirationtime = 1; + size = 5 + math.random() * 4; + glow = 14; + animation = { + type = 'vertical_frames', length = 0.3; + aspect_w = 64, aspect_h = 64; + } + } + minetest.add_particle { + texture = sorcery.lib.image('sorcery_crackle.png'):glow(sorcery.lib.color(255,0,0)):render(); + pos = vector.offset(p,math.random(),math.random(),math.random()); + expirationtime = 1; + size = 4 + math.random() * 6; + glow = 14; + animation = { + type = 'vertical_frames', length = 0.6; + aspect_w = 64, aspect_h = 64; + } + } + end + end}; + }; + } end; }; }; };