local constants = {
farcaster_nonlocal_cost = 0.1;
-- the amount of power it takes to cast 50 nodes away
}
minetest.register_node('sorcery:raycaster', {
description = 'Raycaster';
groups = { cracky = 2; sorcery_ley_device = 1; sorcery_magitech = 1; };
paramtype2 = 'facedir';
tiles = {
'sorcery_farcaster_linear_top.png';
'sorcery_farcaster_linear_bottom.png';
'sorcery_farcaster_linear_side.png';
};
_sorcery = {
ley = {
mode = 'consume', affinity = {'mandatic'};
power = function(pos,delta)
local tune = sorcery.attunement.verify(pos)
if tune then return 0.3 else return 0 end
end
};
attune = {
class = 'sorcery:raycaster', accepts = 'sorcery:raycaster';
source = true, target = true, reciprocal = true;
};
farcaster = {
partner = function(pos)
local tune = sorcery.attunement.verify(pos)
if not tune then return nil end
minetest.load_area(tune.partner)
local vis = false
local ignored
repeat
ignored = false
for _,p in pairs(sorcery.lib.node.offsets.neighbors) do
local sum = vector.add(pos,p)
local _, stop = minetest.line_of_sight(sum,tune.partner)
if vector.equals(stop, tune.partner) then
vis = true
break
else
if minetest.get_node(stop).name == 'ignore' then
minetest.load_area(stop)
ignored = true
end
end
end
until ignored == false
if vis == true
then return tune.partner
else return nil
end
end;
};
};
})
minetest.register_node('sorcery:farcaster', {
description = 'Farcaster';
paramtype2 = 'facedir';
groups = { cracky = 2; sorcery_ley_device = 1; sorcery_magitech = 1; };
tiles = {
'sorcery_farcaster_nonlocal_top.png';
'sorcery_farcaster_nonlocal_top.png';
'sorcery_farcaster_nonlocal_side.png';
'sorcery_farcaster_nonlocal_side.png';
'sorcery_farcaster_nonlocal_back.png';
'sorcery_farcaster_nonlocal_front.png';
};
_sorcery = {
ley = { mode = 'consume'; affinity = {'mandatic'};
power = function(pos,delta)
local tune = sorcery.attunement.verify(pos)
if not tune then
return 0
else
return (vector.distance(pos,tune.partner) / 50) * constants.farcaster_nonlocal_cost
end
end;
};
attune = {
class = 'sorcery:farcaster', accepts = 'sorcery:farcaster';
source = true, target = true, reciprocal = true;
};
farcaster = {
partner = function(pos)
local tune = sorcery.attunement.verify(pos)
if not tune then return nil end
return tune.partner
end;
}
};
})
sorcery.farcaster = {}
sorcery.farcaster.junction = function(start,minconduct)
local stack = {{pos = start, hops = 0, route = {}}}
local checked, network = {},{}
local checkedp = function(pos)
for _,v in pairs(checked) do
if vector.equals(pos,v) then return true end
end
return false
end
local i = 1 repeat
local caps = sorcery.ley.netcaps(stack[i].pos,1,nil,minconduct)
network[#network+1] = {
caps = caps;
hops = stack[i].hops;
route = stack[i].route;
}
for _,d in pairs(caps.net.devices.consume) do
if not checkedp(d.pos) then
checked[#checked+1] = d.pos
local def = minetest.registered_nodes[d.id]
if def and def._sorcery and def._sorcery.farcaster then
local fc = def._sorcery.farcaster
local p = fc.partner(d.pos)
if p ~= nil and d.powerdraw >= d.minpower and not checkedp(p) then
local nr = table.copy(stack[i].route)
checked[#checked+1] = p
nr[#nr+1] = d.pos
stack[#stack+1] = {
pos = p;
route = nr;
hops = stack[i].hops + 1;
}
else
end
end
end
end
i = i + 1 until i > #stack
return network
end