Correct (almost) all luacheck warnings

Also includes a few code opimizations:
- Combined mining drill functions
- Shorter alias registration (unused?)
- Add TODOs to address later
This commit is contained in:
SmallJoker
2022-06-06 21:04:13 +02:00
parent 0211c582e9
commit 0f6bdb1bde
22 changed files with 260 additions and 250 deletions

View File

@ -16,7 +16,17 @@ technic.modpath = modpath
if rawget(_G, "intllib") then
technic.getter = intllib.Getter()
else
technic.getter = function(s,a,...)if a==nil then return s end a={a,...}return s:gsub("(@?)@(%(?)(%d+)(%)?)",function(e,o,n,c)if e==""then return a[tonumber(n)]..(o==""and c or"")else return"@"..o..n..c end end) end
-- Intllib copypasta: TODO replace with the client-side translation API
technic.getter = function(s,a,...)
if a==nil then return s end
a={a,...}
return s:gsub("(@?)@(%(?)(%d+)(%)?)", function(e,o,n,c)
if e==""then
return a[tonumber(n)]..(o==""and c or"")
end
return "@"..o..n..c
end)
end
end
local S = technic.getter

View File

@ -112,10 +112,13 @@ local function set_forcefield_formspec(meta)
else
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
end
-- TODO: String replacement with %s will stop working with client-side translations
if meta:get_int("enabled") == 0 then
formspec = formspec.."button[0,1.75;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
formspec = formspec.."button[0,1.75;5,1;enable;"..
S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
else
formspec = formspec.."button[0,1.75;5,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
formspec = formspec.."button[0,1.75;5,1;disable;"..
S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
end
meta:set_string("formspec", formspec)
end

View File

@ -47,14 +47,19 @@ local function set_quarry_demand(meta)
local radius = meta:get_int("size")
local diameter = radius*2 + 1
local machine_name = S("%s Quarry"):format("HV")
if meta:get_int("enabled") == 0 or meta:get_int("purge_on") == 1 then
meta:set_string("infotext", S(meta:get_int("purge_on") == 1 and "%s purging cache" or "%s Disabled"):format(machine_name))
local do_purge = meta:get_int("purge_on") == 1
if meta:get_int("enabled") == 0 or do_purge then
local infotext = do_purge and
S("%s purging cache") or S("%s Disabled")
meta:set_string("infotext", infotext:format(machine_name))
meta:set_int("HV_EU_demand", 0)
elseif meta:get_int("dug") == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then
meta:set_string("infotext", S("%s Finished"):format(machine_name))
meta:set_int("HV_EU_demand", 0)
else
meta:set_string("infotext", S(meta:get_int("HV_EU_input") >= quarry_demand and "%s Active" or "%s Unpowered"):format(machine_name))
local infotext = meta:get_int("HV_EU_input") >= quarry_demand
and S("%s Active") or S("%s Unpowered")
meta:set_string("infotext", infotext:format(machine_name))
meta:set_int("HV_EU_demand", quarry_demand)
end
end

View File

@ -36,7 +36,8 @@ technic.register_inductive_machine = function(name)
end
-- Appliances:
-- has_supply: pos of supply node if the appliance has a power radiator near with sufficient power for the demand else ""
-- has_supply: pos of supply node if the appliance has a power radiator near
-- with sufficient power for the demand else ""
-- EU_demand: The power demand of the device.
-- EU_charge: Actual use. set to EU_demand if active==1
-- active: set to 1 if the device is on

View File

@ -48,20 +48,23 @@ local function forceload_on(pos, meta)
end
local function set_display(pos, meta)
local ESC = minetest.formspec_escape
meta:set_string("infotext", S(meta:get_int("enabled") ~= 0 and "%s Enabled" or "%s Disabled"):format(desc))
meta:set_string("formspec",
"size[5,3.5]"..
"item_image[0,0;1,1;technic:admin_anchor]"..
"label[1,0;"..minetest.formspec_escape(desc).."]"..
"label[0,1;"..minetest.formspec_escape(S("Owner:").." "..meta:get_string("owner")).."]"..
"label[1,0;"..ESC(desc).."]"..
"label[0,1;"..ESC(S("Owner:").." "..meta:get_string("owner")).."]"..
(meta:get_int("locked") == 0 and
"button[3,1;2,1;lock;"..minetest.formspec_escape(S("Unlocked")).."]" or
"button[3,1;2,1;unlock;"..minetest.formspec_escape(S("Locked")).."]")..
"field[0.25,2.3;1,1;radius;"..minetest.formspec_escape(S("Radius:"))..";"..meta:get_int("radius").."]"..
"button[3,1;2,1;lock;"..ESC(S("Unlocked")).."]" or
"button[3,1;2,1;unlock;"..ESC(S("Locked")).."]")..
"field[0.25,2.3;1,1;radius;"..ESC(S("Radius:"))..";"..meta:get_int("radius").."]"..
(meta:get_int("enabled") == 0 and
"button[3,2;2,1;enable;"..minetest.formspec_escape(S("Disabled")).."]" or
"button[3,2;2,1;disable;"..minetest.formspec_escape(S("Enabled")).."]")..
"label[0,3;"..minetest.formspec_escape(S("Keeping %d/%d map blocks loaded"):format(#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta))).."]")
"button[3,2;2,1;enable;"..ESC(S("Disabled")).."]" or
"button[3,2;2,1;disable;"..ESC(S("Enabled")).."]")..
"label[0,3;"..ESC(S("Keeping %d/%d map blocks loaded"):format(
#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta)
)).."]")
end
minetest.register_node("technic:admin_anchor", {
@ -80,7 +83,8 @@ minetest.register_node("technic:admin_anchor", {
end,
can_dig = function (pos, player)
local meta = minetest.get_meta(pos)
return meta:get_int("locked") == 0 or (player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
return meta:get_int("locked") == 0 or
(player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
end,
on_destruct = function (pos)
local meta = minetest.get_meta(pos)
@ -99,7 +103,11 @@ minetest.register_node("technic:admin_anchor", {
forceload_off(meta)
if fields.disable then meta:set_int("enabled", 0) end
if fields.enable then meta:set_int("enabled", 1) end
if fields.radius and string.find(fields.radius, "^[0-9]+$") and tonumber(fields.radius) < 256 then meta:set_int("radius", fields.radius) end
if fields.radius
and string.find(fields.radius, "^[0-9]+$")
and tonumber(fields.radius) < 256 then
meta:set_int("radius", fields.radius)
end
if meta:get_int("enabled") ~= 0 then
forceload_on(pos, meta)
end

View File

@ -88,22 +88,22 @@ local function pos_in_list(l, pos)
return false
end
local function table_empty(table)
for _, __ in pairs(table) do
local function table_empty(what)
for _ in pairs(what) do
return false
end
return true
end
local function add_table(table, toadd)
local function add_table(what, toadd)
local i = 1
while true do
local o = table[i]
local o = what[i]
if o == toadd then return end
if o == nil then break end
i = i + 1
end
table[i] = toadd
what[i] = toadd
end
local function move_nodes_vect(poslist, vect, must_not_move, owner)
@ -398,20 +398,6 @@ minetest.register_entity("technic:frame_entity", {
local pos = vector.round(self.object:getpos())
frames_pos[pos_to_string(pos)] = node.name
local stack = ItemStack(node.name)
local itemtable = stack:to_table()
local itemname = nil
if itemtable then
itemname = stack:to_table().name
end
local item_texture = nil
local item_type = ""
if minetest.registered_items[itemname] then
item_texture = minetest.registered_items[itemname].inventory_image
item_type = minetest.registered_items[itemname].type
end
local prop = {
is_visible = true,
textures = { node.name },

View File

@ -304,9 +304,9 @@ function technic.register_battery_box(data)
drop = "technic:"..ltier.."_battery_box0",
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local EU_upgrade, tube_upgrade = 0, 0
local EU_upgrade, _ = 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
EU_upgrade, _ = technic.handle_machine_upgrades(meta)
end
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
local charge = meta:get_int("internal_EU_charge")
@ -345,9 +345,9 @@ function technic.register_battery_box(data)
meta = minetest.get_meta(pos)
if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields)
local EU_upgrade, tube_upgrade = 0, 0
local EU_upgrade, _ = 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
EU_upgrade, _ = technic.handle_machine_upgrades(meta)
end
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
local charge = meta:get_int("internal_EU_charge")

View File

@ -63,22 +63,27 @@ local function clear_networks(pos)
-- This is similar to check_node_subp
technic.cables[minetest.hash_node_position(pos)] = network_id
pos.visited = 1
if technic.is_tier_cable(name, tier) then
if technic.is_tier_cable(node.name, tier) then
-- Found a cable
table.insert(network.all_nodes,pos)
elseif technic.machines[tier][node.name] then
meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
if technic.machines[tier][node.name] == technic.producer then
-- Found a machine
local eu_type = technic.machines[tier][node.name]
meta:set_string(tier.."_network", minetest.pos_to_string(sw_pos))
if eu_type == technic.producer then
table.insert(network.PR_nodes,pos)
elseif technic.machines[tier][node.name] == technic.receiver then
elseif eu_type == technic.receiver then
table.insert(network.RE_nodes,pos)
elseif technic.machines[tier][node.name] == technic.producer_receiver then
elseif eu_type == technic.producer_receiver then
table.insert(network.PR_nodes,pos)
table.insert(network.RE_nodes,pos)
elseif technic.machines[tier][node.name] == "SPECIAL" and
elseif eu_type == "SPECIAL" and
(pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
from_below then
nil then
-- TODO: This case was never executed. Needs testing!
-- Supply converter.
table.insert(network.SP_nodes,pos)
elseif technic.machines[tier][node.name] == technic.battery then
elseif eu_type == technic.battery then
table.insert(network.BA_nodes,pos)
end
end

View File

@ -45,14 +45,12 @@ minetest.register_node("technic:switching_station",{
meta:set_string("active", 1)
meta:set_string("channel", "switching_station"..minetest.pos_to_string(pos))
meta:set_string("formspec", "field[channel;Channel;${channel}]")
local poshash = minetest.hash_node_position(pos)
technic.redundant_warn.poshash = nil
end,
after_dig_node = function(pos)
minetest.forceload_free_block(pos)
pos.y = pos.y - 1
minetest.forceload_free_block(pos)
local poshash = minetest.hash_node_position(pos)
technic.redundant_warn.poshash = nil
end,
on_receive_fields = function(pos, formname, fields, sender)
@ -248,18 +246,15 @@ minetest.register_abm({
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
if not technic.powerctrl_state then return end
local meta = minetest.get_meta(pos)
local meta = minetest.get_meta(pos)
local meta1
local pos1 = {}
local tier = ""
local PR_nodes
local BA_nodes
local RE_nodes
local machine_name = S("Switching Station")
-- Which kind of network are we on:
pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
local pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
--Disable if necessary
if meta:get_int("active") ~= 1 then

View File

@ -428,7 +428,7 @@ for _, state in pairs({"flowing", "source"}) do
liquidtype = state,
liquid_alternative_flowing = "technic:corium_flowing",
liquid_alternative_source = "technic:corium_source",
liquid_viscosity = LAVA_VISC,
liquid_viscosity = 7, -- like lava
liquid_renewable = false,
damage_per_second = 6,
post_effect_color = {a=192, r=80, g=160, b=80},

View File

@ -44,7 +44,10 @@ end
-- Wear down a tool depending on the remaining charge.
function technic.set_RE_wear(itemstack, item_load, max_load)
if (minetest.registered_items[itemstack:get_name()].wear_represents or "mechanical_wear") ~= "technic_RE_charge" then return itemstack end
local def = minetest.registered_items[itemstack:get_name()]
if (def.wear_represents or "mechanical_wear") ~= "technic_RE_charge" then
return itemstack
end
local temp
if item_load == 0 then
temp = 0

View File

@ -36,7 +36,10 @@ function technic.register_can(d)
local charge = get_can_level(itemstack)
if charge == data.can_capacity then return end
if minetest.is_protected(pointed_thing.under, user:get_player_name()) then
minetest.log("action", user:get_player_name().." tried to take "..node.name.." at protected position "..minetest.pos_to_string(pointed_thing.under).." with a "..data.can_name)
minetest.log("action", user:get_player_name()..
" tried to take "..node.name..
" at protected position "..minetest.pos_to_string(pointed_thing.under)..
" with a "..data.can_name)
return
end
minetest.remove_node(pointed_thing.under)
@ -63,7 +66,10 @@ function technic.register_can(d)
local charge = get_can_level(itemstack)
if charge == 0 then return end
if minetest.is_protected(pos, user:get_player_name()) then
minetest.log("action", user:get_player_name().." tried to place "..data.liquid_source_name.." at protected position "..minetest.pos_to_string(pos).." with a "..data.can_name)
minetest.log("action", user:get_player_name()..
" tried to place "..data.liquid_source_name..
" at protected position "..minetest.pos_to_string(pos)..
" with a "..data.can_name)
return
end
minetest.set_node(pos, {name=data.liquid_source_name})

View File

@ -239,97 +239,61 @@ local function pos_is_pointable(pos)
return nodedef and nodedef.pointable
end
local function mining_drill_mk2_setmode(user,itemstack)
local player_name=user:get_player_name()
local item=itemstack:to_table()
local mode = nil
local meta=minetest.deserialize(item["metadata"])
if meta==nil then
meta={}
mode=0
local function mining_drill_mkX_setmode(user, itemstack, drill_type, max_modes)
local player_name = user:get_player_name()
local meta = minetest.deserialize(itemstack:get_metadata()) or {}
if not meta["mode"] then
minetest.chat_send_player(player_name,
S("Use while sneaking to change Mining Drill Mk%d modes."):format(drill_type))
end
if meta["mode"]==nil then
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk%d modes."):format(2))
meta["mode"]=0
mode=0
end
mode=(meta["mode"])
mode=mode+1
if mode>=5 then mode=1 end
minetest.chat_send_player(player_name, S("Mining Drill Mk%d Mode %d"):format(2, mode)..": "..mining_drill_mode_text[mode][1])
itemstack:set_name("technic:mining_drill_mk2_"..mode);
meta["mode"]=mode
local mode = (meta["mode"] or 0) + 1
if mode > max_modes then mode = 1 end
minetest.chat_send_player(player_name,
S("Mining Drill Mk%d Mode %d"):format(2, mode)..
": "..mining_drill_mode_text[mode][1])
itemstack:set_name(("technic:mining_drill_mk%d_%s"):format(drill_type, mode))
meta["mode"] = mode
itemstack:set_metadata(minetest.serialize(meta))
return itemstack
end
local function mining_drill_mk3_setmode(user,itemstack)
local player_name=user:get_player_name()
local item=itemstack:to_table()
local meta=minetest.deserialize(item["metadata"])
if meta==nil then
meta={}
mode=0
end
if meta["mode"]==nil then
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk%d modes."):format(3))
meta["mode"]=0
mode=0
end
mode=(meta["mode"])
mode=mode+1
if mode>=6 then mode=1 end
minetest.chat_send_player(player_name, S("Mining Drill Mk%d Mode %d"):format(3, mode)..": "..mining_drill_mode_text[mode][1])
itemstack:set_name("technic:mining_drill_mk3_"..mode);
meta["mode"]=mode
itemstack:set_metadata(minetest.serialize(meta))
return itemstack
end
local function mining_drill_mk2_handler(itemstack, user, pointed_thing)
local function mining_drill_mkX_handler(itemstack, user, pointed_thing, drill_type, max_modes)
local keys = user:get_player_control()
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.mode or keys.sneak then
return mining_drill_mk2_setmode(user, itemstack)
end
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) or not meta.charge then
return
end
local charge_to_take = cost_to_use(2, meta.mode)
if meta.charge >= charge_to_take then
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
drill_dig_it(pos, user, meta.mode)
if not technic.creative_mode then
meta.charge = meta.charge - charge_to_take
itemstack:set_metadata(minetest.serialize(meta))
technic.set_RE_wear(itemstack, meta.charge, max_charge[2])
local meta = minetest.deserialize(itemstack:get_metadata()) or {}
-- Mode switching (if possible)
if max_modes > 1 then
if not meta.mode or keys.sneak then
return mining_drill_mkX_setmode(user, itemstack, drill_type, max_modes)
end
end
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) then
return
end
if not meta.charge then
return
end
-- Check whether the tool has enough charge
local charge_to_take = cost_to_use(drill_type, meta.mode or 1)
if meta.charge < charge_to_take then
return
end
-- Do the actual shoorting action
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
drill_dig_it(pos, user, meta.mode)
if not technic.creative_mode then
meta.charge = meta.charge - charge_to_take
itemstack:set_metadata(minetest.serialize(meta))
technic.set_RE_wear(itemstack, meta.charge, max_charge[drill_type])
end
return itemstack
end
local function mining_drill_mk3_handler(itemstack, user, pointed_thing)
local keys = user:get_player_control()
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.mode or keys.sneak then
return mining_drill_mk3_setmode(user, itemstack)
end
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) or not meta.charge then
return
end
local charge_to_take = cost_to_use(3, meta.mode)
if meta.charge >= charge_to_take then
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
drill_dig_it(pos, user, meta.mode)
if not technic.creative_mode then
meta.charge = meta.charge - charge_to_take
itemstack:set_metadata(minetest.serialize(meta))
technic.set_RE_wear(itemstack, meta.charge, max_charge[3])
end
end
return itemstack
end
-- Simple mining drill registration
technic.register_power_tool("technic:mining_drill", max_charge[1])
@ -340,34 +304,20 @@ minetest.register_tool("technic:mining_drill", {
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) then
return itemstack
end
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.charge then
return
end
local charge_to_take = cost_to_use(1, 1)
if meta.charge >= charge_to_take then
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
drill_dig_it(pos, user, 1)
if not technic.creative_mode then
meta.charge = meta.charge - charge_to_take
itemstack:set_metadata(minetest.serialize(meta))
technic.set_RE_wear(itemstack, meta.charge, max_charge[1])
end
end
mining_drill_mkX_handler(itemstack, user, pointed_thing, 1, 1)
return itemstack
end,
})
-- Mk2 registration
minetest.register_tool("technic:mining_drill_mk2", {
description = S("Mining Drill Mk%d"):format(2),
inventory_image = "technic_mining_drill_mk2.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk2_handler(itemstack, user, pointed_thing)
mining_drill_mkX_handler(itemstack, user, pointed_thing, 2, 4)
return itemstack
end,
})
@ -384,20 +334,22 @@ for i = 1, 4 do
on_refill = technic.refill_RE_charge,
groups = {not_in_creative_inventory=1},
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk2_handler(itemstack, user, pointed_thing)
mining_drill_mkX_handler(itemstack, user, pointed_thing, 2, 4)
return itemstack
end,
})
end
-- Mk3 registration
minetest.register_tool("technic:mining_drill_mk3", {
description = S("Mining Drill Mk%d"):format(3),
inventory_image = "technic_mining_drill_mk3.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk3_handler(itemstack,user,pointed_thing)
return itemstack
mining_drill_mkX_handler(itemstack, user, pointed_thing, 3, 5)
return itemstack
end,
})
@ -413,8 +365,8 @@ for i=1,5,1 do
on_refill = technic.refill_RE_charge,
groups = {not_in_creative_inventory=1},
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk3_handler(itemstack,user,pointed_thing)
return itemstack
mining_drill_mkX_handler(itemstack, user, pointed_thing, 3, 5)
return itemstack
end,
})
end

View File

@ -33,6 +33,7 @@ minetest.register_tool("technic:prospector", {
toolstack:set_metadata(minetest.serialize(toolmeta))
technic.set_RE_wear(toolstack, toolmeta.charge, technic.power_tools[toolstack:get_name()])
end
-- What in the heaven's name is this evil sorcery ?
local start_pos = pointed_thing.under
local forward = minetest.facedir_to_dir(minetest.dir_to_facedir(user:get_look_dir(), true))
local right = forward.x ~= 0 and { x=0, y=1, z=0 } or (forward.y ~= 0 and { x=0, y=0, z=1 } or { x=1, y=0, z=0 })
@ -42,13 +43,36 @@ minetest.register_tool("technic:prospector", {
for f = 0, toolmeta.look_depth-1 do
for r = 0, look_diameter-1 do
for u = 0, look_diameter-1 do
if minetest.get_node(vector.add(vector.add(vector.add(base_pos, vector.multiply(forward, f)), vector.multiply(right, r)), vector.multiply(up, u))).name == toolmeta.target then found = true end
if minetest.get_node(
vector.add(
vector.add(
vector.add(base_pos,
vector.multiply(forward, f)),
vector.multiply(right, r)),
vector.multiply(up, u))
).name == toolmeta.target then
found = true
break
end
end
if found then break end
end
if found then break end
end
if math.random() < 0.02 then found = not found end
minetest.chat_send_player(user:get_player_name(), minetest.registered_nodes[toolmeta.target].description.." is "..(found and "present" or "absent").." in "..look_diameter.."x"..look_diameter.."x"..toolmeta.look_depth.." region")
minetest.sound_play("technic_prospector_"..(found and "hit" or "miss"), { pos = vector.add(user:get_pos(), { x = 0, y = 1, z = 0 }), gain = 1.0, max_hear_distance = 10 })
if math.random() < 0.02 then
found = not found
end
local ndef = minetest.registered_nodes[toolmeta.target]
minetest.chat_send_player(user:get_player_name(),
ndef.description.." is "..(found and "present" or "absent")..
" in "..look_diameter.."x"..look_diameter.."x"..toolmeta.look_depth.." region")
minetest.sound_play("technic_prospector_"..(found and "hit" or "miss"), {
pos = vector.add(user:get_pos(), { x = 0, y = 1, z = 0 }),
gain = 1.0,
max_hear_distance = 10
})
return toolstack
end,
on_place = function(toolstack, user, pointed_thing)