1172 lines
41 KiB
Lua
Raw Normal View History

2016-10-25 15:31:25 +02:00
-- Boilerplate to support localized strings if intllib mod is installed.
2016-10-26 20:27:04 +02:00
local S
2016-10-25 15:31:25 +02:00
if minetest.get_modpath("intllib") then
dofile(minetest.get_modpath("intllib").."/intllib.lua")
S = intllib.Getter(minetest.get_current_modname())
else
S = function(s) return s end
end
2016-08-02 16:27:01 +02:00
doc.sub.items = {}
2016-08-05 02:02:02 +02:00
-- Template texts
doc.sub.items.temp = {}
2016-10-25 15:31:25 +02:00
doc.sub.items.temp.deco = S("This is a decorational block.")
doc.sub.items.temp.build = S("This block is a building block for creating various buildings.")
doc.sub.items.temp.craftitem = S("This item is primarily used for crafting other items.")
2016-08-05 02:02:02 +02:00
2016-10-25 15:31:25 +02:00
doc.sub.items.temp.eat = S("Hold it in your hand, then leftclick to eat it.")
doc.sub.items.temp.eat_bad = S("Hold it in your hand, then leftclick to eat it. But why would you want to do this?")
2016-08-05 02:02:02 +02:00
2016-11-03 02:39:30 +01:00
doc.sub.items.settings = {}
doc.sub.items.settings.friendly_group_names = false
local setting = minetest.setting_getbool("doc_items_friendly_group_names")
if setting ~= nil then
doc.sub.items.settings.friendly_group_names = setting
end
2016-11-03 04:03:07 +01:00
setting = minetest.setting_getbool("doc_items_show_itemstrings")
if setting ~= nil then
doc.sub.items.settings.itemstring = setting
end
2016-11-03 02:39:30 +01:00
2016-08-05 02:02:02 +02:00
-- Local stuff
2016-08-02 15:55:05 +02:00
local groupdefs = {}
2016-08-05 00:02:34 +02:00
local mininggroups = {}
2016-08-04 12:41:11 +02:00
local miscgroups = {}
2016-08-10 07:47:39 +02:00
-- List of forcefully added (true) and hidden (false) items
2016-08-03 15:03:38 +02:00
local forced_items = {
["ignore"] = false
2016-08-03 15:03:38 +02:00
}
local hidden_items = {}
2016-08-03 15:03:38 +02:00
local item_name_overrides = {
2016-10-25 15:31:25 +02:00
[""] = S("Hand"),
["air"] = S("Air")
2016-08-03 15:03:38 +02:00
}
2016-08-05 02:02:02 +02:00
-- Helper functions
2016-08-05 02:43:12 +02:00
local yesno = function(bool)
2016-10-25 15:31:25 +02:00
if bool==true then return S("Yes")
elseif bool==false then return S("No")
2016-08-05 02:43:12 +02:00
else return "N/A" end
end
2016-08-04 12:41:11 +02:00
local groups_to_string = function(grouptable, filter)
2015-05-16 22:57:51 +02:00
local gstring = ""
2016-07-31 23:58:58 +02:00
local groups_count = 0
2015-05-16 22:57:51 +02:00
for id, value in pairs(grouptable) do
2016-08-04 12:41:11 +02:00
if groupdefs[id] ~= nil and (filter == nil or filter[id] == true) then
2016-08-03 22:12:43 +02:00
-- Readable group name
2016-07-31 23:58:58 +02:00
if groups_count > 0 then
2016-10-26 20:27:04 +02:00
-- List seperator
gstring = gstring .. S(", ")
2016-07-31 23:58:58 +02:00
end
2016-11-03 02:39:30 +01:00
if groupdefs[id] ~= nil and doc.sub.items.settings.friendly_group_names == true then
gstring = gstring .. groupdefs[id]
else
gstring = gstring .. id
end
2016-08-03 22:12:43 +02:00
groups_count = groups_count + 1
2015-05-16 22:57:51 +02:00
end
end
2016-07-31 23:58:58 +02:00
if groups_count == 0 then
2016-08-03 22:12:43 +02:00
return nil, 0
2016-07-31 23:58:58 +02:00
else
return gstring, groups_count
end
2015-05-16 22:57:51 +02:00
end
-- Replaces all newlines with spaces
local scrub_newlines = function(text)
local new, x = string.gsub(text, "\n", " ")
return new
end
2016-10-07 17:41:41 +02:00
--[[ Append a newline to text, unless it already ends with a newline. ]]
local newline = function(text)
if string.sub(text, #text, #text) == "\n" then
return text
else
return text .. "\n"
end
end
--[[ Make sure the text ends with two newlines by appending any missing newlines at the end, if neccessary. ]]
local newline2 = function(text)
if string.sub(text, #text-1, #text) == "\n\n" then
return text
elseif string.sub(text, #text, #text) == "\n" then
return text .. "\n"
else
return text .. "\n\n"
end
end
-- Extract suitable item description for formspec
local description_for_formspec = function(itemstring)
local description = minetest.registered_items[itemstring].description
if description == nil or description == "" then
return minetest.formspec_escape(itemstring)
else
return minetest.formspec_escape(scrub_newlines(description))
end
end
2016-11-03 03:21:47 +01:00
doc.sub.items.get_group_name = function(groupname)
2016-11-03 02:39:30 +01:00
if groupdefs[groupname] ~= nil and doc.sub.items.settings.friendly_group_names == true then
2016-08-05 05:01:58 +02:00
return groupdefs[groupname]
else
return groupname
end
2016-08-01 04:31:53 +02:00
end
2016-07-19 17:45:46 +02:00
local burntime_to_text = function(burntime)
if burntime == nil then
2016-10-25 15:31:25 +02:00
return S("unknown")
2016-07-19 17:45:46 +02:00
elseif burntime == 1 then
2016-10-25 15:31:25 +02:00
return S("1 second")
2016-07-19 17:45:46 +02:00
else
2016-10-25 15:31:25 +02:00
return string.format(S("%d seconds"), burntime)
2016-07-19 17:45:46 +02:00
end
end
2016-08-01 04:31:53 +02:00
local toolcaps_to_text = function(tool_capabilities)
local formstring = ""
if tool_capabilities ~= nil and tool_capabilities ~= {} then
local punch = 1.0
if tool_capabilities.full_punch_interval ~= nil then
punch = tool_capabilities.full_punch_interval
end
2016-10-27 03:16:14 +02:00
formstring = formstring .. string.format(S("Full punch interval: %.1f s"), punch)
2016-10-25 15:31:25 +02:00
formstring = formstring .. "\n\n"
2016-08-01 04:31:53 +02:00
local groupcaps = tool_capabilities.groupcaps
if groupcaps ~= nil then
2016-10-25 15:31:25 +02:00
formstring = formstring .. S("This tool is capable of mining.\nMining capabilities:\n")
2016-08-01 04:31:53 +02:00
for k,v in pairs(groupcaps) do
2016-08-01 06:44:38 +02:00
local minrating, maxrating
for rating, time in pairs(v.times) do
if minrating == nil then minrating = rating else
if minrating > rating then minrating = rating end
end
if maxrating == nil then maxrating = rating else
if maxrating < rating then maxrating = rating end
end
2016-08-01 06:17:59 +02:00
end
2016-08-01 06:44:38 +02:00
local ratingstring = "Unknown rating"
if minrating ~= nil and maxrating ~= nil then
if minrating == maxrating then
2016-10-25 15:31:25 +02:00
ratingstring = string.format(S("Rating %d"), minrating)
2016-08-01 06:44:38 +02:00
else
2016-10-25 15:31:25 +02:00
ratingstring = string.format(S("Rating %d-%d"), minrating, maxrating)
2016-08-01 06:44:38 +02:00
end
end
local levelstring
if v.maxlevel == 0 then
2016-10-25 15:31:25 +02:00
levelstring = S("level 0")
2016-08-01 06:44:38 +02:00
elseif v.maxlevel ~= nil then
2016-10-25 15:31:25 +02:00
levelstring = string.format(S("level 0-%d"), v.maxlevel)
2016-08-01 06:44:38 +02:00
else
2016-10-25 15:31:25 +02:00
levelstring = S("any level")
2016-08-01 06:44:38 +02:00
end
2016-11-03 03:21:47 +01:00
formstring = formstring .. string.format(S("• %s: %s, %s"), doc.sub.items.get_group_name(k), ratingstring, levelstring)
2016-10-25 15:31:25 +02:00
formstring = formstring .. "\n"
2016-08-01 04:31:53 +02:00
end
end
2016-10-07 17:41:41 +02:00
formstring = newline2(formstring)
2016-08-01 04:31:53 +02:00
local damage_groups = tool_capabilities.damage_groups
if damage_groups ~= nil then
2016-10-25 15:31:25 +02:00
formstring = formstring .. S("This is a melee weapon which deals damage by punching.\nMaximum damage per hit:\n")
2016-08-01 04:31:53 +02:00
for k,v in pairs(damage_groups) do
2016-11-03 03:21:47 +01:00
formstring = formstring .. string.format(S("• %s: %d HP"), doc.sub.items.get_group_name(k), v)
2016-10-25 15:31:25 +02:00
formstring = formstring .. "\n"
2016-08-01 04:31:53 +02:00
end
end
end
return formstring
end
2016-08-05 02:41:16 +02:00
local range_factoid = function(itemstring, def)
local handrange = minetest.registered_items[""].range
local itemrange = def.range
if itemstring == "" then
if handrange ~= nil then
2016-10-25 15:31:25 +02:00
return string.format(S("Range: %d"), itemrange)
2016-08-05 02:41:16 +02:00
else
2016-10-25 15:31:25 +02:00
return S("Range: 4")
2016-08-05 02:41:16 +02:00
end
else
if handrange == nil then handrange = 4 end
if itemrange ~= nil then
2016-10-25 15:31:25 +02:00
return string.format(S("Range: %d"), itemrange)
2016-08-05 02:41:16 +02:00
else
2016-10-25 15:31:25 +02:00
return string.format(S("Range: %s (%d)"), item_name_overrides[""], handrange)
2016-08-05 02:41:16 +02:00
end
end
end
-- Smelting fuel factoid
local fuel_factoid = function(itemstring, ctype)
local formstring = ""
local result, decremented = minetest.get_craft_result({method = "fuel", items = {itemstring}})
if result ~= nil and result.time > 0 then
local base
if ctype == "tools" then
2016-10-25 15:31:25 +02:00
base = S("This tool can serve as a smelting fuel with a burning time of %s.")
elseif ctype == "nodes" then
2016-10-25 15:31:25 +02:00
base = S("This block can serve as a smelting fuel with a burning time of %s.")
else
2016-10-25 15:31:25 +02:00
base = S("This item can serve as a smelting fuel with a burning time of %s.")
end
formstring = formstring .. string.format(base, burntime_to_text(result.time))
local replaced = decremented.items[1]:get_name()
if not decremented.items[1]:is_empty() and replaced ~= itemstring then
2016-10-25 15:31:25 +02:00
formstring = formstring .. string.format(S(" Using it as fuel turns it into: %s."), description_for_formspec(replaced))
end
2016-10-07 17:41:41 +02:00
formstring = newline(formstring)
end
return formstring
end
2016-08-05 02:02:02 +02:00
-- For factoids
2016-08-02 16:27:01 +02:00
local factoid_generators = {}
factoid_generators.nodes = {}
factoid_generators.tools = {}
factoid_generators.craftitems = {}
function doc.sub.items.register_factoid(category_id, factoid_type, factoid_generator)
local ftable = { fgen = factoid_generator, ftype = factoid_type }
if category_id == "nodes" then
table.insert(factoid_generators.nodes, ftable)
return true
elseif category_id == "tools" then
table.insert(factoid_generators.tools, ftable)
return true
elseif category_id == "craftitems" then
table.insert(factoid_generators.craftitems, ftable)
return true
else
return false
end
end
2016-08-01 04:31:53 +02:00
2015-05-16 22:57:51 +02:00
doc.new_category("nodes", {
2016-09-01 14:29:46 +02:00
hide_entries_by_default = true,
2016-10-25 15:31:25 +02:00
name = S("Blocks"),
description = S("Item reference of blocks and other things which are capable of occupying space"),
2015-05-16 22:57:51 +02:00
build_formspec = function(data)
if data then
local longdesc = data.longdesc
local usagehelp = data.usagehelp
local formstring = ""
if data.itemstring ~= "air" then
if data.image ~= nil then
2016-11-07 21:30:48 +01:00
formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.image.."]"
else
2016-11-07 21:30:48 +01:00
formstring = formstring .. "item_image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.itemstring.."]"
end
end
2016-10-09 03:03:50 +02:00
local datastring = ""
if longdesc ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Description: %s"), longdesc) .."\n\n"
end
if usagehelp ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Usage help: %s"), usagehelp) .. "\n\n"
end
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Maximum stack size: %d"), data.def.stack_max) .. "\n"
2015-05-16 22:57:51 +02:00
2016-10-09 03:03:50 +02:00
datastring = datastring .. range_factoid(data.itemstring, data.def) .. "\n"
2016-08-05 02:41:16 +02:00
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-10-07 17:41:41 +02:00
2016-08-05 03:21:52 +02:00
if data.def.liquids_pointable == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block points to liquids.")).. "\n"
2016-08-05 03:21:52 +02:00
end
2016-08-05 04:15:06 +02:00
if data.def.on_use ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.")) .. "\n"
2016-08-05 04:15:06 +02:00
end
2016-08-05 03:21:52 +02:00
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-08-05 02:41:16 +02:00
2016-10-09 03:03:50 +02:00
datastring = datastring .. toolcaps_to_text(data.def.tool_capabilities)
2016-08-05 02:41:16 +02:00
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Collidable: %s"), yesno(data.def.walkable)) .. "\n"
2016-08-05 04:56:25 +02:00
local liquid
if data.def.liquidtype ~= "none" then liquid = true else liquid = false end
2016-08-05 04:47:38 +02:00
if data.def.pointable == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Pointable: Yes") .. "\n"
2016-08-05 04:47:38 +02:00
elseif liquid then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Pointable: Only by special items") .. "\n"
2016-08-05 04:47:38 +02:00
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Pointable: No") .. "\n"
2016-08-05 04:47:38 +02:00
end
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2015-05-16 22:57:51 +02:00
if liquid then
2016-10-09 03:03:50 +02:00
datastring = newline(datastring, false)
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is a liquid with these properties:") .. "\n"
2015-05-16 22:57:51 +02:00
local range, renew, viscos
if data.def.liquid_range then range = data.def.liquid_range else range = 8 end
2016-07-19 17:25:24 +02:00
if data.def.liquid_renewable ~= nil then renew = data.def.liquid_renewable else renew = true end
2016-08-03 23:39:14 +02:00
if data.def.liquid_viscosity then viscos = data.def.liquid_viscosity else viscos = 0 end
if renew then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("• Renewable") .. "\n"
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("• Not renewable") .. "\n"
end
2016-08-05 04:47:38 +02:00
if range == 0 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("• No flowing") .. "\n"
2016-08-05 04:47:38 +02:00
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("• Flowing range: %d"), range) .. "\n"
2016-08-05 04:47:38 +02:00
end
2016-10-27 03:19:45 +02:00
datastring = datastring .. string.format(S("• Viscosity: %d"), viscos) .. "\n"
2016-08-05 02:10:22 +02:00
end
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2015-05-16 22:57:51 +02:00
-- Global factoids
--- Direct interaction with the player
---- Damage (very important)
2016-10-27 03:19:45 +02:00
if data.def.damage_per_second ~= nil and data.def.damage_per_second > 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block causes a damage of %d hit points per second."), data.def.damage_per_second) .. "\n"
elseif data.def.damage_per_second == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block causes a damage of %d hit point per second."), data.def.damage_per_second) .. "\n"
end
if data.def.drowning > 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block decreases your breath and causes a drowning damage of %d hit points every 2 seconds."), data.def.drowning) .. "\n"
elseif data.def.drowning == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block decreases your breath and causes a drowning damage of %d hit point every 2 seconds."), data.def.drowning) .. "\n"
end
local fdap = data.def.groups.fall_damage_add_percent
if fdap ~= nil then
if fdap > 0 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("The fall damage on this block is increased by %d%%."), fdap) .. "\n"
2016-10-10 00:01:49 +02:00
elseif fdap <= -100 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block negates all fall damage.") .. "\n"
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("The fall damage on this block is reduced by %d%%"), math.abs(fdap)) .. "\n"
end
end
---- Movement
if data.def.groups.disable_jump == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("You can not jump while standing on this block.").."\n"
end
if data.def.climbable == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block can be climbed.").."\n"
end
local bouncy = data.def.groups.bouncy
if bouncy ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block will make you bounce off with an elasticity of %d%%"), bouncy).."\n"
end
---- Sounds
local function is_silent(def, soundtype)
return def.sounds == nil or def.sounds[soundtype] == nil or def.sounds[soundtype] == "" or (type(data.def.sounds[soundtype]) == "table" and (data.def.sounds[soundtype].name == nil or data.def.sounds[soundtype].name == ""))
end
local silentstep, silentdig, silentplace = false, false, false
if data.def.walkable and is_silent(data.def, "footstep") then
silentstep = true
end
if data.def.diggable and is_silent(data.def, "dig") and is_silent(data.def, "dug") then
silentdig = true
end
if is_silent(data.def, "place") and data.itemstring ~= "air" then
silentplace = true
end
if silentstep and silentdig and silentplace then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is completely silent when walked on, mined or built.").."\n"
elseif silentdig and silentplace then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is completely silent when mined or built.").."\n"
else
if silentstep then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Walking on this block is completely silent.").."\n"
end
if silentdig then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Mining this block is completely silent.").."\n"
end
if silentplace then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Building this block is completely silent.").."\n"
end
end
-- Block activity
--- Gravity
if data.def.groups.falling_node == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is affected by gravity and can fall.").."\n"
end
--- Dropping and destruction
2015-05-16 22:57:51 +02:00
if data.def.buildable_to == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Building another block at this block will place it inside and replace it.").."\n"
if data.def.walkable then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Falling blocks can go through this block; they destroy it when doing so.").."\n"
end
end
if data.def.walkable == false then
2016-11-03 03:23:00 +01:00
if data.def.buildable_to == false and data.def.drop ~= "" then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block will drop as an item when a falling block ends up inside it.").."\n"
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is destroyed when a falling block ends up inside it.").."\n"
end
2015-05-16 22:57:51 +02:00
end
if data.def.groups.attached_node == 1 then
if data.def.paramtype2 == "wallmounted" then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block will drop as an item when it is not attached to a surrounding block.").."\n"
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block will drop as an item when no collidable block is below it.").."\n"
end
end
if data.def.floodable == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Liquids can flow into this block and destroy it.").."\n"
end
-- Block appearance
--- Light
if data.def.light_source == 15 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is an extremely bright light source. It glows as bright the sun.").."\n"
elseif data.def.light_source == 14 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is a very bright light source.").."\n"
elseif data.def.light_source > 12 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is a bright light source.").."\n"
elseif data.def.light_source > 5 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is a light source of medium luminance.").."\n"
elseif data.def.light_source > 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block is a weak light source and glows faintly.").."\n"
elseif data.def.light_source == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block glows faintly. It is barely noticable.").."\n"
end
if data.def.paramtype == "light" and data.def.sunlight_propagates then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly.").."\n"
elseif data.def.paramtype == "light" then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block allows light to propagate with a small loss of brightness.").."\n"
elseif data.def.sunlight_propagates then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block allows sunlight to propagate without loss in brightness.").."\n"
end
--- List nodes/groups to which this node connects to
2016-08-03 22:12:43 +02:00
if data.def.connects_to ~= nil then
local nodes = {}
local groups = {}
for c=1,#data.def.connects_to do
local itemstring = data.def.connects_to[c]
if string.sub(itemstring,1,6) == "group:" then
groups[string.sub(itemstring,7,#itemstring)] = 1
else
table.insert(nodes, itemstring)
end
end
local nstring = ""
for n=1,#nodes do
local name
if item_name_overrides[nodes[n]] ~= nil then
name = item_name_overrides[nodes[n]]
else
name = description_for_formspec(minetest.registered_nodes[nodes[n]])
2016-08-03 22:12:43 +02:00
end
if n > 1 then
2016-10-26 20:27:04 +02:00
nstring = nstring .. S(", ")
2016-08-03 22:12:43 +02:00
end
if name ~= nil then
nstring = nstring .. name
else
2016-10-25 15:31:25 +02:00
nstring = nstring .. S("Unknown Node")
2016-08-03 22:12:43 +02:00
end
end
if #nodes == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block connects to this block: %s."), nstring) .. "\n"
2016-08-03 22:12:43 +02:00
elseif #nodes > 1 then
2016-10-27 03:16:14 +02:00
datastring = datastring .. string.format(S("This block connects to these blocks: %s."), nstring) .. "\n"
2016-08-03 22:12:43 +02:00
end
2016-08-04 12:41:11 +02:00
local gstring, gcount = groups_to_string(groups)
2016-08-03 22:12:43 +02:00
if gcount == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block connects to blocks of the %s group."), gstring) .. "\n"
2016-08-03 22:12:43 +02:00
elseif gcount > 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This block connects to blocks of the following groups: %s."), gstring) .. "\n"
2016-08-03 22:12:43 +02:00
end
end
2015-05-16 22:57:51 +02:00
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2015-05-16 22:57:51 +02:00
-- Mining groups
if data.def.pointable ~= false and (data.def.liquid_type == "none" or data.def.liquid_type == nil) then
-- Check if there are no mining groups at all
local nogroups = true
for groupname,_ in pairs(mininggroups) do
if data.def.groups[groupname] ~= nil or groupname == "dig_immediate" then
nogroups = false
break
2016-08-05 00:33:08 +02:00
end
end
-- dig_immediate
if data.def.drop ~= "" then
if data.def.groups.dig_immediate == 2 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block can be mined by any mining tool in half a second.").."\n"
elseif data.def.groups.dig_immediate == 3 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block can be mined by any mining tool immediately.").."\n"
-- Note: “unbreakable” is an unofficial group for undiggable blocks
elseif data.def.diggable == false or nogroups or data.def.groups.immortal == 1 or data.def.groups.unbreakable == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block can not be mined by ordinary mining tools.").."\n"
end
2016-08-05 00:33:08 +02:00
else
if data.def.groups.dig_immediate == 2 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block can be destroyed by any mining tool in half a second.").."\n"
elseif data.def.groups.dig_immediate == 3 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block can be destroyed by any mining tool immediately.").."\n"
elseif data.def.diggable == false or nogroups or data.def.groups.immortal == 1 or data.def.groups.unbreakable == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block can not be destroyed by ordinary mining tools.").."\n"
end
2016-08-05 00:33:08 +02:00
end
-- Expose “ordinary” mining groups (crumbly, cracky, etc.) and level group
-- Skip this for immediate digging to avoid redundancy
if data.def.groups.dig_immediate ~= 3 then
2016-10-25 15:31:25 +02:00
local mstring = S("This block can be mined by mining tools which match any of the following mining ratings and its mining level.").."\n"
mstring = mstring .. S("Mining ratings:").."\n"
local minegroupcount = 0
for group,_ in pairs(mininggroups) do
local rating = data.def.groups[group]
if rating ~= nil then
2016-11-03 03:21:47 +01:00
mstring = mstring .. string.format(S("• %s: %d"), doc.sub.items.get_group_name(group), rating).."\n"
minegroupcount = minegroupcount + 1
end
end
if data.def.groups.level ~= nil then
2016-10-25 15:31:25 +02:00
mstring = mstring .. string.format(S("Mining level: %d"), data.def.groups.level).."\n"
else
2016-10-25 15:31:25 +02:00
mstring = mstring .. S("Mining level: 0").."\n"
end
2016-08-01 07:12:43 +02:00
if minegroupcount > 0 then
2016-10-09 03:03:50 +02:00
datastring = datastring .. mstring
end
2016-08-05 00:33:08 +02:00
end
2016-08-01 07:12:43 +02:00
end
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-08-01 07:12:43 +02:00
2016-08-02 16:27:01 +02:00
-- Custom factoids are inserted here
for i=1,#factoid_generators.nodes do
2016-10-09 03:03:50 +02:00
datastring = datastring .. factoid_generators.nodes[i].fgen(data.itemstring, data.def)
datastring = newline(datastring)
2016-08-02 16:27:01 +02:00
end
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-07-19 22:21:08 +02:00
2016-08-01 07:12:43 +02:00
-- Show other “exposable” groups in quick list
2016-08-04 12:41:11 +02:00
local gstring, gcount = groups_to_string(data.def.groups, miscgroups)
2015-05-16 22:57:51 +02:00
if gstring ~= nil then
2016-07-31 23:58:58 +02:00
if gcount == 1 then
2016-10-26 20:27:04 +02:00
datastring = datastring .. string.format(S("This block belongs to the %s group."), gstring) .. "\n"
2016-07-31 23:58:58 +02:00
else
2016-10-26 20:27:04 +02:00
datastring = datastring .. string.format(S("This block belongs to these groups: %s."), gstring) .. "\n"
2016-07-31 23:58:58 +02:00
end
2016-07-19 17:45:46 +02:00
end
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-07-19 17:45:46 +02:00
2016-08-01 02:23:08 +02:00
-- Non-default drops
if data.def.drop ~= nil and data.def.drop ~= data.itemstring and data.itemstring ~= "air" then
2016-08-25 22:44:42 +02:00
-- TODO: Calculate drop probabilities of max > 1 like for max == 1
2016-08-01 02:23:08 +02:00
local get_desc = function(stack)
return description_for_formspec(stack:get_name())
2016-08-01 02:23:08 +02:00
end
if data.def.drop == "" then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This block won't drop anything when mined.").."\n"
2016-08-01 02:23:08 +02:00
elseif type(data.def.drop) == "string" then
local dropstack = ItemStack(data.def.drop)
if dropstack:get_name() ~= data.itemstring and dropstack:get_name() ~= 1 then
2016-08-01 02:23:08 +02:00
local desc = get_desc(dropstack)
local count = dropstack:get_count()
if count > 1 then
2016-10-26 20:27:04 +02:00
datastring = datastring .. string.format(S("This block will drop the following when mined: %d×%s."), count, desc).."\n"
2016-08-01 02:23:08 +02:00
else
2016-10-26 20:27:04 +02:00
datastring = datastring .. string.format(S("This block will drop the following when mined: %s."), desc).."\n"
2016-08-01 02:23:08 +02:00
end
end
2016-08-03 02:12:37 +02:00
elseif type(data.def.drop) == "table" and data.def.drop.items ~= nil then
2016-08-01 02:23:08 +02:00
local max = data.def.drop.max_items
2016-10-26 20:27:04 +02:00
local dropstring = ""
local dropstring_base = ""
2016-08-01 02:23:08 +02:00
if max == nil then
2016-10-26 20:27:04 +02:00
dropstring_base = S("This block will drop the following items when mined: %s.")
2016-08-01 02:23:08 +02:00
elseif max == 1 then
if #data.def.drop.items == 1 then
2016-10-26 20:27:04 +02:00
dropstring_base = S("This block will drop the following when mined: %s.")
else
2016-10-26 20:27:04 +02:00
dropstring_base = S("This block will randomly drop one of the following when mined: %s.")
end
2016-08-01 02:23:08 +02:00
else
2016-10-26 20:27:04 +02:00
dropstring_base = S("This block will randomly drop up to %d drops of the following possible drops when mined: %s.")
2016-08-01 02:23:08 +02:00
end
-- Save calculated probabilities into a table for later output
local probtables = {}
local probtable
local rarity_history = {}
2016-08-01 02:23:08 +02:00
for i=1,#data.def.drop.items do
local local_rarity = data.def.drop.items[i].rarity
local chance = 1
local rarity = 1
if local_rarity == nil then
local_rarity = 1
end
if max == 1 then
-- Chained probability
table.insert(rarity_history, local_rarity)
chance = 1
for r=1, #rarity_history do
local chance_factor
if r > 1 and rarity_history[r-1] == 1 then
chance = 0
break
end
if r == #rarity_history then
chance_factor = 1/rarity_history[r]
else
chance_factor = (rarity_history[r]-1)/rarity_history[r]
end
chance = chance * chance_factor
end
if chance > 0 then
rarity = 1/chance
end
else
rarity = local_rarity
chance = 1/rarity
2016-08-01 02:38:34 +02:00
end
-- Exclude impossible drops
if chance > 0 then
probtable = {}
probtable.items = {}
for j=1,#data.def.drop.items[i].items do
local dropstack = ItemStack(data.def.drop.items[i].items[j])
local itemstring = dropstack:get_name()
local desc = get_desc(dropstack)
local count = dropstack:get_count()
if not(itemstring == nil or itemstring == "" or count == 0) then
if probtable.items[itemstring] == nil then
probtable.items[itemstring] = {desc = desc, count = count}
else
probtable.items[itemstring].count = probtable.items[itemstring].count + count
end
end
end
probtable.rarity = rarity
if #data.def.drop.items[i].items > 0 then
table.insert(probtables, probtable)
end
2016-08-01 02:23:08 +02:00
end
end
-- Do some cleanup of the probability table
if max == 1 or max == nil then
-- Sort by rarity
local comp = function(p1, p2)
return p1.rarity < p2.rarity
end
table.sort(probtables, comp)
2016-08-01 02:23:08 +02:00
end
-- Output probability table
local pcount = 0
for i=1, #probtables do
if pcount > 0 then
2016-10-26 20:27:04 +02:00
-- List seperator
dropstring = dropstring .. S(", ")
end
local probtable = probtables[i]
local icount = 0
2016-10-26 20:27:04 +02:00
local dropstring_this = ""
for _, itemtable in pairs(probtable.items) do
if icount > 0 then
2016-10-26 20:27:04 +02:00
-- Final list seperator
dropstring_this = dropstring_this .. S(" and ")
end
2016-10-26 20:27:04 +02:00
local desc = S(itemtable.desc)
local count = itemtable.count
if count ~= 1 then
2016-10-26 20:27:04 +02:00
desc = string.format(S("%d×%s"), count, desc)
end
2016-10-26 20:27:04 +02:00
dropstring_this = dropstring_this .. desc
icount = icount + 1
end
local rarity = probtable.rarity
2016-10-26 20:27:04 +02:00
local raritystring = ""
-- No percentage if there's only one possible guaranteed drop
if not(rarity == 1 and #data.def.drop.items == 1) then
local chance = (1/rarity)*100
if rarity > 200 then -- <0.5%
-- For very low percentages
2016-10-26 20:27:04 +02:00
dropstring_this = string.format(S("%s (<0.5%)"), dropstring_this)
else
-- Add circa indicator for percentages with decimal point
-- FIXME: Is this check actually reliable?
if math.fmod(chance, 1) > 0 then
2016-10-26 20:27:04 +02:00
dropstring_this = string.format(S("%s (ca. %.0f%%)"), dropstring_this, chance)
else
dropstring_this = string.format(S("%s (%.0f%%)"), dropstring_this, chance)
end
end
end
2016-10-26 20:27:04 +02:00
dropstring = dropstring .. dropstring_this
pcount = pcount + 1
end
2016-10-26 20:27:04 +02:00
if max ~= nil and max > 1 then
datastring = datastring .. string.format(dropstring_base, max, dropstring)
else
datastring = datastring .. string.format(dropstring_base, dropstring)
end
2016-10-09 03:03:50 +02:00
datastring = newline(datastring)
2016-08-01 02:23:08 +02:00
end
end
2016-07-31 23:58:58 +02:00
2016-07-19 17:45:46 +02:00
-- Show fuel recipe
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
datastring = datastring .. fuel_factoid(data.itemstring, "nodes")
2016-07-19 17:45:46 +02:00
if doc.sub.items.settings.itemstring == true then
2016-11-03 04:03:07 +01:00
datastring = newline2(datastring)
datastring = datastring .. string.format(S("Itemstring: \"%s\""), data.itemstring)
end
2016-11-07 21:30:48 +01:00
formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2)
2015-05-16 22:57:51 +02:00
return formstring
else
2016-11-03 03:50:21 +01:00
return "label[0,1;NO DATA AVALIABLE!]"
2015-05-16 22:57:51 +02:00
end
end
})
doc.new_category("tools", {
2016-09-01 14:29:46 +02:00
hide_entries_by_default = true,
2016-10-25 15:31:25 +02:00
name = S("Tools and weapons"),
description = S("Item reference of all wieldable tools and weapons"),
build_formspec = function(data)
if data then
2016-08-01 04:46:43 +02:00
local longdesc = data.longdesc
local usagehelp = data.usagehelp
2016-07-24 16:32:49 +02:00
local formstring = ""
2016-07-24 18:50:30 +02:00
-- Hand
if data.itemstring == "" then
2016-11-07 21:30:48 +01:00
formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..
minetest.registered_items[""].wield_image.."]"
2016-07-24 18:50:30 +02:00
-- Other tools
elseif data.image ~= nil then
2016-11-07 21:30:48 +01:00
formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.image.."]"
2016-07-24 16:32:49 +02:00
else
2016-11-07 21:30:48 +01:00
formstring = formstring .. "item_image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.itemstring.."]"
2016-07-24 16:32:49 +02:00
end
2016-10-09 03:03:50 +02:00
local datastring = ""
2016-08-01 04:46:43 +02:00
if longdesc ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Description: %s"), longdesc)
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-08-01 04:46:43 +02:00
end
if usagehelp ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Usage help: %s"), usagehelp)
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-08-01 04:46:43 +02:00
end
2016-08-01 04:52:56 +02:00
if data.itemstring ~= "" then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Maximum stack size: %d"), data.def.stack_max).. "\n"
2016-08-01 04:52:56 +02:00
end
2016-10-09 03:03:50 +02:00
datastring = datastring .. range_factoid(data.itemstring, data.def) .. "\n"
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-10-07 17:41:41 +02:00
2016-08-05 03:21:52 +02:00
if data.def.liquids_pointable == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This tool points to liquids.").."\n"
2016-08-05 03:21:52 +02:00
end
2016-08-05 04:15:06 +02:00
if data.def.on_use ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently.").."\n"
2016-08-05 04:15:06 +02:00
end
2016-08-05 03:21:52 +02:00
2016-10-09 03:03:50 +02:00
datastring = newline(datastring)
2016-10-09 03:03:50 +02:00
datastring = datastring .. toolcaps_to_text(data.def.tool_capabilities)
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-10-07 17:41:41 +02:00
2016-07-31 23:58:58 +02:00
-- Show other “exposable” groups
2016-08-04 12:41:11 +02:00
local gstring, gcount = groups_to_string(data.def.groups, miscgroups)
2016-07-31 23:58:58 +02:00
if gstring ~= nil then
if gcount == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This tool belongs to the %s group."), gstring).."\n"
2016-07-31 23:58:58 +02:00
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This tool belongs to these groups: %s."), gstring).."\n"
2016-07-31 23:58:58 +02:00
end
end
2016-07-19 17:45:46 +02:00
-- Show fuel recipe
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
datastring = datastring .. fuel_factoid(data.itemstring, "tools")
2016-07-19 17:45:46 +02:00
if doc.sub.items.settings.itemstring == true then
2016-11-03 04:03:07 +01:00
datastring = newline2(datastring)
datastring = datastring .. string.format(S("Itemstring: \"%s\""), data.itemstring)
end
2016-11-07 21:30:48 +01:00
formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2)
return formstring
else
2016-11-03 03:50:21 +01:00
return "label[0,1;NO DATA AVALIABLE!]"
end
end
})
doc.new_category("craftitems", {
2016-09-01 14:29:46 +02:00
hide_entries_by_default = true,
2016-10-25 15:31:25 +02:00
name = S("Miscellaneous items"),
description = S("Item reference of items which are neither blocks, tools or weapons (esp. crafting items)"),
build_formspec = function(data)
if data then
2016-08-01 04:46:43 +02:00
local longdesc = data.longdesc
local usagehelp = data.usagehelp
2016-08-16 18:01:33 +02:00
local formstring = ""
if data.image ~= nil then
2016-11-07 21:30:48 +01:00
formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.image.."]"
else
2016-11-07 21:30:48 +01:00
formstring = formstring .. "item_image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.itemstring.."]"
end
2016-10-09 03:03:50 +02:00
local datastring = ""
2016-08-01 04:46:43 +02:00
if longdesc ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Description: %s"), longdesc).."\n\n"
2016-08-01 04:46:43 +02:00
end
if usagehelp ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Usage help: %s"), usagehelp).. "\n\n"
2016-08-01 04:46:43 +02:00
end
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("Maximum stack size: %d"), data.def.stack_max).. "\n"
2016-10-09 03:03:50 +02:00
datastring = datastring .. range_factoid(data.itemstring, data.def) .. "\n"
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-10-07 17:41:41 +02:00
2016-08-05 03:21:52 +02:00
if data.def.liquids_pointable == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("This item points to liquids.").."\n"
2016-08-05 03:21:52 +02:00
end
2016-08-05 04:15:06 +02:00
if data.def.on_use ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S("Punches with this item don't work as usual; melee combat and mining are either not possible or work differently.").."\n"
2016-08-05 04:15:06 +02:00
end
2016-10-09 03:03:50 +02:00
datastring = newline(datastring)
2016-10-09 03:03:50 +02:00
datastring = datastring .. toolcaps_to_text(data.def.tool_capabilities)
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
2016-10-07 17:41:41 +02:00
2016-07-31 23:58:58 +02:00
-- Show other “exposable” groups
2016-08-04 12:41:11 +02:00
local gstring, gcount = groups_to_string(data.def.groups, miscgroups)
2016-07-31 23:58:58 +02:00
if gstring ~= nil then
if gcount == 1 then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This item belongs to the %s group."), gstring) .. "\n"
2016-07-31 23:58:58 +02:00
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format(S("This item belongs to these groups: %s."), gstring) .. "\n"
2016-07-31 23:58:58 +02:00
end
end
2016-07-19 17:45:46 +02:00
-- Show fuel recipe
2016-10-09 03:03:50 +02:00
datastring = newline2(datastring)
datastring = datastring .. fuel_factoid(data.itemstring, "craftitems")
2016-07-19 17:45:46 +02:00
if doc.sub.items.settings.itemstring == true then
2016-11-03 04:03:07 +01:00
datastring = newline2(datastring)
datastring = datastring .. string.format(S("Itemstring: \"%s\""), data.itemstring)
end
2016-11-07 21:30:48 +01:00
formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2)
return formstring
else
2016-11-03 03:50:21 +01:00
return "label[0,1;NO DATA AVALIABLE!]"
end
end
})
2016-08-02 15:35:40 +02:00
doc.sub.items.help = {}
doc.sub.items.help.longdesc = {}
doc.sub.items.help.usagehelp = {}
doc.sub.items.help.image = {}
2016-08-03 15:34:15 +02:00
-- Sets the long description for a table of items
function doc.sub.items.set_items_longdesc(longdesc_table)
for k,v in pairs(longdesc_table) do
2016-08-02 15:35:40 +02:00
doc.sub.items.help.longdesc[k] = v
end
2016-08-03 15:34:15 +02:00
end
-- Sets the usage help texts for a table of items
function doc.sub.items.set_items_usagehelp(usagehelp_table)
for k,v in pairs(usagehelp_table) do
2016-08-02 15:35:40 +02:00
doc.sub.items.help.usagehelp[k] = v
end
end
function doc.sub.items.add_item_image_overrides(image_overrides)
for itemstring, new_image in pairs(image_overrides) do
doc.sub.items.help.image[itemstring] = new_image
end
end
2016-08-02 15:55:05 +02:00
-- Register group definition stuff
-- More (user-)friendly group names to replace the rather technical names
-- for better understanding
function doc.sub.items.add_friendly_group_names(groupnames)
2016-08-02 15:55:05 +02:00
for internal, real in pairs(groupnames) do
groupdefs[internal] = real
end
end
2016-08-04 12:41:11 +02:00
-- Adds groups to be displayed in the generic “misc.” groups
-- factoid. Those groups should be neither be used as mining
-- groups nor as damage groups and should be relevant to the
-- player in someway.
function doc.sub.items.add_notable_groups(groupnames)
for g=1,#groupnames do
miscgroups[groupnames[g]] = true
2016-08-02 15:55:05 +02:00
end
end
2016-08-10 07:47:39 +02:00
-- Add items which will be forced to be added to the item list,
-- even if the item is not in creative inventory
function doc.sub.items.add_forced_item_entries(itemstrings)
for i=1,#itemstrings do
forced_items[itemstrings[i]] = true
2016-08-02 15:55:05 +02:00
end
end
2016-08-10 07:47:39 +02:00
-- Add items which will be forced *not* to be added to the item list
function doc.sub.items.add_suppressed_item_entries(itemstrings)
for i=1,#itemstrings do
forced_items[itemstrings[i]] = false
end
end
-- Add items which will be hidden from the entry list, but their entries
-- are still created.
function doc.sub.items.add_hidden_item_entries(itemstrings)
for i=1,#itemstrings do
hidden_items[itemstrings[i]] = true
end
end
2016-08-02 15:55:05 +02:00
-- Register a list of entry names where the entry name should differ
-- from the original item description
function doc.sub.items.add_item_name_overrides(itemstrings)
for internal, real in pairs(itemstrings) do
item_name_overrides[internal] = real
end
end
2015-05-16 22:57:51 +02:00
local function gather_descs()
2016-08-02 15:35:40 +02:00
local help = doc.sub.items.help
2016-08-03 15:03:38 +02:00
-- 1st pass
-- Gather all groups used for mining
for id, def in pairs(minetest.registered_items) do
if def.tool_capabilities ~= nil then
local groupcaps = def.tool_capabilities.groupcaps
if groupcaps ~= nil then
for k,v in pairs(groupcaps) do
if mininggroups[k] ~= true then
mininggroups[k] = true
end
end
end
end
end
-- 2nd pass: Add entries
2016-08-03 15:03:38 +02:00
-- Set default air text
-- Custom longdesc and usagehelp may be set by mods through the add_helptexts function
if help.longdesc["air"] == nil then
2016-10-25 15:31:25 +02:00
help.longdesc["air"] = S("A transparent block, basically empty space. It is usually left behind after digging something.")
2016-08-03 15:03:38 +02:00
end
2016-08-16 00:18:28 +02:00
local add_entries = function(deftable, category_id)
2016-10-30 20:35:16 +01:00
-- TODO: Remove legacy support: Groups in_doc, not_in_doc; forced_items, help table, etc.
2016-08-16 00:18:28 +02:00
for id, def in pairs(deftable) do
local name, ld, uh, im
2016-08-16 00:18:28 +02:00
local forced = false
2016-10-30 19:53:30 +01:00
if (forced_items[id] == true or def.groups.in_doc or def.x_doc_items_create_entry == true) and def ~= nil then forced = true end
2016-10-30 20:35:16 +01:00
if def.x_doc_items_entry_name ~= nil then
name = def.x_doc_items_entry_name
end
2016-08-16 00:18:28 +02:00
if item_name_overrides[id] ~= nil then
name = item_name_overrides[id]
2016-10-30 20:35:16 +01:00
end
if name == nil then
2016-08-16 00:18:28 +02:00
name = def.description
end
2016-10-30 20:35:16 +01:00
if not (((def.description == nil or def.description == "") and def.x_doc_items_entry_name == nil) or def.groups.not_in_doc or forced_items[id] == false or def.x_doc_items_create_entry == false) or forced then
2016-10-30 04:17:55 +01:00
if def.x_doc_items_longdesc then
ld = def.x_doc_items_longdesc
end
2016-08-16 00:18:28 +02:00
if help.longdesc[id] ~= nil then
ld = help.longdesc[id]
end
2016-10-30 04:17:55 +01:00
if def.x_doc_items_usagehelp then
uh = def.x_doc_items_usagehelp
end
2016-08-16 00:18:28 +02:00
if help.usagehelp[id] ~= nil then
uh = help.usagehelp[id]
end
2016-10-30 04:17:55 +01:00
if def.x_doc_items_image then
im = def.x_doc_items_image
end
if help.image[id] ~= nil then
im = help.image[id]
2016-08-16 00:18:28 +02:00
end
2016-09-01 14:29:46 +02:00
local hidden
if id == "air" then hidden = false end
2016-10-30 19:53:30 +01:00
if type(def.x_doc_items_hidden) == "boolean" then
hidden = def.x_doc_items_hidden
end
local custom_image
name = scrub_newlines(name)
2016-08-16 00:18:28 +02:00
local infotable = {
name = name,
2016-09-01 14:29:46 +02:00
hidden = hidden,
2016-08-16 00:18:28 +02:00
data = {
longdesc = ld,
usagehelp = uh,
image = im,
2016-08-16 00:18:28 +02:00
itemstring = id,
def = def,
}
2015-05-16 22:57:51 +02:00
}
2016-08-16 00:18:28 +02:00
doc.new_entry(category_id, id, infotable)
end
end
end
2016-08-16 00:18:28 +02:00
-- Add node entries
add_entries(minetest.registered_nodes, "nodes")
2016-08-03 15:03:38 +02:00
-- Add entry for the default tool (“hand”)
-- Custom longdesc and usagehelp may be set by mods through the add_helptexts function
if help.longdesc[""] == nil then
-- Default text
2016-10-25 15:31:25 +02:00
help.longdesc[""] = S("Whenever you are not wielding any item, you use the hand which acts as a tool with its own capabilities. When you are wielding an item which is not a mining tool or a weapon it will behave as if it would be the hand.")
2016-08-03 14:11:21 +02:00
end
2016-08-03 15:03:38 +02:00
doc.new_entry("tools", "", {
name = item_name_overrides[""],
2016-09-01 14:29:46 +02:00
hidden = false,
2016-08-03 15:03:38 +02:00
data = {
longdesc = help.longdesc[""],
usagehelp = help.usagehelp[""],
itemstring = "",
def = minetest.registered_items[""]
}
})
-- Add tool entries
2016-08-16 00:18:28 +02:00
add_entries(minetest.registered_tools, "tools")
2016-08-03 15:03:38 +02:00
-- Add craftitem entries
2016-08-16 00:18:28 +02:00
add_entries(minetest.registered_craftitems, "craftitems")
2015-05-16 22:57:51 +02:00
end
2016-09-01 14:29:46 +02:00
--[[ Reveal items as the player progresses through the game.
Items are revealed by:
* Digging, punching or placing node,
* Crafting
* Having item in inventory (not instantly revealed) ]]
local function reveal_item(playername, itemstring)
local category_id
if itemstring == nil or itemstring == "" or playername == nil or playername == "" then
return false
end
if minetest.registered_nodes[itemstring] ~= nil then
category_id = "nodes"
elseif minetest.registered_tools[itemstring] ~= nil then
category_id = "tools"
elseif minetest.registered_craftitems[itemstring] ~= nil then
category_id = "craftitems"
elseif minetest.registered_items[itemstring] ~= nil then
2016-09-01 14:29:46 +02:00
category_id = "craftitems"
else
return false
end
doc.mark_entry_as_revealed(playername, category_id, itemstring)
return true
end
2016-09-01 14:29:46 +02:00
local function reveal_items_in_inventory(player)
local inv = player:get_inventory()
local list = inv:get_list("main")
for l=1, #list do
reveal_item(player:get_player_name(), list[l]:get_name())
end
end
minetest.register_on_dignode(function(pos, oldnode, digger)
2016-10-24 16:26:34 +02:00
if digger == nil then return end
local playername = digger:get_player_name()
2016-10-24 16:26:34 +02:00
if playername ~= nil and playername ~= "" and oldnode ~= nil then
reveal_item(playername, oldnode.name)
2016-09-01 14:29:46 +02:00
reveal_items_in_inventory(digger)
end
end)
minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
2016-10-24 16:26:34 +02:00
if puncher == nil then return end
local playername = puncher:get_player_name()
if playername ~= nil and playername ~= "" and node ~= nil then
reveal_item(playername, node.name)
end
end)
2016-09-01 14:53:35 +02:00
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
2016-10-24 16:26:34 +02:00
if placer == nil then return end
local playername = placer:get_player_name()
2016-10-24 16:26:34 +02:00
if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then
reveal_item(playername, itemstack:get_name())
end
2016-09-01 14:53:35 +02:00
end)
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
2016-10-24 16:26:34 +02:00
if player == nil then return end
local playername = player:get_player_name()
2016-10-24 16:26:34 +02:00
if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then
reveal_item(playername, itemstack:get_name())
end
end)
2016-09-01 14:53:35 +02:00
minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing)
2016-10-24 16:26:34 +02:00
if user == nil then return end
local playername = user:get_player_name()
2016-10-24 16:26:34 +02:00
if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then
reveal_item(playername, itemstack:get_name())
if replace_with_item ~= nil then
reveal_item(playername, replace_with_item)
end
2016-09-01 14:53:35 +02:00
end
end)
2016-09-01 14:29:46 +02:00
minetest.register_on_joinplayer(function(player)
reveal_items_in_inventory(player)
end)
--[[ Periodically check all items in player inventory and reveal them all.
TODO: Check whether there's a serious performance impact on servers with many players.
TODO: If possible, try to replace this functionality by updating the revealed items as
soon the player obtained a new item (probably needs new Minetest callbacks). ]]
local checktime = 8
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer > checktime then
local players = minetest.get_connected_players()
for p=1, #players do
reveal_items_in_inventory(players[p])
end
timer = math.fmod(timer, checktime)
end
end)
2015-05-16 22:57:51 +02:00
minetest.after(0, gather_descs)