Differences From
Artifact [b24c7d1147]:
1 1 local constants = {
2 2 keg_volume = sorcery.liquid.constants.glasses_per_bottle * 600
3 3 }
4 4
5 -local hitbox = {
5 +local hitbox = function(yo) return {
6 + type = 'fixed';
7 + fixed = {
8 + -0.4, -0.5 + yo, -0.45;
9 + 0.4, 0.2 + yo, 0.5;
10 + };
11 +} end
12 +local mcbox = {
6 13 type = 'fixed';
7 14 fixed = {
8 - -0.4, -0.5, -0.5;
9 - 0.4, 0.2, 0.5;
15 + -0.5, -0.4, -0.5;
16 + 0.5, 0.3, 0.4;
10 17 };
11 18 }
19 +
12 20 local kegcaption = function(m)
13 21 local liqid = m:get_string('liquid')
14 22 if liqid ~= '' then
15 23 local liq = sorcery.register.liquid.db[liqid]
16 24 if not liq then log.err('missing entry for liquid',liqid) return end
17 25 return {
18 26 title = string.format('%s Keg', sorcery.lib.str.capitalize(liq.name));
19 27 color = sorcery.lib.color(liq.color);
20 28 desc = string.format('%s of %s', liq.measure(m:get_int('charge')), liq.name);
21 29 };
22 30 else return { title = 'Empty Keg', props = {} } end
23 31 end
32 +
24 33 local log = sorcery.logger('keg')
25 -minetest.register_node('sorcery:keg', {
26 - description = 'Keg';
27 - drawtype = 'mesh';
28 - mesh = 'sorcery-keg.obj';
29 - sunlight_propagates = true;
30 - paramtype = 'light';
31 - paramtype2 = 'facedir';
32 - groups = { choppy = 2; sorcery_container = 2 }; -- 2=liquid
33 - tiles = {
34 - 'default_bronze_block.png';
35 - 'default_wood.png';
36 - 'default_steel_block.png';
37 - };
38 - selection_box = hitbox;
39 - collision_box = hitbox;
40 - drop = {
41 - -- preserve_metadata will not work without this!
42 - max_items = 1;
43 - items = {
44 - { items = { 'sorcery:keg' } };
34 +for _, keg in pairs {
35 + { name = 'Keg', id = 'sorcery:keg', model = 'sorcery-keg.obj', atch = 1 };
36 + { name = 'Mounted Keg', id = 'sorcery:keg_stand', model = 'sorcery-keg-stand.obj', atch = 0, ofs = 0.1, cb = mcbox };
37 +} do
38 + minetest.register_node(keg.id, {
39 + description = keg.name;
40 + drawtype = 'mesh';
41 + mesh = keg.model;
42 + sunlight_propagates = true;
43 + paramtype = 'light';
44 + paramtype2 = 'facedir';
45 + groups = { choppy = 2; sorcery_container = 2; attached_node = keg.atch }; -- 2=liquid
46 + tiles = {
47 + 'default_bronze_block.png';
48 + 'default_wood.png';
49 + 'default_steel_block.png';
50 + };
51 + selection_box = hitbox(keg.ofs or 0);
52 + collision_box = keg.cb or hitbox(keg.ofs or 0);
53 + drop = {
54 + -- preserve_metadata will not work without this!
55 + max_items = 1;
56 + items = {
57 + { items = { keg.id } };
58 + };
45 59 };
46 - };
47 - preserve_metadata = function(pos,node,meta,drops)
48 - if meta.liquid and meta.liquid ~= '' then
49 - local m = drops[1]:get_meta()
50 - m:from_table({fields = meta})
51 - local cap = kegcaption(m)
52 - m:set_string('description', sorcery.lib.ui.tooltip(cap))
53 - m:set_string('short_description', cap.title)
54 - end
55 - end;
56 - after_place_node = function(pos, placer, stack, tgt)
57 - local meta = minetest.get_meta(pos)
58 - local stackmeta = stack:get_meta()
59 - meta:from_table(stackmeta:to_table())
60 - if not meta:contains('infotext') then
61 - meta:set_string('infotext', 'Empty Keg')
62 - end
63 - end;
64 - on_rightclick = function(pos, node, user, stack)
65 - local m = minetest.get_meta(pos)
66 - local update = function()
67 - local c = kegcaption(m)
68 - local str = c.title
69 - if c.desc then str = str .. '\n(' .. c.desc .. ')' end
70 - if c.props then for _,p in pairs(c.props) do -- future-proofing
71 - str = str .. string.format('\n(%s: %s)', p.title, p.desc)
72 - end end
73 - m:set_string('infotext', str)
74 - end
75 -
76 - if stack:is_empty() then return end
77 -
78 - local ctr = sorcery.itemclass.get(stack, 'container')
79 - if (not ctr) or not ctr.hold == 'liquid' then return end
80 -
81 - local liqid = m:get_string('liquid')
82 - if ctr.has and -- add liquid to keg
83 - (liqid == ctr.has or not m:contains('liquid')) then
84 - if not ctr.empty then log.err(stack:get_name(), 'does not specify its empty counterpart container') return end
85 -
86 - local add = ctr.charge * stack:get_count()
87 - local chg = m:get_int('charge')
88 - if chg + add > constants.keg_volume then
89 - log.act(string.format('%s tried to overfill a %s keg at %s',
90 - user:get_player_name(),
91 - ctr.has, minetest.pos_to_string(pos)))
92 - return
60 + preserve_metadata = function(pos,node,meta,drops)
61 + if meta.liquid and meta.liquid ~= '' then
62 + local m = drops[1]:get_meta()
63 + m:from_table({fields = meta})
64 + local cap = kegcaption(m)
65 + m:set_string('description', sorcery.lib.ui.tooltip(cap))
66 + m:set_string('short_description', cap.title)
67 + end
68 + end;
69 + after_place_node = function(pos, placer, stack, tgt)
70 + local meta = minetest.get_meta(pos)
71 + local stackmeta = stack:get_meta()
72 + meta:from_table(stackmeta:to_table())
73 + if not meta:contains('infotext') then
74 + meta:set_string('infotext', 'Empty Keg')
75 + end
76 + end;
77 + on_rightclick = function(pos, node, user, stack)
78 + local m = minetest.get_meta(pos)
79 + local update = function()
80 + local c = kegcaption(m)
81 + local str = c.title
82 + if c.desc then str = str .. '\n(' .. c.desc .. ')' end
83 + if c.props then for _,p in pairs(c.props) do -- future-proofing
84 + str = str .. string.format('\n(%s: %s)', p.title, p.desc)
85 + end end
86 + m:set_string('infotext', str)
93 87 end
94 - m:set_int('charge', chg + add)
95 - m:set_string('liquid', ctr.has)
96 - sorcery.liquid.sound_pour(add,chg,pos)
88 +
89 + if stack:is_empty() then return end
90 +
91 + local ctr = sorcery.itemclass.get(stack, 'container')
92 + if (not ctr) or not ctr.hold == 'liquid' then return end
93 +
94 + local liqid = m:get_string('liquid')
95 + if ctr.has and -- add liquid to keg
96 + (liqid == ctr.has or not m:contains('liquid')) then
97 + if not ctr.empty then log.err(stack:get_name(), 'does not specify its empty counterpart container') return end
98 +
99 + local add = ctr.charge * stack:get_count()
100 + local chg = m:get_int('charge')
101 + if chg + add > constants.keg_volume then
102 + log.act(string.format('%s tried to overfill a %s keg at %s',
103 + user:get_player_name(),
104 + ctr.has, minetest.pos_to_string(pos)))
105 + return
106 + end
107 + m:set_int('charge', chg + add)
108 + m:set_string('liquid', ctr.has)
109 + sorcery.liquid.sound_pour(add,chg,pos)
97 110
98 - local liq = sorcery.register.liquid.db[ctr.has]
99 - if liq then
100 - update()
101 - log.act(string.format('%s added %u units of %s to a keg at %s',
102 - user:get_player_name(), add,
103 - ctr.has, minetest.pos_to_string(pos)))
104 - else log.err('no liquid entry for',ctr.has) end
111 + local liq = sorcery.register.liquid.db[ctr.has]
112 + if liq then
113 + update()
114 + log.act(string.format('%s added %u units of %s to a keg at %s',
115 + user:get_player_name(), add,
116 + ctr.has, minetest.pos_to_string(pos)))
117 + else log.err('no liquid entry for',ctr.has) end
105 118
106 - return ItemStack {
107 - name = ctr.empty;
108 - count = stack:get_count();
109 - }
110 - elseif not ctr.has and liqid ~= '' then -- take liquid
111 - local liq = sorcery.register.liquid.db[m:get_string('liquid')]
112 - if not liq then log.err('missing definition for liquid', liqid) return end
119 + return ItemStack {
120 + name = ctr.empty;
121 + count = stack:get_count();
122 + }
123 + elseif not ctr.has and liqid ~= '' then -- take liquid
124 + local liq = sorcery.register.liquid.db[m:get_string('liquid')]
125 + if not liq then log.err('missing definition for liquid', liqid) return end
113 126
114 - local basin = m:get_int('charge')
115 - local filled, amtleft = sorcery.liquid.fill_from_basin(stack, liqid, basin)
116 - if filled then
117 - local chg = basin - amtleft
118 - log.act(string.format('%s removed %u units of %s from a keg at %s',
119 - user:get_player_name(), chg, liqid,
120 - minetest.pos_to_string(pos)))
121 - if amtleft == 0 then
122 - m:set_string('liquid','')
123 - m:set_int('charge',0)
124 - else m:set_int('charge', amtleft) end
125 - sorcery.liquid.sound_dip(chg,avail,pos)
126 - update()
127 + local basin = m:get_int('charge')
128 + local filled, amtleft = sorcery.liquid.fill_from_basin(stack, liqid, basin)
129 + if filled then
130 + local chg = basin - amtleft
131 + log.act(string.format('%s removed %u units of %s from a keg at %s',
132 + user:get_player_name(), chg, liqid,
133 + minetest.pos_to_string(pos)))
134 + if amtleft == 0 then
135 + m:set_string('liquid','')
136 + m:set_int('charge',0)
137 + else m:set_int('charge', amtleft) end
138 + sorcery.liquid.sound_dip(chg,avail,pos)
139 + update()
127 140
128 - -- fancy visuals
129 - local color = sorcery.lib.color(liq.color or {255,255,255})
130 - local spritz = sorcery.lib.image('sorcery_droplet.png'):glow(color)
131 - local drop = sorcery.lib.image('sorcery_drop.png'):glow(color)
132 - local facing = minetest.facedir_to_dir(minetest.get_node(pos).param2)
133 - local noz = vector.add(pos, vector.rotate(
134 - vector.new(0.0,0,-0.48),
135 - vector.dir_to_rotation(facing)
136 - ))
137 - local minnoz = vector.offset(noz, -0.03, -0.32, -0.03);
138 - local maxnoz = vector.offset(noz, 0.03, -0.32, 0.03);
139 - minetest.add_particlespawner {
140 - amount = 15 * chg, time = 0.1*chg;
141 - texture = spritz:render();
142 - minpos = minnoz, maxpos = maxnoz;
143 - minvel = vector.new(0,0,0);
144 - maxvel = vector.new(0,-0.1,0);
145 - minacc = vector.new(0,-0.1,0);
146 - maxacc = vector.new(0,-0.13,0);
147 - minsize = 0.4, maxsize = 1;
148 - glow = 14; -- FIXME liquid glow prop
149 - minexptime = 0.5, maxexptime = 0.5;
150 - animation = {
151 - type = 'sheet_2d';
152 - frames_w = 14;
153 - frames_h = 1;
154 - frame_length = (0.5/14) + 0.02;
155 - }
156 - }
157 - minetest.after(0.2, function()
141 + -- fancy visuals
142 + local color = sorcery.lib.color(liq.color or {255,255,255})
143 + local spritz = sorcery.lib.image('sorcery_droplet.png'):glow(color)
144 + local drop = sorcery.lib.image('sorcery_drop.png'):multiply(color)
145 + local facing = minetest.facedir_to_dir(minetest.get_node(pos).param2)
146 + local noz = vector.add(
147 + vector.offset(pos,0,keg.ofs or 0,0),
148 + vector.rotate(
149 + vector.new(0.0,0,-0.48),
150 + vector.dir_to_rotation(facing)
151 + )
152 + )
153 + local minnoz = vector.offset(noz, -0.03, -0.32, -0.03);
154 + local maxnoz = vector.offset(noz, 0.03, -0.32, 0.03);
158 155 minetest.add_particlespawner {
159 - amount = math.random(5,11) * chg, time = 0.13 * chg;
160 - texture = drop:render();
161 - minpos = minnoz;
162 - maxpos = maxnoz;
163 - minvel = vector.new(0,-0.1,0);
164 - maxvel = vector.new(0,-0.4,0);
165 - minacc = vector.new(0,-0.15,0);
166 - maxacc = vector.new(0,-0.18,0);
167 - minsize = 0.3, maxsize = 0.5;
156 + amount = 15 * chg, time = 0.1*chg;
157 + texture = spritz:render();
158 + minpos = minnoz, maxpos = maxnoz;
159 + minvel = vector.new(0,0,0);
160 + maxvel = vector.new(0,-0.1,0);
161 + minacc = vector.new(0,-0.1,0);
162 + maxacc = vector.new(0,-0.13,0);
163 + minsize = 0.4, maxsize = 1;
168 164 glow = 14; -- FIXME liquid glow prop
169 - minexptime = 1, maxexptime = 1.5;
165 + minexptime = 0.5, maxexptime = 0.5;
170 166 animation = {
171 167 type = 'sheet_2d';
172 - frames_w = 10;
168 + frames_w = 14;
173 169 frames_h = 1;
174 - frame_length = (1.5/10) + 0.02;
170 + frame_length = (0.5/14) + 0.02;
175 171 }
176 172 }
177 - end)
173 + minetest.after(0.2, function()
174 + minetest.add_particlespawner {
175 + amount = math.random(5,11) * chg, time = 0.13 * chg;
176 + texture = drop:render();
177 + minpos = minnoz;
178 + maxpos = maxnoz;
179 + minvel = vector.new(0,-0.1,0);
180 + maxvel = vector.new(0,-0.4,0);
181 + minacc = vector.new(0,-0.15,0);
182 + maxacc = vector.new(0,-0.18,0);
183 + minsize = 0.3, maxsize = 0.5;
184 + glow = 14; -- FIXME liquid glow prop
185 + minexptime = 1, maxexptime = 1.5;
186 + animation = {
187 + type = 'sheet_2d';
188 + frames_w = 10;
189 + frames_h = 1;
190 + frame_length = (1.5/10) + 0.02;
191 + }
192 + }
193 + end)
178 194
179 - return filled
195 + return filled
196 + end
180 197 end
181 - end
182 - end;
183 -})
198 + end;
199 + })
200 +end
184 201
185 202 minetest.register_craft {
186 203 output = "sorcery:keg";
187 204 recipe = {
188 205 {'','screwdriver:screwdriver',''};
189 206 {'sorcery:screw_bronze', 'sorcery:tap', 'sorcery:screw_bronze'};
190 207 {'sorcery:screw_bronze', 'xdecor:barrel', 'sorcery:screw_bronze'};
191 208 };
192 209 replacements = {
193 210 {'screwdriver:screwdriver', 'screwdriver:screwdriver'};
194 211 };
195 212 }
213 +
214 +minetest.register_craft {
215 + output = "sorcery:keg_stand";
216 + recipe = {
217 + {'','sorcery:keg',''};
218 + {'sorcery:screw_steel','group:wood','sorcery:screw_steel'};
219 + {'sorcery:screw_steel','screwdriver:screwdriver','sorcery:screw_steel'};
220 + };
221 + replacements = {{'screwdriver:screwdriver', 'screwdriver:screwdriver'}};
222 +}
223 +
224 +minetest.register_craft {
225 + output = "sorcery:keg";
226 + type = 'shapeless';
227 + recipe = { 'sorcery:keg_stand', 'screwdriver:screwdriver' };
228 + replacements = {
229 + {'screwdriver:screwdriver', 'screwdriver:screwdriver'};
230 + {'sorcery:keg_stand', 'sorcery:screw_steel 4'};
231 + };
232 +}