sorcery  Artifact [9c44805455]

Artifact 9c4480545556b902d71d4af271d0e39438823dfe946056a812e65f33552ec66e:

  • File entities.lua — part of check-in [ea6e475e44] at 2020-10-19 09:52:11 on branch trunk — continue dev on celestial mechanics, add melding+division spells (resonance), refine itemclasses, add keypunch and punchcards, add paper pulp, add a shitload of visuals, add convenience scripts for working with the wiki, make the flamebolt spell actually useful instead of just a pretty lightshow, add essences, inferno crystal, and other goodies; iterate on wands, lots of shit i can't remember, various bugfixes (user: lexi, size: 3718) [annotate] [blame] [check-ins using]

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;
})