Wuzzy c72d0ecba9 Consistent writing style of item descriptions
- Fix capitalization
- Fix ungrammatical word order (like “Wood dark”)
2019-04-13 23:52:11 -07:00

791 lines
23 KiB
Lua

--[[
ITB (insidethebox) minetest game - Copyright (C) 2017-2018 sofar & nore
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1
of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
]]--
--
-- hand tools
--
minetest.register_item(":", {
type = "none",
wield_image = "wieldhand.png",
inventory_image = "wieldhand.png",
wield_scale = {x = 1, y = 1, z = 2},
range = 4,
tool_capabilities = {
full_punch_interval = 0.5,
max_drop_level = 0,
-- can't pick up any node by hand
groupcaps = {
hand = {times={[1] = 0.2}, uses = 0, maxlevel = 1},
},
damage_groups = {},
},
groups = {not_in_creative_inventory = 1}
})
minetest.register_item("tools:edit", {
type = "none",
wield_image = "wieldhand_edit.png",
inventory_image = "wieldhand_edit.png",
wield_scale = {x = 1, y = 1, z = 2},
range = 4, -- to make sure we can reach as far as the player
tool_capabilities = {
full_punch_interval = 0.1,
max_drop_level = 0,
groupcaps = {
hand = {times={[1] = 0.2}, uses = 0, maxlevel = 1},
axe = {times={[1] = 0.2}, uses = 0, maxlevel = 1},
shovel = {times={[1] = 0.2}, uses = 0, maxlevel = 1},
pickaxe = {times={[1] = 0.2}, uses = 0, maxlevel = 1},
node = {times={[1] = 0.2}, uses = 0, maxlevel = 1},
unbreakable = {times={[1] = 0.2}, uses = 0, maxlevel = 1},
},
damage_groups = {},
},
groups = {not_in_creative_inventory = 1}
})
-- node tools
minetest.register_tool("tools:shovel", {
description = "Shovel",
inventory_image = "shovel.png",
tool_capabilities = {
groupcaps = {
shovel = {
times = {[1] = 1.5, [2] = 1.5, [3] = 1.5},
uses = 0,
},
},
},
})
frame.register("tools:shovel")
minetest.register_tool("tools:axe", {
description = "Axe",
inventory_image = "axe.png",
tool_capabilities = {
groupcaps = {
axe = {
times = {[1] = 1.5, [2] = 1.5, [3] = 1.5},
uses = 0,
},
},
},
})
frame.register("tools:axe")
minetest.register_tool("tools:pickaxe", {
description = "Pickaxe",
inventory_image = "pickaxe.png",
tool_capabilities = {
groupcaps = {
pickaxe = {
times = {[1] = 3, [2] = 3, [3] = 3},
uses = 0,
},
},
},
})
frame.register("tools:pickaxe")
minetest.register_tool("tools:sword", {
description = "Sword",
inventory_image = "sword.png",
})
frame.register("tools:sword")
minetest.register_tool("tools:flint_and_steel", {
description = "Flint and steel",
inventory_image = "flint_and_steel.png",
})
frame.register("tools:flint_and_steel")
local function node_dig(pos, digger)
-- from builtin/item.lua core.node_dig():
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
local sounds = minetest.registered_nodes[node.name].sounds
if sounds and sounds.dig then
minetest.sound_play(sounds.dig, {pos = pos})
end
local oldmetadata = nil
if def and def.after_dig_node then
oldmetadata = core.get_meta(pos):to_table()
end
minetest.remove_node(pos, node)
if def and def.after_dig_node then
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name = node.name, param1 = node.param1, param2 = node.param2}
def.after_dig_node(pos_copy, node_copy, oldmetadata, digger)
end
for _, callback in ipairs(core.registered_on_dignodes) do
local origin = core.callback_origins[callback]
if origin then
core.set_last_run_mod(origin.mod)
end
-- Copy pos and node because callback can modify them
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name = node.name, param1 = node.param1, param2 = node.param2}
callback(pos_copy, node_copy, digger)
end
end
minetest.register_tool("tools:admin", {
description = "Admin tool",
inventory_image = "admin_tool.png",
liquids_pointable = true,
range = 10,
on_use = function(itemstack, digger, pointed_thing)
if not pointed_thing or not pointed_thing.under then
return
end
-- Prevent non-admins from using an admin tool if they ever get one
if not digger or not minetest.check_player_privs(digger, "server") then
return
end
node_dig(pointed_thing.under, digger)
return itemstack
end,
})
minetest.register_tool("tools:player", {
description = "Remove tool\nLeft click to remove a node\nRight click to remove a lot of nodes\n" ..
"shift-left click a placed node to restrict removal",
inventory_image = "remove_tool.png",
liquids_pointable = true,
range = 6,
on_use = function(itemstack, digger, pointed_thing)
if not digger then
return
end
local name = digger:get_player_name()
if not boxes.players_editing_boxes[name] then
return
end
if not pointed_thing or not pointed_thing.under then
if not digger:get_player_control().sneak then
return itemstack
end
-- empty the contained node
local meta = itemstack:get_meta()
meta:set_string("nodes", "return {}")
minetest.chat_send_player(name, "Remove tool unrestricted")
meta:set_string("description", "Remove tool\nLeft click to remove a node\n" ..
"Right click to remove a lot of nodes\n" ..
"shift-left click a placed node to restrict removal")
return itemstack
end
if digger:get_player_control().sneak then
-- fill the itemstack
local meta = itemstack:get_meta()
local nodes = minetest.deserialize(meta:get_string("nodes") or {}) or {}
local node = minetest.get_node(pointed_thing.under)
nodes[#nodes + 1] = node.name
meta:set_string("nodes", minetest.serialize(nodes))
minetest.chat_send_player(name, "Remove tool restricted to: " .. table.concat(nodes, ", "))
meta:set_string("description", "Remove tool\nWill remove: " .. table.concat(nodes, ", "))
return itemstack
end
local box = boxes.players_editing_boxes[name]
local pos = pointed_thing.under
if pos.x <= box.minp.x or pos.x >= box.maxp.x or
pos.y <= box.minp.y or pos.y >= box.maxp.y or
pos.z <= box.minp.z or pos.z >= box.maxp.z
then
return
end
local meta = itemstack:get_meta()
local n = meta:get_string("nodes")
if n and n ~= "" and n ~= "return {}" then
local nodes = minetest.deserialize(n)
local t = minetest.get_node(pointed_thing.under)
for _, v in ipairs(nodes) do
if t.name == v then
node_dig(pointed_thing.under, digger)
end
end
return itemstack
end
node_dig(pointed_thing.under, digger)
return itemstack
end,
on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing or not pointed_thing.under then
return
end
if not placer then
return
end
local name = placer:get_player_name()
if not boxes.players_editing_boxes[name] then
return
end
local box = boxes.players_editing_boxes[name]
local pos = pointed_thing.under
local meta = itemstack:get_meta()
local n = meta:get_string("nodes")
local nodes = {}
if n and n ~= "" and n ~= "return {}" then
nodes = minetest.deserialize(n)
end
for x = pos.x - 1, pos.x + 1 do
for y = pos.y + 1, pos.y - 1, -1 do
for z = pos.z - 1, pos.z + 1 do
if x > box.minp.x and x < box.maxp.x and
y > box.minp.y and y < box.maxp.y and
z > box.minp.z and z < box.maxp.z then
if #nodes == 0 then
node_dig({x = x, y = y, z = z}, placer)
else
for _, v in ipairs(nodes) do
local p = {x = x, y = y, z = z}
local t = minetest.get_node(p)
if t.name == v then
node_dig(p, placer)
end
end
end
end
end
end
end
return itemstack
end,
})
frame.register("tools:player")
local bulk_modes = {
[0] = "blob",
[1] = "sheet",
[2] = "large blob",
[3] = "large sheet",
[4] = "wall",
}
minetest.register_tool("tools:bulk", {
description = "Bulk placement tool\nLeft-click air to toggle mode\nShift-left-click " ..
"to toggle mode\nLeft-click a node to pick it up\nRight-click to place nodes",
inventory_image = "node_place_tool.png",
liquids_pointable = true,
range = 8,
on_use = function(itemstack, placer, pointed_thing)
if not pointed_thing or not pointed_thing.under or
placer:get_player_control().sneak then
-- toggle placement mode
local meta = itemstack:get_meta()
local mode = meta:get_int("mode") or 0
mode = mode + 1
if mode > #bulk_modes then
mode = 0
end
minetest.chat_send_player(placer:get_player_name(),
"Bulk tool will place a \"" .. bulk_modes[mode] .. "\"")
meta:set_int("mode", mode)
return itemstack
end
local node = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[node.name]
if not def and not def.groups then
return itemstack
end
if def.groups.not_in_creative_inventory or
def.groups.trigger or def.groups.mech or
def.groups.door
then
if not minetest.check_player_privs(placer:get_player_name(), "server") then
return itemstack
end
end
itemstack:set_metadata(minetest.serialize(node))
minetest.chat_send_player(placer:get_player_name(),
"Bulk tool will place " .. node.name)
local meta = itemstack:get_meta()
meta:set_string("description", "Bulk placement tool\nNode: " .. node.name ..
"\nmode: " .. bulk_modes[meta:get_int("mode")])
return itemstack
end,
on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing or not pointed_thing.above or not placer then
return
end
local node = minetest.deserialize(itemstack:get_metadata())
if not node then
minetest.chat_send_player(placer:get_player_name(),
"Pick up a node first by left-clicking it with this tool")
return
end
local name = placer:get_player_name()
local box = boxes.players_editing_boxes[name]
if not box and not minetest.check_player_privs(name, "server") then
return
end
if not box then
box = {
minp = { x = -32768, y = -32768, z = -32768 },
maxp = { x = 32768, y = 32768, z = 32768 },
}
end
-- make sure we don't choke the player.
local head = vector.add(vector.round(placer:get_pos()), {x = 0, y = 1, z = 0})
local pos = pointed_thing.under
local pnode = minetest.get_node(pos)
if not minetest.registered_nodes[pnode.name].buildable_to then
pos = pointed_thing.above
end
local meta = itemstack:get_meta()
local mode = meta:get_int("mode") or 0
-- toggle size
local size = { 3, 20, 28 }
if mode == 2 or mode == 3 then
size = {7, 50, 68 }
end
local function can_place_at(p, b, h)
if p.x <= b.minp.x or p.x >= b.maxp.x or
p.y <= b.minp.y or p.y >= b.maxp.y or
p.z <= b.minp.z or p.z >= b.maxp.z then
return false
end
if vector.equals(p, h) then
return false
end
local n = minetest.get_node(p)
if n.name == "air" then
return true
end
local def = minetest.registered_nodes[n.name]
if def and def.liquidtype and def.liquidtype == "flowing" then
return true
end
return false
end
if mode == 0 or mode == 2 then
for x = pos.x - size[1], pos.x + size[1] do
for y = pos.y - size[1], pos.y + size[1] do
for z = pos.z - size[1], pos.z + size[1] do
local ppos = {x = x, y = y, z = z}
if can_place_at(ppos, box, head) and
vector.distance(pos, ppos) <=
(math.random(size[2], size[3]) / 10)
then
minetest.set_node(ppos, node)
end
end
end
end
elseif mode == 1 or mode == 3 then
for x = pos.x - size[1], pos.x + size[1] do
for z = pos.z - size[1], pos.z + size[1] do
local ppos = {x = x, y = pos.y, z = z}
if can_place_at(ppos, box, head) and
vector.distance(pos, ppos) <=
(math.random(size[2], size[3]) / 10)
then
minetest.set_node(ppos, node)
end
end
end
elseif mode == 4 then
local dir = minetest.yaw_to_dir(placer:get_look_yaw() - (math.pi / 2))
for i = 0, 4 do
for y = 0, 2 do
local ppos = vector.round(vector.add(pos, vector.multiply(dir, i)))
ppos.y = ppos.y + y
if can_place_at(ppos, box, head) then
minetest.set_node(ppos, node)
end
end
end
else
return itemstack
end
minetest.log("action", name .. " uses tools:bulk placing a " .. bulk_modes[mode] ..
" of " .. node.name .. " at " .. minetest.pos_to_string(pos))
return itemstack
end,
})
frame.register("tools:bulk")
minetest.register_tool("tools:paint", {
description = "Paint tool\nPaint nodes over with a different node\nLeft-click to " ..
"fill the tool with a node\nRight-click to paint",
inventory_image = "node_paint_tool.png",
liquids_pointable = true,
range = 6,
on_use = function(itemstack, placer, pointed_thing)
if not pointed_thing or not pointed_thing.under then
return itemstack
end
local node = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[node.name]
if not def and not def.groups then
return itemstack
end
if def.groups.not_in_creative_inventory or
def.groups.trigger or def.groups.mech or
def.groups.door
then
if not minetest.check_player_privs(placer:get_player_name(), "server") then
return itemstack
end
end
itemstack:set_metadata(minetest.serialize(node))
minetest.chat_send_player(placer:get_player_name(),
"Paint tool will paint " .. node.name)
local meta = itemstack:get_meta()
meta:set_string("description", "Paint tool\nNode: " .. node.name)
return itemstack
end,
on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing or not pointed_thing.above or not placer then
return
end
local node = minetest.deserialize(itemstack:get_metadata())
if not node then
minetest.chat_send_player(placer:get_player_name(),
"Pick up a node first by left-clicking it with this tool")
return
end
local name = placer:get_player_name()
local box = boxes.players_editing_boxes[name]
if not box and not minetest.check_player_privs(name, "server") then
return
end
if not box then
box = {
minp = { x = -32768, y = -32768, z = -32768 },
maxp = { x = 32768, y = 32768, z = 32768 },
}
end
local pos = pointed_thing.under
if pos.x > box.minp.x and pos.x < box.maxp.x and
pos.y > box.minp.y and pos.y < box.maxp.y and
pos.z > box.minp.z and pos.z < box.maxp.z then
minetest.set_node(pos, node)
end
return itemstack
end,
})
frame.register("tools:paint")
minetest.register_tool("tools:grow", {
description = "Grow things",
inventory_image = "grow_tool.png",
range = 6,
on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing or not pointed_thing.under or not placer then
return
end
local name = placer:get_player_name()
local box = boxes.players_editing_boxes[name]
if not box then
if not minetest.check_player_privs(placer, "server") then
return
end
box = {
minp = { x = -32768, y = -32768, z = -32768 },
maxp = { x = 32768, y = 32768, z = 32768 },
}
end
local pos = pointed_thing.under
local nname = minetest.get_node(pos).name
if nname == "nodes:dirt" then
for x = math.max(box.minp.x + 1, pos.x - 2), math.min(box.maxp.x - 1, pos.x + 2) do
for y = math.max(box.minp.y + 1, pos.y), math.min(box.maxp.y - 1, pos.y) do
for z = math.max(box.minp.z + 1, pos.z - 2), math.min(box.maxp.z - 1, pos.z + 2) do
local ppos = {x = x, y = y, z = z}
if vector.distance(pos, ppos) <= 2.3 then
local node = minetest.get_node(ppos)
local above_node = minetest.get_node({x = x, y = y + 1, z = z})
if node.name == "nodes:dirt" and
minetest.registered_nodes[above_node.name] and
minetest.registered_nodes[above_node.name].walkable == false then
node.name = "nodes:dirt_with_grass"
minetest.set_node(ppos, node)
end
end
end
end
end
elseif nname == "nodes:grass" or nname == "nodes:dirt_with_grass" then
-- Grow grass and other things
for x = math.max(box.minp.x + 1, pos.x - 2), math.min(box.maxp.x - 1, pos.x + 2) do
for y = math.max(box.minp.y + 1, pos.y), math.min(box.maxp.y - 1, pos.y) do
for z = math.max(box.minp.z + 1, pos.z - 2), math.min(box.maxp.z - 1, pos.z + 2) do
local ppos = {x = x, y = y, z = z}
if vector.distance(pos, ppos) <= 2.3 then
local node = minetest.get_node(ppos)
local pos_above = {x = x, y = y + 1, z = z}
local above_node = minetest.get_node(pos_above)
if (node.name == "nodes:grass" or node.name == "nodes:dirt_with_grass") and
above_node.name == "air" and math.random() < 0.2 then
local plants = {
{"grass_1", 56},
{"grass_2", 56},
{"grass_3", 56},
{"grass_4", 56},
{"grass_5", 56},
{"grass_1", 56},
{"grass_2", 56},
{"grass_3", 56},
{"grass_4", 56},
{"grass_5", 56},
{"grass_1", 56},
{"grass_2", 56},
{"grass_3", 56},
{"grass_4", 56},
{"grass_5", 56},
{"grass_1", 56},
{"grass_2", 56},
{"grass_3", 56},
{"grass_4", 56},
{"grass_5", 56},
{"rose", 9},
{"dandelion", 9},
{"white_tulip", 9},
{"allium", 9},
{"orchid", 9},
{"daisy", 9},
{"houstonia", 9},
{"paeonia", 9},
}
local p = plants[math.random(1, 28)]
local nnode = {name = "nodes:" .. p[1], param2 = p[2]}
minetest.set_node(pos_above, nnode)
end
end
end
end
end
end
return itemstack
end,
})
frame.register("tools:grow")
local function dehash_vector(s)
return {
x = 256 * string.byte(s, 1) + string.byte(s, 2) - 32768,
y = 256 * string.byte(s, 3) + string.byte(s, 4) - 32768,
z = 256 * string.byte(s, 5) + string.byte(s, 6) - 32768,
}
end
local function particlestream(p, o, name)
local d = vector.length(o)
local c = 0
while c < d - 0.5 do
minetest.add_particle({
texture = "glowblock.png",
pos = vector.add(p, vector.multiply(o, c / d)),
velocity = vector.divide(o, d * 3),
expirationtime = 3,
size = 2,
glow = 14,
playername = name,
})
c = c + 0.5
end
end
minetest.register_tool("tools:reveal", {
description = "Reveal breakable nodes and Placeholder nodes\nPunch a node to see it's connections",
inventory_image = "reveal_tool.png",
on_use = function(itemstack, digger, pointed_thing)
if not digger then
return
end
local name = digger:get_player_name()
if not boxes.players_editing_boxes[name] and not minetest.check_player_privs(digger, "server") then
return
end
local box = boxes.players_editing_boxes[name]
if not box then
if not minetest.check_player_privs(digger, "server") then
return
end
box = {
minp = { x = -32768, y = -32768, z = -32768 },
maxp = { x = 32768, y = 32768, z = 32768 },
}
end
local off = {
{ x = 0, y = 0, z = -9/16},
{ x = 0, y = 0, z = 9/16},
{ x = 0, y = -9/16, z = 0},
{ x = 0, y = 9/16, z = 0},
{ x = -9/16, y = 0, z = 0},
{ x = 9/16, y = 0, z = 0},
}
-- if clicking a node, reveal mech connections
if pointed_thing.under then
local p = pointed_thing.under
local meta = minetest.get_meta(p)
local offsets = minetest.deserialize(meta:get_string("offsets")) or {}
for v, _ in pairs(offsets) do
local o = dehash_vector(v)
particlestream(p, o, name)
end
local roffsets = minetest.deserialize(meta:get_string("roffsets")) or {}
for v, _ in pairs(roffsets) do
local o = dehash_vector(v)
particlestream(vector.add(p, o), {x=-o.x, y=-o.y, z=-o.z}, name)
end
local dn = digger:get_player_name()
-- reveal callbacks, mech linkage info
local n = minetest.get_node(p)
if n and n.name and minetest.registered_nodes[n.name] then
local def = minetest.registered_nodes[n.name]
minetest.chat_send_player(dn, minetest.colorize("#ff8888",
"Detailed info for \"" .. def.description:gsub("\n.*", "") ..
"\" at " .. minetest.pos_to_string(p) .. ":"))
for so, _ in pairs(offsets) do
local offs = dehash_vector(so)
local npos = vector.add(p, offs)
local nname = minetest.registered_nodes[minetest.get_node(npos).name].description
minetest.chat_send_player(dn, minetest.colorize("#44ff88",
"> triggers " .. nname:gsub("[\n(].*", "") .. " at " ..
minetest.pos_to_string(npos) .. " (offset is " ..
minetest.pos_to_string(offs) .. ")"))
end
for so, _ in pairs(roffsets) do
local offs = dehash_vector(so)
local npos = vector.add(p, offs)
local nname = minetest.registered_nodes[minetest.get_node(npos).name].description
minetest.chat_send_player(dn, minetest.colorize("#8888ff",
"> triggered by " .. nname:gsub("[\n(].*", "") .. " at " ..
minetest.pos_to_string(npos) .. " (offset is " ..
minetest.pos_to_string(offs) .. ")"))
end
local cb = def.on_reveal
if cb then
cb(dn, p)
end
end
end
local limit = 32
local ppos = vector.floor(digger:get_pos())
local nodes = {}
local needle = {"group:axe", "group:shovel", "group:pickaxe", "group:hand"}
for d = 3, 6 do
if limit > 0 then
local poslist, _ = minetest.find_nodes_in_area(vector.subtract(ppos, d),
vector.add(ppos, d),
needle)
for _, v in pairs(poslist) do
if limit > 0 then
if v.x < box.maxp.x and v.y < box.maxp.y and v.z < box.maxp.z and
v.x > box.minp.x and v.y > box.minp.y and v.z > box.minp.z then
nodes[minetest.pos_to_string(v)] = 1
limit = limit - 1
end
end
end
end
end
for k, _ in pairs(nodes) do
local pos = minetest.string_to_pos(k)
local node = minetest.get_node(pos)
local groups = minetest.registered_nodes[node.name] and
minetest.registered_nodes[node.name].groups
local texture
if groups.axe then
texture = "axe.png"
elseif groups.shovel then
texture = "shovel.png"
elseif groups.pickaxe then
texture = "pickaxe.png"
elseif groups.hand then
texture = "wieldhand.png"
end
--FIXME leaves somehow don't work?
if texture and vector.distance(pos, digger:get_pos()) < 8 and
node.name ~= "nodes:snow_ledge" then
for _, v in ipairs(off) do
minetest.add_particle({
pos = vector.add(pos, v),
expirationtime = 8,
size = 3,
texture = texture,
playername = name,
glow = 13,
})
end
end
if node.name == "nodes:placeholder" then
local meta = minetest.get_meta(pos)
local placeable = meta:get_string("placeable")
if placeable ~= "" then
local nodelist = minetest.parse_json(placeable)
--FIXME just do the first placeholder, only
local n, _ = next(nodelist)
minetest.add_particle({
pos = pos,
expirationtime = 8,
size = 3,
texture = nodes.get_tiles(n),
glow = 14,
playername = name,
})
end
end
end
return itemstack
end,
})
frame.register("tools:reveal")