252 lines
9.0 KiB
Lua
252 lines
9.0 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.
|
|
|
|
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` field of
|
|
categories.
|
|
]]
|
|
|
|
-- Let's start with a very simple text-based category
|
|
-- This category only contains simple text
|
|
doc.new_category("example1", {
|
|
-- This is for humans and mandatory
|
|
name = "Text Example",
|
|
-- 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 ]]
|
|
})
|
|
|
|
-- Entry 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 boring 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 one entry
|
|
which starts hidden. ]]
|
|
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 game, 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,
|
|
|
|
--[[ 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", "widgets", "testbutton" },
|
|
})
|
|
|
|
doc.new_entry("example3", "simple", {
|
|
name="Label",
|
|
-- Please note the coordinates are shoddily chosen here.
|
|
-- FIXME: Show how to properly align widgets
|
|
data = "label[5,5;Just a label.]"
|
|
})
|
|
doc.new_entry("example3", "widgets", {
|
|
name="Widget Chaos",
|
|
-- Just some meaningless widgets for demonstration purposes
|
|
data = "label[0,1;Label]label[0,2;Label 2]button[0,3;3,1;example_ignored;Button]textlist[0,4;4,4;example_ignored2;A,B,C,D;]scrollbar[4,1;2,0.2;horizontal;example_ignored3;0]",
|
|
})
|
|
doc.new_entry("example3", "testbutton", {
|
|
name="Event Button",
|
|
-- This button actually will be used for an event …
|
|
data = "button[2,2;3,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 shows off the gallery widget ]]
|
|
-- FIXME: Depends on Minetest Game
|
|
doc.new_category("example4", {
|
|
name="Example: Galleries",
|
|
build_formspec = function(data, playername)
|
|
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"}},
|
|
})
|
|
|
|
|