local constants = {
keg_volume = sorcery.liquid.constants.glasses_per_bottle * 600
}
local hitbox = function(yo) return {
type = 'fixed';
fixed = {
-0.4, -0.5 + yo, -0.45;
0.4, 0.2 + yo, 0.5;
};
} end
local mcbox = {
type = 'fixed';
fixed = {
-0.5, -0.4, -0.5;
0.5, 0.3, 0.4;
};
}
local kegcaption = function(m)
local liqid = m:get_string('liquid')
if liqid ~= '' then
local liq = sorcery.register.liquid.db[liqid]
if not liq then log.err('missing entry for liquid',liqid) return end
return {
title = string.format('%s Keg', sorcery.lib.str.capitalize(liq.name));
color = sorcery.lib.color(liq.color);
desc = string.format('%s of %s', liq.measure(m:get_int('charge')), liq.name);
};
else return { title = 'Empty Keg', props = {} } end
end
local log = sorcery.logger('keg')
for _, keg in pairs {
{ name = 'Keg', id = 'sorcery:keg', model = 'sorcery-keg.obj', atch = 1 };
{ name = 'Mounted Keg', id = 'sorcery:keg_stand', model = 'sorcery-keg-stand.obj', atch = 0, ofs = 0.1, cb = mcbox };
} do
minetest.register_node(keg.id, {
description = keg.name;
drawtype = 'mesh';
mesh = keg.model;
sunlight_propagates = true;
paramtype = 'light';
paramtype2 = 'facedir';
groups = { choppy = 2; sorcery_container = 2; attached_node = keg.atch }; -- 2=liquid
tiles = {
'default_bronze_block.png';
'default_wood.png';
'default_steel_block.png';
};
selection_box = hitbox(keg.ofs or 0);
collision_box = keg.cb or hitbox(keg.ofs or 0);
drop = {
-- preserve_metadata will not work without this!
max_items = 1;
items = {
{ items = { keg.id } };
};
};
preserve_metadata = function(pos,node,meta,drops)
if meta.liquid and meta.liquid ~= '' then
local m = drops[1]:get_meta()
m:from_table({fields = meta})
local cap = kegcaption(m)
m:set_string('description', sorcery.lib.ui.tooltip(cap))
m:set_string('short_description', cap.title)
end
end;
after_place_node = function(pos, placer, stack, tgt)
local meta = minetest.get_meta(pos)
local stackmeta = stack:get_meta()
meta:from_table(stackmeta:to_table())
if not meta:contains('infotext') then
meta:set_string('infotext', 'Empty Keg')
end
end;
on_rightclick = function(pos, node, user, stack)
local m = minetest.get_meta(pos)
local update = function()
local c = kegcaption(m)
local str = c.title
if c.desc then str = str .. '\n(' .. c.desc .. ')' end
if c.props then for _,p in pairs(c.props) do -- future-proofing
str = str .. string.format('\n(%s: %s)', p.title, p.desc)
end end
m:set_string('infotext', str)
end
if stack:is_empty() then return end
local ctr = sorcery.itemclass.get(stack, 'container')
if (not ctr) or not ctr.hold == 'liquid' then return end
local liqid = m:get_string('liquid')
if ctr.has and -- add liquid to keg
(liqid == ctr.has or not m:contains('liquid')) then
if not ctr.empty then log.err(stack:get_name(), 'does not specify its empty counterpart container') return end
local add = ctr.charge * stack:get_count()
local chg = m:get_int('charge')
if chg + add > constants.keg_volume then
log.act(string.format('%s tried to overfill a %s keg at %s',
user:get_player_name(),
ctr.has, minetest.pos_to_string(pos)))
return
end
m:set_int('charge', chg + add)
m:set_string('liquid', ctr.has)
sorcery.liquid.sound_pour(add,chg,pos)
local liq = sorcery.register.liquid.db[ctr.has]
if liq then
update()
log.act(string.format('%s added %u units of %s to a keg at %s',
user:get_player_name(), add,
ctr.has, minetest.pos_to_string(pos)))
else log.err('no liquid entry for',ctr.has) end
return ItemStack {
name = ctr.empty;
count = stack:get_count();
}
elseif not ctr.has and liqid ~= '' then -- take liquid
local liq = sorcery.register.liquid.db[m:get_string('liquid')]
if not liq then log.err('missing definition for liquid', liqid) return end
local basin = m:get_int('charge')
local filled, amtleft = sorcery.liquid.fill_from_basin(stack, liqid, basin)
if filled then
local chg = basin - amtleft
log.act(string.format('%s removed %u units of %s from a keg at %s',
user:get_player_name(), chg, liqid,
minetest.pos_to_string(pos)))
if amtleft == 0 then
m:set_string('liquid','')
m:set_int('charge',0)
else m:set_int('charge', amtleft) end
sorcery.liquid.sound_dip(chg,avail,pos)
update()
-- fancy visuals
local color = sorcery.lib.color(liq.color or {255,255,255})
local spritz = sorcery.lib.image('sorcery_droplet.png'):glow(color)
local drop = sorcery.lib.image('sorcery_drop.png'):multiply(color)
local facing = minetest.facedir_to_dir(minetest.get_node(pos).param2)
local noz = vector.add(
vector.offset(pos,0,keg.ofs or 0,0),
vector.rotate(
vector.new(0.0,0,-0.48),
vector.dir_to_rotation(facing)
)
)
local minnoz = vector.offset(noz, -0.03, -0.32, -0.03);
local maxnoz = vector.offset(noz, 0.03, -0.32, 0.03);
minetest.add_particlespawner {
amount = 15 * chg, time = 0.1*chg;
texture = spritz:render();
minpos = minnoz, maxpos = maxnoz;
minvel = vector.new(0,0,0);
maxvel = vector.new(0,-0.1,0);
minacc = vector.new(0,-0.1,0);
maxacc = vector.new(0,-0.13,0);
minsize = 0.4, maxsize = 1;
glow = 14; -- FIXME liquid glow prop
minexptime = 0.5, maxexptime = 0.5;
animation = {
type = 'sheet_2d';
frames_w = 14;
frames_h = 1;
frame_length = (0.5/14) + 0.02;
}
}
minetest.after(0.2, function()
minetest.add_particlespawner {
amount = math.random(5,11) * chg, time = 0.13 * chg;
texture = drop:render();
minpos = minnoz;
maxpos = maxnoz;
minvel = vector.new(0,-0.1,0);
maxvel = vector.new(0,-0.4,0);
minacc = vector.new(0,-0.15,0);
maxacc = vector.new(0,-0.18,0);
minsize = 0.3, maxsize = 0.5;
glow = 14; -- FIXME liquid glow prop
minexptime = 1, maxexptime = 1.5;
animation = {
type = 'sheet_2d';
frames_w = 10;
frames_h = 1;
frame_length = (1.5/10) + 0.02;
}
}
end)
return filled
end
end
end;
})
end
minetest.register_craft {
output = "sorcery:keg";
recipe = {
{'','screwdriver:screwdriver',''};
{'sorcery:screw_bronze', 'sorcery:tap', 'sorcery:screw_bronze'};
{'sorcery:screw_bronze', 'xdecor:barrel', 'sorcery:screw_bronze'};
};
replacements = {
{'screwdriver:screwdriver', 'screwdriver:screwdriver'};
};
}
minetest.register_craft {
output = "sorcery:keg_stand";
recipe = {
{'','sorcery:keg',''};
{'sorcery:screw_steel','group:wood','sorcery:screw_steel'};
{'sorcery:screw_steel','screwdriver:screwdriver','sorcery:screw_steel'};
};
replacements = {{'screwdriver:screwdriver', 'screwdriver:screwdriver'}};
}
minetest.register_craft {
output = "sorcery:keg";
type = 'shapeless';
recipe = { 'sorcery:keg_stand', 'screwdriver:screwdriver' };
replacements = {
{'screwdriver:screwdriver', 'screwdriver:screwdriver'};
{'sorcery:keg_stand', 'sorcery:screw_steel 4'};
};
}