local u = sorcery.lib
local flamebolt_pack, flamebolt_unpack = u.marshal.transcoder {
age = u.marshal.t.u32;
lastemit = u.marshal.t.u32;
}
minetest.register_entity('sorcery:spell_projectile_flamebolt',{
initial_properties = {
visual = "sprite";
use_texture_alpha = true;
textures = {'sorcery_fireball.png'};
visual_size = { x = 2, y = 2, z = 2 };
physical = true;
collide_with_objects = true;
pointable = false;
glow = 14;
static_save = false;
shaded = false;
};
on_activate = function(self)
self.object:set_armor_groups{immortal = 1}
end;
on_step = function(self,dtime,collision)
local pos = self.object:get_pos()
if not self._meta then
self._meta = { age = 0; lastemit = 0; emitters = {} }
goto emit
end
self._meta.age = self._meta.age + dtime
if self._meta.age >= 6 then
goto destroy
elseif (self._meta.age - self._meta.lastemit) < 3 then
goto collcheck
end
-- fireballs dissipate when entering antimagic fields
do local probe = sorcery.spell.probe(self.object:get_pos())
if probe.disjunction and not self._meta.ignore_disjunction then
sorcery.vfx.cast_sparkle(nil,sorcery.lib.color(255,90,10),3,0.3,self.object:get_pos())
goto destroy
end end
::emit:: do
self._meta.lastemit = self._meta.age
local spawn = function(num, life_min, life_max, size_min, size_max, gl, speed, img)
table.insert(self._meta.emitters, minetest.add_particlespawner {
amount = num;
minexptime = life_min;
maxexptime = life_max;
minvel = vector.multiply({ x = -1; y = -1; z = -1; }, speed);
maxvel = vector.multiply({ x = 1; y = 1; z = 1; }, speed);
minacc = vector.multiply({ x = 0; y = -1; z = 0; }, speed);
maxacc = vector.multiply({ x = 0; y = 1; z = 0; }, speed);
texture = img or u.image('sorcery_spark.png'):multiply(u.color(255,74,25):brighten(gl)):render();
time = 3;
glow = 14;
minsize = size_min;
maxsize = size_max;
attached = self.object;
animation = ((not img) and {
type = "vertical_frames";
aspect_w = 16;
aspect_h = 16;
length = life_max;
}) or nil;
})
end
-- # life size glow speed
spawn(50, 0.5,1, 10.0,15.0, 1.0, 1.0)
spawn(80, 3.0,6, 5.0, 7.0, 1.7, 2.0)
spawn(140, 1.0,7, 1.0, 6.0, 2.4, 3.0)
spawn(250, 4.0,9, 0.3, 0.8, 3.0, 7.0)
spawn(500, 10,20, 1.0, 1.8, 2.0, 0.2)
spawn(500, 10,20, 0.5, 1.0, 3.0, 0.5)
end
::collcheck:: do
-- if no collision then return end
-- local nname = minetest.get_node(pos).name
-- if nname == 'air' or minetest.registered_nodes[nname].walkable ~= true then return
-- elseif nname == 'ignore' then goto destroy end
-- else fall through to explode
if collision then -- since 5.3 only!!
print('collision detected!',dump(collision))
if collision.collides == false then return end
if #collision.collisions > 0 then
local col = collision.collisions[1]
if col.node_pos then
pos = col.node_pos
elseif col.object then
pos = col.object:get_pos()
end
-- fall through to explode
else return end
else return end
end
::explode:: do
-- minetest.add_particle({
-- pos = pos,
-- velocity = { x = 0, y = 0, z = 0 };
-- acceleration = { x = 0, y = 0, z = 0 };
-- expirationtime = 0.4,
-- size = 50,
-- collisiondetection = false,
-- vertical = false,
-- texture = "tnt_boom.png",
-- glow = 14,
-- })
local boom = function(len,num,speed)
-- minetest.add_particlespawner {
-- amount = num;
-- time = len;
-- minpos = vector.subtract(pos, 1.2);
-- maxpos = vector.add(pos, 1,2);
-- minvel = vector.multiply({ x = -10; y = -10; z = -10; }, speed);
-- maxvel = vector.multiply({ x = 10; y = 10; z = 10; }, speed);
-- minacc = vector.multiply({ x = -1; y = -1; z = -1; }, speed);
-- maxacc = vector.multiply({ x = 1; y = 1; z = 1; }, speed);
-- minexptime = 0.1;
-- maxexptime = 0.3;
-- minsize = 6;
-- maxsize = 25;
-- texture = 'tnt_smoke.png';
-- }
end
boom(0.7, 140, 0.8)
-- minetest.sound_play("tnt_explode", {pos = pos, gain = 1.5, max_hear_distance = 40}, true)
tnt.boom(pos, {
radius = self._blastradius;
})
end
::destroy:: do
if self._meta then for _,v in pairs(self._meta.emitters) do
minetest.delete_particlespawner(v)
end end
self.object:remove()
end
end;
})