local constants = {
cost_per_barrier = 0.1;
-- 0.1 points of current will be required per second per
-- unit of charge given to a barrier-block when ley-force
-- of counterpraxic affinity is not available
}
local aimtbl = {
[0] = {x = 0, y = 1, z = 0};
[1] = {x = 0, y = 0, z = 1};
[2] = {x = 0, y = 0, z = -1};
[3] = {x = 1, y = 0, z = 0};
[4] = {x = -1, y = 0, z = 0};
[5] = {x = 0, y = -1, z = 0};
}
local pofstbl = {
[0] = {x=0.5, y=0, z=0.5};
[1] = {x=0.5, y=0.5, z=0};
[2] = {x=0.5, y=0.5, z=0};
[3] = {x=0, y=0.5, z=0.5};
[4] = {x=0, y=0.5, z=0.5};
[5] = {x=0.5, y=0, z=0.5};
}
local calc_cost = function(pos,time)
local node = minetest.get_node(pos)
local aim = aimtbl[math.floor(node.param2 / 4)]
local tgts = {}
for i=1,5 do
local tpos = vector.add(pos, vector.multiply(aim,i))
local n = minetest.get_node(tpos)
if n.name == 'air' then tgts[#tgts + 1] = {tpos,0} else
local f = minetest.get_item_group(n.name, 'sorcery_force_barrier')
if f > 0 then
tgts[#tgts + 1] = {tpos,f}
else break end
end
end
return {
aim = aim;
maxcost = #tgts * constants.cost_per_barrier * time;
mincost = math.min(1,#tgts) * constants.cost_per_barrier * time;
targets = tgts;
}
end
for i=1,10 do
minetest.register_node('sorcery:air_barrier_' .. tostring(i), {
drawtype = 'glasslike';
walkable = true;
pointable = false;
sunlight_propagates = true;
paramtype = 'light';
light_source = i;
drop = {max_items = 0, items = {}};
on_blast = function() end; -- not affected by explosions
tiles = {'sorcery_transparent.png'};
groups = {
air = 1;
sorcery_air = 1;
sorcery_force_barrier = i;
};
-- _proto = {
-- strength = i;
-- };
on_construct = function(pos)
minetest.get_node_timer(pos):start(1)
end;
on_timer = function(pos,delta)
local dec = 40*delta
local node = minetest.get_node(pos)
local newstr = math.ceil(10 * ((node.param2 - dec) / 0xFF))
local newnode = 'sorcery:air_barrier_' .. tostring(newstr)
if newstr <= 0 then
minetest.remove_node(pos)
return false
else
for _,c in pairs {{165,255,252}, {146,205,255}, {190,93,253}} do
minetest.add_particlespawner {
time = 1;
amount = 15;
minpos = vector.add(pos, -0.6);
maxpos = vector.add(pos, 0.6);
minvel = {x = 0, y = 0, z = 0};
maxvel = {x = 0, y = 0, z = 0};
minacc = {x = -0.1, y = -0.1, z = -0.1};
maxacc = {x = 0.1, y = 0.1, z = 0.1};
minexptime = 0.5;
maxexptime = 1.0;
minsize = 0.2;
minsize = 0.7;
texture = sorcery.lib.image('sorcery_spark.png'):multiply(sorcery.lib.color(c)):render();
glow = 14;
animation = {
length = 1.1;
type = 'vertical_frames';
aspect_h = 16, aspect_w = 16;
};
}
end
minetest.swap_node(pos, {
name = newnode;
param1 = node.param1;
param2 = newstr;
})
return true
end
end;
})
end
minetest.register_node('sorcery:emitter_barrier', {
description = "Barrier Screen Emitter";
paramtype2 = 'facedir';
groups = {
cracky = 2;
sorcery_ley_device = 1;
sorcery_magitech = 1;
};
tiles = {
'sorcery_emitter_barrier_top.png';
'sorcery_emitter_barrier_bottom.png';
'sorcery_emitter_barrier_front.png^[transformR270';
'sorcery_emitter_barrier_front.png^[transformFXR90';
'sorcery_emitter_barrier_side.png';
'sorcery_emitter_barrier_side.png';
};
on_construct = function(pos)
minetest.get_node_timer(pos):start(1)
end;
on_timer = function(pos,delta)
local orientation = math.floor(minetest.get_node(pos).param2 / 4)
local costs = calc_cost(pos,delta)
local probe = sorcery.spell.probe(pos)
if probe.disjunction then return true end
local l = sorcery.ley.netcaps(pos,delta)
if l.self.powerdraw >= costs.mincost then
local dist = l.self.powerdraw / (constants.cost_per_barrier * delta)
for i=1,math.floor(dist) do
local t = costs.targets[i]
local str = math.min(0xFF,t[2] + 50*delta);
local fprobe = sorcery.spell.probe(t[1])
if not fprobe.disjunction then
minetest.swap_node(t[1], {
name = 'sorcery:air_barrier_' .. math.max(1, math.floor(10*(str/0xFF)));
param2 = str;
})
minetest.get_node_timer(t[1]):start(1)
end
end
local pn = vector.add(pos, vector.divide(costs.aim,2));
local pp = vector.add(pn, pofstbl[orientation])
pn = vector.subtract(pn, pofstbl[orientation])
minetest.add_particlespawner {
time = 1;
amount = 20 * dist;
minpos = pn;
maxpos = pp;
minvel = costs.aim;
maxvel = vector.multiply(costs.aim,2);
minsize = 0.3;
maxsize = 0.5;
minexptime = dist*0.5;
maxexptime = dist*0.5;
texture = sorcery.lib.image('sorcery_spark.png'):multiply(sorcery.lib.color(240,255,160)):render();
glow = 14;
animation = {
length = dist + 0.1;
type = 'vertical_frames';
aspect_h = 16, aspect_w = 16;
};
}
return true
end
return false
end;
after_place_node = function(pos, placer, stack, point)
local vec = vector.subtract(point.under, pos)
local n = minetest.get_node(pos)
n.param2 = minetest.dir_to_facedir(vec)
minetest.swap_node(pos,n)
end;
_sorcery = {
ley = {
mode='consume', affinity={'counterpraxic'},
power = function(pos,time)
local l = calc_cost(pos,time)
return l.mincost, l.maxcost
end;
};
on_leychange = function(pos)
minetest.get_node_timer(pos):start(1)
end;
};
})