local modes = {
off = {next = 'stop'; power = 0};
stop = {next = 'slow'; power = 0.4; factor = 0; color = {255,126,113}};
slow = {next = 'lift'; power = 0.2; factor = 0.5; color = {255,255,100}};
lift = {next = 'crush'; power = 0.6; factor = -0.25; color = {113,255,126}};
crush = {next = 'off'; power = 1; factor = 2; color = {113,126,255}};
}
for kind, p in pairs(modes) do
local radius = 4
local enoughpower = function(pos,mode)
if mode and modes[mode] == nil then return false end
local n = modes[mode or kind]
local l = sorcery.ley.netcaps(pos,1,nil,n.power)
local maxfree = l.self.powerdraw + l.freepower
return maxfree >= n.power
end
local setmeta = function(pos,nextmode)
local label = 'Gravitator'
if nextmode ~= 'off' then
label = label .. ' (' .. nextmode .. ')'
minetest.get_node_timer(pos):start(4)
end
local meta = minetest.get_meta(pos)
meta:set_string('infotext',label)
end
minetest.register_node('sorcery:gravitator_' .. kind, {
description = 'Gravitator';
drop = 'sorcery:gravitator_off';
paramtype2 = 'facedir';
groups = {
cracky = 2;
sorcery_magitech = 1;
sorcery_ley_device = 1;
not_in_creative_inventory = kind == 'off' and nil or 1;
effect_trigger = (kind == 'off') and nil or 1;
};
tiles = {
'sorcery_gravitator_side.png';
'sorcery_gravitator_side.png';
'sorcery_gravitator_side.png';
'sorcery_gravitator_side.png';
'sorcery_gravitator_side.png';
'sorcery_gravitator_panel_'..kind..'.png';
};
effect_near = p.factor and {
impacts = {
gravity = p.factor;
};
distance = radius;
spread = 1.5;
} or nil;
_sorcery = {
ley = {
mode = 'consume', affinity = {'counterpraxic'};
power = p.power;
};
on_leychange = function(pos)
local meta = minetest.get_meta(pos)
if kind ~= 'off' then
if not enoughpower(pos) then
local old = minetest.get_node(pos)
old.name = 'sorcery:gravitator_off'
minetest.swap_node(pos,old)
meta:set_string('lastmode',kind)
setmeta(pos,'off')
end
elseif meta:contains('lastmode') then
local nm = meta:get_string('lastmode')
if enoughpower(pos,nm) then
local old = minetest.get_node(pos)
old.name = 'sorcery:gravitator_' .. nm
minetest.set_node(pos,old)
setmeta(pos,nm)
end
end
end;
};
on_construct = function(pos)
setmeta(pos,'off')
end;
on_timer = function(pos)
if p.color == nil then return false end
local vee = {x=0,y=-1,z=0};
minetest.add_particlespawner {
amount = 128;
time = 4;
minpos = vector.subtract(pos,radius);
maxpos = vector.add(pos,radius);
minvel = vector.multiply(vee, p.factor*0.5);
maxvel = vector.multiply(vee, p.factor);
minexptime = 1;
maxexptime = 1.3;
minsize = 0.2, maxsize = 1.4;
glow = 12;
texture = sorcery.lib.image('sorcery_spark.png'):multiply(sorcery.lib.color(p.color)):render();
animation = {
type = 'vertical_frames';
aspect_w = 16, aspect_h = 16;
length = 1.4;
}
}
return true;
end;
on_rightclick = function(pos)
minetest.sound_play('doors_steel_door_open', {
gain = 0.6;
pos = pos;
}, true)
local nextmode = p.next
while true do
local nm = modes[nextmode]
if nm.power == 0 then break end
if nm.power <= p.power then break end
if enoughpower(pos,nextmode) then break end
nextmode = nm.next
end
local old = minetest.get_node(pos)
minetest.set_node(pos, {
name = 'sorcery:gravitator_' .. nextmode;
param1 = old.param1;
param2 = old.param2;
})
setmeta(pos,nextmode)
end;
})
end