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
2016-11-09 01:38:24 +01:00
S = intllib.Getter ( )
2016-10-25 15:31:25 +02:00
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 = {
2016-08-29 18:53:37 +02:00
[ " ignore " ] = false
2016-08-03 15:03:38 +02:00
}
2016-08-29 18:53:37 +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
}
2015-06-03 10:07:04 +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
2016-08-17 00:41:42 +02:00
-- 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
2016-09-06 17:30:25 +02:00
-- Extract suitable item description for formspec
local description_for_formspec = function ( itemstring )
2016-12-03 21:11:55 +01:00
if minetest.registered_items [ itemstring ] == nil then
-- Huh? The item doesn't exist for some reason. Better give a dummy string
minetest.log ( " warning " , " [doc] Unknown item detected: " .. tostring ( itemstring ) )
return S ( " Unknown item (@1) " , tostring ( itemstring ) )
end
2016-09-06 17:30:25 +02:00
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
2016-08-17 00:41:42 +02:00
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. \n Mining 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. \n Maximum 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
2016-08-03 02:01:46 +02:00
-- 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. " )
2016-08-03 02:01:46 +02:00
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. " )
2016-08-03 02:01:46 +02:00
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. " )
2016-08-03 02:01:46 +02:00
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 ) )
2016-08-03 02:01:46 +02:00
end
2016-10-07 17:41:41 +02:00
formstring = newline ( formstring )
2016-08-03 02:01:46 +02:00
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
2015-06-03 10:07:04 +02:00
local longdesc = data.longdesc
local usagehelp = data.usagehelp
local formstring = " "
if data.itemstring ~= " air " then
2016-08-16 00:36:11 +02:00
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 .. " ] "
2016-08-16 00:36:11 +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-08-16 00:36:11 +02:00
end
2015-06-03 10:07:04 +02:00
end
2016-10-09 03:03:50 +02:00
local datastring = " "
2015-06-03 10:07:04 +02:00
if longdesc ~= nil then
2016-10-25 15:31:25 +02:00
datastring = datastring .. string.format ( S ( " Description: %s " ) , longdesc ) .. " \n \n "
2015-06-03 10:07:04 +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 "
2015-06-03 10:07:04 +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 "
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
2016-08-24 23:42:35 +02:00
if renew then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S ( " • Renewable " ) .. " \n "
2016-08-24 23:42:35 +02:00
else
2016-10-25 15:31:25 +02:00
datastring = datastring .. S ( " • Not renewable " ) .. " \n "
2016-08-24 23:42:35 +02:00
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
2016-08-28 18:17:32 +02:00
--- 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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
end
if data.def . climbable == true then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S ( " This block can be climbed. " ) .. " \n "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
else
if silentstep then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S ( " Walking on this block is completely silent. " ) .. " \n "
2016-08-28 18:17:32 +02:00
end
if silentdig then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S ( " Mining this block is completely silent. " ) .. " \n "
2016-08-28 18:17:32 +02:00
end
if silentplace then
2016-10-25 15:31:25 +02:00
datastring = datastring .. S ( " Building this block is completely silent. " ) .. " \n "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 17:55:30 +02:00
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 "
2016-08-28 17:55:30 +02:00
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 "
2016-08-28 17:55:30 +02:00
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 "
2016-08-28 17:55:30 +02:00
end
2015-05-16 22:57:51 +02:00
end
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
end
end
2016-08-28 18:28:24 +02:00
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 "
2016-08-28 18:28:24 +02:00
end
2016-08-28 18:17:32 +02:00
-- 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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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 "
2016-08-28 18:17:32 +02:00
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
2016-09-06 17:30:25 +02:00
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
2016-08-29 13:37:50 +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
2016-09-02 07:28:27 +02:00
if data.def . groups [ groupname ] ~= nil or groupname == " dig_immediate " then
2016-08-29 13:37:50 +02:00
nogroups = false
break
2016-08-05 00:33:08 +02:00
end
end
2016-08-29 13:37:50 +02:00
-- 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 "
2016-08-29 13:37:50 +02:00
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 "
2016-08-29 13:37:50 +02:00
-- 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 "
2016-08-29 13:37:50 +02:00
end
2016-08-05 00:33:08 +02:00
else
2016-08-29 13:37:50 +02:00
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 "
2016-08-29 13:37:50 +02:00
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 "
2016-08-29 13:37:50 +02:00
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 "
2016-08-29 13:37:50 +02:00
end
2016-08-05 00:33:08 +02:00
end
2016-08-29 13:37:50 +02:00
-- 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 "
2016-08-29 13:37:50 +02:00
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 "
2016-08-29 13:37:50 +02:00
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 "
2016-08-29 13:37:50 +02:00
else
2016-10-25 15:31:25 +02:00
mstring = mstring .. S ( " Mining level: 0 " ) .. " \n "
2016-08-29 13:37:50 +02:00
end
2016-08-01 07:12:43 +02:00
2016-08-29 13:37:50 +02:00
if minegroupcount > 0 then
2016-10-09 03:03:50 +02:00
datastring = datastring .. mstring
2016-08-29 13:37:50 +02:00
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
2016-08-01 23:47:24 +02:00
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 )
2016-09-06 17:30:25 +02:00
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 )
2016-08-01 23:47:24 +02:00
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
2016-08-25 20:25:25 +02:00
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. " )
2016-08-25 20:25:25 +02:00
else
2016-10-26 20:27:04 +02:00
dropstring_base = S ( " This block will randomly drop one of the following when mined: %s. " )
2016-08-25 20:25:25 +02:00
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
2016-08-17 12:03:40 +02:00
-- Save calculated probabilities into a table for later output
2016-08-25 20:12:30 +02:00
local probtables = { }
local probtable
2016-08-25 22:24:48 +02:00
local rarity_history = { }
2016-08-01 02:23:08 +02:00
for i = 1 , # data.def . drop.items do
2016-08-25 22:24:48 +02:00
local local_rarity = data.def . drop.items [ i ] . rarity
local chance = 1
local rarity = 1
if local_rarity == nil then
local_rarity = 1
2016-08-17 11:51:52 +02:00
end
2016-08-25 22:24:48 +02:00
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 ]
2016-08-25 20:54:56 +02:00
else
2016-08-25 22:24:48 +02:00
chance_factor = ( rarity_history [ r ] - 1 ) / rarity_history [ r ]
2016-08-25 20:54:56 +02:00
end
2016-08-25 22:24:48 +02:00
chance = chance * chance_factor
2016-08-25 20:34:26 +02:00
end
2016-08-25 22:24:48 +02:00
if chance > 0 then
rarity = 1 / chance
end
else
rarity = local_rarity
chance = 1 / rarity
2016-08-01 02:38:34 +02:00
end
2016-08-25 22:24:48 +02:00
-- 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
2016-08-17 12:12:45 +02:00
end
-- Do some cleanup of the probability table
2016-08-25 22:39:56 +02:00
if max == 1 or max == nil then
2016-08-17 12:12:45 +02:00
-- Sort by rarity
local comp = function ( p1 , p2 )
return p1.rarity < p2.rarity
end
2016-08-25 20:12:30 +02:00
table.sort ( probtables , comp )
2016-08-01 02:23:08 +02:00
end
2016-08-17 12:03:40 +02:00
-- Output probability table
2016-08-25 20:54:56 +02:00
local pcount = 0
2016-08-25 20:12:30 +02:00
for i = 1 , # probtables do
2016-08-25 20:54:56 +02:00
if pcount > 0 then
2016-10-26 20:27:04 +02:00
-- List seperator
dropstring = dropstring .. S ( " , " )
2016-08-17 12:03:40 +02:00
end
2016-08-25 20:12:30 +02:00
local probtable = probtables [ i ]
2016-08-25 20:54:56 +02:00
local icount = 0
2016-10-26 20:27:04 +02:00
local dropstring_this = " "
2016-08-25 20:54:56 +02:00
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 " )
2016-08-25 20:12:30 +02:00
end
2016-10-26 20:27:04 +02:00
local desc = S ( itemtable.desc )
2016-08-25 20:54:56 +02:00
local count = itemtable.count
2016-08-25 20:12:30 +02:00
if count ~= 1 then
2016-10-26 20:27:04 +02:00
desc = string.format ( S ( " %d× %s " ) , count , desc )
2016-08-25 20:12:30 +02:00
end
2016-10-26 20:27:04 +02:00
dropstring_this = dropstring_this .. desc
2016-08-25 20:54:56 +02:00
icount = icount + 1
2016-08-17 12:03:40 +02:00
end
2016-08-25 20:12:30 +02:00
local rarity = probtable.rarity
2016-10-26 20:27:04 +02:00
local raritystring = " "
2016-08-25 20:25:25 +02:00
-- 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%
2016-08-17 12:03:40 +02:00
-- For very low percentages
2016-10-26 20:27:04 +02:00
dropstring_this = string.format ( S ( " %s (<0.5%) " ) , dropstring_this )
2016-08-25 20:25:25 +02:00
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 )
2016-08-25 20:25:25 +02:00
end
2016-08-17 12:03:40 +02:00
end
end
2016-10-26 20:27:04 +02:00
dropstring = dropstring .. dropstring_this
2016-08-25 20:54:56 +02:00
pcount = pcount + 1
2016-08-17 12:03:40 +02:00
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
2016-11-03 04:12:44 +01: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
} )
2015-06-03 10:07:04 +02:00
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 " ) ,
2015-06-03 10:07:04 +02:00
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
2016-08-16 00:36:11 +02:00
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
2015-06-03 10:07:04 +02:00
2016-10-09 03:03:50 +02:00
datastring = datastring .. range_factoid ( data.itemstring , data.def ) .. " \n "
2015-06-03 10:07:04 +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 .. 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 )
2015-06-03 10:07:04 +02:00
2016-10-09 03:03:50 +02:00
datastring = datastring .. toolcaps_to_text ( data.def . tool_capabilities )
2015-06-03 10:07:04 +02:00
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
2016-11-03 04:12:44 +01: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-06-03 10:07:04 +02:00
return formstring
else
2016-11-03 03:50:21 +01:00
return " label[0,1;NO DATA AVALIABLE!] "
2015-06-03 10:07:04 +02:00
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) " ) ,
2015-06-03 10:07:04 +02:00
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 = " "
2016-08-16 00:36:11 +02:00
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 .. " ] "
2016-08-16 00:36:11 +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-08-16 00:36:11 +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 ) .. " \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 "
2015-06-03 10:07:04 +02:00
2016-10-09 03:03:50 +02:00
datastring = datastring .. range_factoid ( data.itemstring , data.def ) .. " \n "
2015-06-03 10:07:04 +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 .. 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 )
2015-06-03 10:07:04 +02:00
2016-10-09 03:03:50 +02:00
datastring = datastring .. toolcaps_to_text ( data.def . tool_capabilities )
2015-06-03 10:07:04 +02:00
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
2015-06-03 10:07:04 +02:00
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
2016-11-03 04:12:44 +01: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-06-03 10:07:04 +02:00
return formstring
else
2016-11-03 03:50:21 +01:00
return " label[0,1;NO DATA AVALIABLE!] "
2015-06-03 10:07:04 +02:00
end
end
} )
2016-08-02 15:35:40 +02:00
doc.sub . items.help = { }
doc.sub . items.help . longdesc = { }
doc.sub . items.help . usagehelp = { }
2016-08-16 00:36:11 +02:00
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
2016-07-24 17:45:25 +02:00
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
2016-07-24 17:45:25 +02:00
end
end
2015-06-03 10:07:04 +02:00
2016-08-16 00:36:11 +02:00
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
2016-11-03 02:41:13 +01:00
-- 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,
2016-08-03 09:49:37 +02:00
-- 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
2016-08-29 18:53:37 +02:00
-- 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
2016-08-13 00:18:14 +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
2016-08-16 00:36:11 +02:00
local name , ld , uh , im
2016-08-16 00:18:28 +02:00
local forced = false
2016-11-16 06:35:24 +01:00
if ( forced_items [ id ] == true or def.groups . in_doc or def._doc_items_create_entry == true ) and def ~= nil then forced = true end
if def._doc_items_entry_name ~= nil then
name = def._doc_items_entry_name
2016-10-30 20:35:16 +01:00
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-11-16 06:35:24 +01:00
if not ( ( ( def.description == nil or def.description == " " ) and def._doc_items_entry_name == nil ) or def.groups . not_in_doc or forced_items [ id ] == false or def._doc_items_create_entry == false ) or forced then
if def._doc_items_longdesc then
ld = def._doc_items_longdesc
2016-10-30 04:17:55 +01:00
end
2016-08-16 00:18:28 +02:00
if help.longdesc [ id ] ~= nil then
ld = help.longdesc [ id ]
end
2016-11-16 06:35:24 +01:00
if def._doc_items_usagehelp then
uh = def._doc_items_usagehelp
2016-10-30 04:17:55 +01:00
end
2016-08-16 00:18:28 +02:00
if help.usagehelp [ id ] ~= nil then
uh = help.usagehelp [ id ]
end
2016-11-16 06:35:24 +01:00
if def._doc_items_image then
im = def._doc_items_image
2016-10-30 04:17:55 +01:00
end
2016-08-16 00:36:11 +02:00
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-11-16 06:35:24 +01:00
if type ( def._doc_items_hidden ) == " boolean " then
hidden = def._doc_items_hidden
2016-10-30 19:53:30 +01:00
end
2016-08-16 00:36:11 +02:00
local custom_image
2016-08-17 00:41:42 +02:00
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 ,
2016-08-16 00:36:11 +02:00
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
2015-06-03 10:07:04 +02:00
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 " )
2015-06-03 10:07:04 +02:00
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 ) ] ]
2016-09-01 12:35:03 +02:00
local function reveal_item ( playername , itemstring )
local category_id
2016-10-23 00:23:20 +02:00
if itemstring == nil or itemstring == " " or playername == nil or playername == " " then
return false
end
2016-09-01 12:35:03 +02:00
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 "
2016-09-01 12:35:03 +02:00
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
2016-09-01 12:35:03 +02:00
minetest.register_on_dignode ( function ( pos , oldnode , digger )
2016-10-24 16:26:34 +02:00
if digger == nil then return end
2016-10-23 00:23:20 +02:00
local playername = digger : get_player_name ( )
2016-10-24 16:26:34 +02:00
if playername ~= nil and playername ~= " " and oldnode ~= nil then
2016-10-23 00:23:20 +02:00
reveal_item ( playername , oldnode.name )
2016-09-01 14:29:46 +02:00
reveal_items_in_inventory ( digger )
end
2016-09-01 12:35:03 +02:00
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
2016-10-23 00:23:20 +02:00
local playername = puncher : get_player_name ( )
if playername ~= nil and playername ~= " " and node ~= nil then
reveal_item ( playername , node.name )
end
2016-09-01 12:35:03 +02:00
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
2016-10-23 00:23:20 +02:00
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
2016-10-23 00:23:20 +02:00
reveal_item ( playername , itemstack : get_name ( ) )
end
2016-09-01 14:53:35 +02:00
end )
2016-09-01 12:35:03 +02:00
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
2016-10-23 00:23:20 +02:00
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
2016-10-23 00:23:20 +02:00
reveal_item ( playername , itemstack : get_name ( ) )
end
2016-09-01 12:35:03 +02:00
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
2016-10-23 00:23:20 +02:00
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
2016-10-23 00:23:20 +02:00
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
2016-09-01 12:35:03 +02:00
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 )