276 lines
10 KiB
Lua
276 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.new_category("example1", {
|
|
-- This name is for humans and mandatory
|
|
name = "Text Examples",
|
|
-- 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 ]]
|
|
})
|
|
|
|
-- Entries for the aforementioned category. We add 2 entries.
|
|
doc.new_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.new_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.new_category("example_hide", {
|
|
name = "Example Hidden",
|
|
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.new_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.new_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.new_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.new_entry("example2", "shanghai", {
|
|
name="Shanghai",
|
|
data = {
|
|
description = "Shanghai lies in China and is one of the biggest cities in the world.",
|
|
population = 23019148,
|
|
},
|
|
})
|
|
doc.new_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.new_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.new_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.new_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.new_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.new_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.new_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.new_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.new_entry("example4", "gallery3", {
|
|
name="Gallery with 3 images",
|
|
data = {
|
|
{image="default_grass.png"},
|
|
{image="default_book.png"},
|
|
{image="default_papyrus.png"}},
|
|
})
|
|
|
|
doc.new_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.new_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.new_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.new_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"}},
|
|
})
|
|
|
|
|