sorcery  entities.lua at [ea6e475e44]

File entities.lua artifact 9c44805455 part of check-in ea6e475e44


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'};
		groups = {immortal = 1};
		visual_size = { x = 2, y = 2, z = 2 };
		physical = false;
		collide_with_objects = false;
		pointable = false;
		glow = 14;
		static_save = false;
	};
	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
		
		::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
		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;
})