minetest_doc_example/doc.lua

285 lines
10 KiB
Lua

--[[ Example for Documentation System [`doc`].
Reminder: This mod is the core of the Help modpack. It is thus rather low-level.
Use this to add your very own categories and entries, and to use some utility
functions.
This example demonstrates how to add categories and how to add entries into them.
It also demonstrates the versatility of the very important `build_formspec`
function used in category definitions. ]]
-- Let's start with a very simple text-based category.
-- This category only contains simple text.
doc.add_category("example1", {
-- This name is for humans and mandatory
name = "Example: Text",
-- This category uses a preset formspec builder for simple text
build_formspec = doc.entry_builders.text
--[[ Reminder: build_formspec determines how the entry data will be presented
to the user ]]
})
doc.add_category("sexample", {
name = "Example: Empty",
})
-- Entries for the aforementioned category. We add 2 entries.
doc.add_entry("example1", "text", {
-- This is for the entry title in the user interface, it's mandatory.
name = "Text example",
-- For this category, the entry data is simply the text to be displayed
data = "Lorem Minetest dolor sit amet. Bla bla bla bla Minetest bla bla bla bla Mese bla. Bla bla bla bla bla, celeron55 bla bla, bla.",
})
-- We will use this entry in doc_identifier.lua
doc.add_entry("example1", "entity", {
name = "Entity entry",
data = "This is the entry for the entity (added in doc_identifier.lua). The example entity is just a simple cube which floats in the air. Punch it to destroy it.",
})
-------------------------------------------------------------------------------
--[[ Category with hidden entry.
This is a category like the one before, but this time, we add a hidden entry.
]]
doc.add_category("example_hide", {
name = "Example: Hidden entry",
build_formspec = doc.entry_builders.text
})
-- This entry will start hidden. The user will not see it until it gets
-- revealed by using doc.mark_entry_as_revealed. Note that you should
-- NOT hide entries if there is no way for the player to reveal them.
doc.add_entry("example_hide", "hidden", {
name = "Hidden Entry",
hidden = true,
data = "This entry is hidden.",
})
-- This chat command demonstrates how to use `doc.mark_entry_as_revealed`.
minetest.register_chatcommand("doc_example_reveal", {
param = "",
description = "Reveal the hidden entry of the doc_example mod",
privs = {},
func = function(playername, params)
-- This reveals the previously created entry
doc.mark_entry_as_revealed(playername, "example_hide", "hidden")
minetest.chat_send_player(playername, "The hidden doc_example entry has been revealed! Look into the category “Example Hidden” to see it.")
end,
})
--[[ In actual games, you would probably want to invent more engaging ways to
reveal entries. ;-) ]]
-------------------------------------------------------------------------------
--[[ A simple category with 3 entries: Cities.
Now we're getting somewhere! This time, we define a custom build_formspec
function to display entry data dynamically. ]]
doc.add_category("example2", {
name = "Example: Cities",
description = "Example category: Quick information about the cities of the world",
--[[ This is a manual formspec builder: This will parse the entry data and
turns it into nice formspec widgets.
Reminder: We MUST return a valid formspec string! ]]
build_formspec = function(data)
return "label[0,1;Description: "..minetest.formspec_escape(data.description).."]" ..
"label[0,2;Population: "..data.population.."]"
end,
--[[ ADVANCED: Sorting example ]]
--[[ The entry data includes population as a number. This means we could (if we
want to) define a custom sorting function. This affects the order of the entries.
It makes sure that in the list of entries, the city with the highest population
comes first. Custom sorting is entirely optional but it might make it easier
for the user to navigate. But note that the default alphabetical sorting is
often good as well. ]]
sorting = "function",
sorting_data = function(entry1, entry2)
return entry1.data.population > entry2.data.population
end,
})
doc.add_entry("example2", "london", {
name="London",
-- Reminder: This data is put into the previous build_formspec function
data = {
description = "London is the capital of the United Kingdom.",
population = 8538689,
},
})
doc.add_entry("example2", "shanghai", {
name="Shanghai",
data = {
description = "Shanghai lies in China and is one of the biggest cities in the world.",
population = 23019148,
},
})
doc.add_entry("example2", "tripoli", {
name="Tripoli",
data = {
description = "Tripoli is the capital of Lybia.",
population = 1780000,
},
})
-------------------------------------------------------------------------------
--[[ Formspec category: This category shows how you can add widgets in entries
and even interact with them ]]
doc.add_category("example3", {
name="Example: Formspec",
description="Example category for manual free-form formspec entries",
--[[ This is a built-in formspec builder. In this case, the entry data
is expected to contains the full formspec definition for any entry.
This is useful if you want to build every entry by hand. The downside
is that it doesn't allow for dynamic entries. ]]
build_formspec = doc.entry_builders.formspec,
--[[ Sorting example ]]
--[[ This demonstrates the custom sorting type. In the entry list, the
entries will appear in the exact order as specified. ]]
sorting = "custom",
sorting_data = { "simple_bad", "simple_good", "multi", "testbutton" },
})
-- Just an entry with a label (BAD example)
doc.add_entry("example3", "simple_bad", {
name="Label",
-- Please note the coordinates are shoddily chosen here, the don't respect
-- the Documention System formspec boundaries at all, so this is just a guess.
data = "label[5,5;Just a bad, bad label.]"
})
-- Just an entry with a label (good example)
doc.add_entry("example3", "simple_good", {
name="Label",
--[[ This is the proper way to add widgets (this is also how you should do it in build_formspec):
Defining the coordinates relative to the Documentation System's boundaries. In this case,
the label will be at the top right. ]]
data = "label["..doc.FORMSPEC.ENTRY_START_X..","..doc.FORMSPEC.ENTRY_START_Y..";Just a good label.]"
})
-- Now let's get crazy with MULTIPLE formspec entries. How awesome is that?
doc.add_entry("example3", "multi", {
name="Label",
-- Label, just like before
data = "label["..doc.FORMSPEC.ENTRY_START_X..","..doc.FORMSPEC.ENTRY_START_Y..";Just another label.]" ..
-- Note the different Y offsets
"button["..doc.FORMSPEC.ENTRY_START_X..","..(doc.FORMSPEC.ENTRY_START_Y + 1)..";5,1;example_useless;Useless button]" ..
"button["..doc.FORMSPEC.ENTRY_START_X..","..(doc.FORMSPEC.ENTRY_START_Y + 2)..";5,1;example_useless;Useless button 2]" ..
"button["..doc.FORMSPEC.ENTRY_START_X..","..(doc.FORMSPEC.ENTRY_START_Y + 3)..";5,1;example_useless;Useless button 3]"
-- As you see, it's special at all. It's a normal formspec string, just longer.
})
-- This entry will be interactive.
doc.add_entry("example3", "testbutton", {
name="Event Button",
-- This button actually will be used for an event …
data = "button["..doc.FORMSPEC.ENTRY_START_X..","..doc.FORMSPEC.ENTRY_START_Y..";5,1;example_button;Event]",
})
-- … and here we react on the button event by writing something into the chat
-- This demonstrates how you can use an entry widget for custom actions
minetest.register_on_player_receive_fields(function(player, formname, fields)
-- Condition 1: This checks if the player is even using the entry tab.
-- This check is always the same.
if formname == "doc:entry" then
local playername = player:get_player_name()
-- Condition 2: this check is required to make sure we “listen”
-- to the correct entry
local category_id, entry_id = doc.get_selection(playername)
if category_id == "example3" and entry_id == "testbutton" then
-- Condition 3: Has the widget we actually care about been pressed?
if fields.example_button then
-- All conditions are met! Now the custom action can be executed
minetest.chat_send_player(playername, "You have pressed the event button!")
end
end
end
end)
-------------------------------------------------------------------------------
--[[ This category demonstrates the use of the gallery widget. ]]
-- FIXME: Depends on Minetest Game
doc.add_category("example4", {
name="Example: Galleries",
build_formspec = function(data, playername)
-- The trick here is to include doc.widgets.gallery into the custom
-- build_formspec definition.
local formspec = ""
--[[ Mostly using default values, but we want an aspect ratio of
1:1 (square). ]]
formspec = formspec .. doc.widgets.gallery(data, playername, nil, nil, 1)
return formspec
end,
})
-- Several gallery entries
doc.add_entry("example4", "gallery2", {
name="Gallery with 2 images",
-- The entry data will be also fed into `doc_widgets_gallery`
data = {
{image="default_grass.png"},
{image="default_book.png"}
},
})
doc.add_entry("example4", "gallery3", {
name="Gallery with 3 images",
data = {
{image="default_grass.png"},
{image="default_book.png"},
{image="default_papyrus.png"}},
})
--[[ The default gallery size is 3. But this gallery has 4 images.
The Documentation System automatically adds “scroll buttons”
if the number of images exceeds the gallery size ]]
doc.add_entry("example4", "gallery4", {
name="Gallery with 4 images",
data = {
{image="default_dirt.png"},
{image="default_leaves.png"},
{image="default_brick.png"},
{image="default_gold_block.png"}
},
})
doc.add_entry("example4", "gallery5", {
name="Gallery with 5 images",
data = {
{image="default_dirt.png"},
{image="default_leaves.png"},
{image="default_brick.png"},
{image="default_gold_block.png"},
{image="default_bronze_block.png"}
},
})
doc.add_entry("example4", "gallery6", {
name="Gallery with 6 images",
data = {
{image="default_grass.png"},
{image="default_dirt.png"},
{image="default_leaves.png"},
{image="default_brick.png"},
{image="default_gold_block.png"},
{image="default_bronze_block.png"}},
})
doc.add_entry("example4", "gallery7", {
name="Gallery with 7 item images",
data = {
-- You can use this syntax to display item images instead of normal textures
{image="default:bookshelf", imagetype="item"},
{image="default:grass_5", imagetype="item"},
{image="default:dirt", imagetype="item"},
{image="default:fence_wood", imagetype="item"},
{image="default:flint", imagetype="item"},
{image="default:goldblock", imagetype="item"},
{image="default:bronzeblock", imagetype="item"}},
})