sorcery  Diff

Differences From Artifact [64df297e83]:

To Artifact [7838002de4]:






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95






96
97
98

99
100
101
102
103


104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125



126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206




local hitbox = {
	type = 'fixed';
	fixed = {
		-0.4, -0.5, -0.5;
		 0.4,  0.2,  0.5;
	};
}
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
		local measure = liq.measure or function(u)
			return string.format('%s drams', u*63.9)
		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', measure(m:get_int('charge')), liq.name);
		};
	else return { title = 'Empty Keg', props = {} } end
end
local log = sorcery.logger('keg')
minetest.register_node('sorcery:keg', {
	description = 'Keg';
	drawtype = 'mesh';
................................................................................
			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())
	end;
	on_construct = function(pos)
		local m = minetest.get_meta(pos)
		m:set_string('infotext', 'Empty Keg')

	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
		local noise = function(amt)
			minetest.sound_play('default_water_footstep', {
				gain = 0.5 + amt / 9.0;
				pitch = 1.3 - amt / 12.0;
				pos = pos;
			}, true)
		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


		if ctr.has and
			(m:get_string('liquid') == 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')






			m:set_int('charge', chg + add)
			m:set_string('liquid', ctr.has)
			noise(chg + add)


			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', user:get_player_name(), add, ctr.has))


			else log.err('no liquid entry for',ctr.has) end

			return ItemStack {
				name = ctr.empty;
				count = stack:get_count();
			}
		elseif not ctr.has and m:get_string('liquid') ~= '' then
			local reg = sorcery.register.liquid.db[m:get_string('liquid')]
			if not reg then log.err('missing definition for liquid', m:get_string('liquid')) return end

			local filled = reg.containers[stack:get_name()]

			if filled then
				local fs = sorcery.itemclass.get(filled, 'container')
				if not fs then log.err(filled,'is named as filled container but does not have the required itemclass definition') return end
				local chg = fs.charge * stack:get_count()
				local avail = m:get_int('charge')
				
				if avail >= chg then
					local liqid = m:get_string('liquid')
					local liq = sorcery.register.liquid.db[liqid]
					log.act(string.format('%s removed %u units of %s from a keg', user:get_player_name(), chg, liqid))
					if avail == chg then



						m:set_string('liquid','')
						m:set_int('charge',0)
					else m:set_int('charge', avail - chg) end
					noise(chg)

					update()

					-- fancy visuals
					local color = sorcery.lib.color(liq.color or {255,255,255})
					local spritz = sorcery.lib.image('sorcery_droplet.png')
					local drop = sorcery.lib.image('sorcery_drop.png')
					spritz = spritz:blit(spritz:multiply(color))
					drop   = drop:blit  (drop:multiply  (color))
					local facing = minetest.facedir_to_dir(minetest.get_node(pos).param2)
					local noz = vector.add(pos, 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.4*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;
						}
					}
					minetest.after(0.2, function()
						minetest.add_particlespawner {
							amount = math.random(5,11) * chg, time = 0.45 * chg;
							texture = drop:render();
							minpos = vector.offset(minnoz, 0,-0.05,0);
							maxpos = vector.offset(maxnoz, 0,-0.05,0);
							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;
							}
						}
					end)

					return ItemStack {
						name = filled;
						count = stack:get_count();
					}
				end
			end

		end
	end;
})

minetest.register_craft {
	output = "sorcery:keg";
	recipe = {
		{'', 'basic_materials:steel_bar', 'screwdriver:screwdriver'};
		{'sorcery:screw_bronze', 'default:bronze_ingot', 'sorcery:screw_bronze'};
		{'', 'xdecor:barrel', ''};
	};
	replacements = {
		{'screwdriver:screwdriver', 'screwdriver:screwdriver'};
	};
}
>
>
>
>












<
<
<
<



|







 







|
<
<
|
>












<
<
<
<
<
<
<






>
|
|

<



>
>
>
>
>
>


<
>




|
>
>






|
|
|

|
>

<
|
<
<
<
<
<
<
|
<
>
>
>
|
|
|
<
>
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

<
|
<
<
|
<
<







|
|






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16




17
18
19
20
21
22
23
24
25
26
27
..
53
54
55
56
57
58
59
60


61
62
63
64
65
66
67
68
69
70
71
72
73
74







75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117






118

119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181


182


183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
local constants = {
	keg_volume = sorcery.liquid.constants.glasses_per_bottle * 600
}

local hitbox = {
	type = 'fixed';
	fixed = {
		-0.4, -0.5, -0.5;
		 0.4,  0.2,  0.5;
	};
}
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')
minetest.register_node('sorcery:keg', {
	description = 'Keg';
	drawtype = 'mesh';
................................................................................
			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')
				local drop = sorcery.lib.image('sorcery_drop.png')
				spritz = spritz:blit(spritz:multiply(color))
				drop   = drop:blit  (drop:multiply  (color))
				local facing = minetest.facedir_to_dir(minetest.get_node(pos).param2)
				local noz = vector.add(pos, 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;
					}
				}
				minetest.after(0.2, function()
					minetest.add_particlespawner {
						amount = math.random(5,11) * chg, time = 0.13 * chg;
						texture = drop:render();
						minpos = vector.offset(minnoz, 0,-0.05,0);
						maxpos = vector.offset(maxnoz, 0,-0.05,0);
						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;
						}
					}
				end)


				return filled


			end


		end
	end;
})

minetest.register_craft {
	output = "sorcery:keg";
	recipe = {
		{'','screwdriver:screwdriver',''};
		{'sorcery:screw_bronze', 'sorcery:tap', 'sorcery:screw_bronze'};
		{'', 'xdecor:barrel', ''};
	};
	replacements = {
		{'screwdriver:screwdriver', 'screwdriver:screwdriver'};
	};
}