Replace tab character with four spaces for better formatting
This commit is contained in:
parent
d68975ba9f
commit
5d64318342
170
README.md
170
README.md
@ -41,19 +41,19 @@ fit my idea of quality.
|
||||
|
||||
I use [Jekyll](http://jekyllrb.com/) 2.5.3
|
||||
|
||||
# For Linux based:
|
||||
# For Linux based:
|
||||
|
||||
$ sudo apt-get install ruby-dev
|
||||
$ gem install jekyll
|
||||
$ gem install jekyll-sitemap
|
||||
$ sudo apt-get install ruby-dev
|
||||
$ gem install jekyll
|
||||
$ gem install jekyll-sitemap
|
||||
|
||||
# You may need to use sudo on the above commands
|
||||
# You may need to use sudo on the above commands
|
||||
|
||||
### Building as a website
|
||||
|
||||
You can build it as a website using [Jekyll](http://jekyllrb.com/)
|
||||
|
||||
$ jekyll build
|
||||
$ jekyll build
|
||||
|
||||
Goes to _site/
|
||||
|
||||
@ -62,7 +62,7 @@ Goes to _site/
|
||||
You can start a webserver on localhost which will automatically
|
||||
rebuild pages when you modify their markdown source.
|
||||
|
||||
$ jekyll serve
|
||||
$ jekyll serve
|
||||
|
||||
|
||||
This serves at <http://localhost:4000> on my computer, but the port
|
||||
@ -89,107 +89,107 @@ Replace spaces with underscores ( _ )
|
||||
|
||||
{% raw %}
|
||||
|
||||
---
|
||||
title: Player Physics
|
||||
layout: default
|
||||
root: ../
|
||||
---
|
||||
---
|
||||
title: Player Physics
|
||||
layout: default
|
||||
root: ../
|
||||
---
|
||||
|
||||
Introduction
|
||||
------------
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Write an paragraph or so explaining what will be covered in this chapter.
|
||||
Explain why/how these concepts are useful in modding
|
||||
Write an paragraph or so explaining what will be covered in this chapter.
|
||||
Explain why/how these concepts are useful in modding
|
||||
|
||||
* List the
|
||||
* Parts in
|
||||
* This chapter
|
||||
* List the
|
||||
* Parts in
|
||||
* This chapter
|
||||
|
||||
Section
|
||||
-------
|
||||
Section
|
||||
-------
|
||||
|
||||
Explaining the concept of something.
|
||||
Explaining the concept of something.
|
||||
|
||||
You can link to other chapters like this: [chapter title]({{ relative }}/chaptertitle/).//
|
||||
Do it like Wikipedia, link words in a sentence but avoid explicitly telling the user to view it//
|
||||
or click the link.
|
||||
You can link to other chapters like this: [chapter title]({{ relative }}/chaptertitle/).//
|
||||
Do it like Wikipedia, link words in a sentence but avoid explicitly telling the user to view it//
|
||||
or click the link.
|
||||
|
||||
Mod Name
|
||||
- init.lua - the main scripting code file, which is run when the game loads.
|
||||
- (optional) depends.txt - a list of mod names that needs to be loaded before this mod.
|
||||
- (optional) textures/ - place images here, commonly in the format modname_itemname.png
|
||||
- (optional) sounds/ - place sounds in here
|
||||
- (optional) models/ - place 3d models in here
|
||||
...and any other lua files to be included by init.lua
|
||||
Mod Name
|
||||
- init.lua - the main scripting code file, which is run when the game loads.
|
||||
- (optional) depends.txt - a list of mod names that needs to be loaded before this mod.
|
||||
- (optional) textures/ - place images here, commonly in the format modname_itemname.png
|
||||
- (optional) sounds/ - place sounds in here
|
||||
- (optional) models/ - place 3d models in here
|
||||
...and any other lua files to be included by init.lua
|
||||
|
||||
Code snippets are tabbed one level in, except for lua snippets, which use a code highligter.
|
||||
Code snippets are tabbed one level in, except for lua snippets, which use a code highligter.
|
||||
|
||||
Section 2
|
||||
---------
|
||||
Section 2
|
||||
---------
|
||||
|
||||
Explaining another concept
|
||||
Explaining another concept
|
||||
|
||||
{% highlight lua %}
|
||||
print("This file will be run at load time!")
|
||||
{% highlight lua %}
|
||||
print("This file will be run at load time!")
|
||||
|
||||
minetest.register_node("mymod:node",{
|
||||
description = "This is a node",
|
||||
tiles = {
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png"
|
||||
},
|
||||
groups = {cracky = 1}
|
||||
})
|
||||
{% endhighlight %}
|
||||
minetest.register_node("mymod:node",{
|
||||
description = "This is a node",
|
||||
tiles = {
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png"
|
||||
},
|
||||
groups = {cracky = 1}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
Use the highlight tags to highlight Lua code.
|
||||
Use the highlight tags to highlight Lua code.
|
||||
|
||||
Section 3
|
||||
---------
|
||||
Section 3
|
||||
---------
|
||||
|
||||
You should include plenty of examples. Each example should
|
||||
be able to be installed in a mod and used. Don't do the thing where
|
||||
you make the reading create the mod line-by-line, it is rather annoying
|
||||
and good code can explain itself. Explaining line-by-line is needed in earlier chapters,
|
||||
and when introducing new concepts.
|
||||
You should include plenty of examples. Each example should
|
||||
be able to be installed in a mod and used. Don't do the thing where
|
||||
you make the reading create the mod line-by-line, it is rather annoying
|
||||
and good code can explain itself. Explaining line-by-line is needed in earlier chapters,
|
||||
and when introducing new concepts.
|
||||
|
||||
### Mod Folder
|
||||
mymod/
|
||||
- init.lua
|
||||
- depends.txt
|
||||
### Mod Folder
|
||||
mymod/
|
||||
- init.lua
|
||||
- depends.txt
|
||||
|
||||
|
||||
default
|
||||
default
|
||||
|
||||
{% highlight lua %}
|
||||
print("This file will be run at load time!")
|
||||
{% highlight lua %}
|
||||
print("This file will be run at load time!")
|
||||
|
||||
minetest.register_node("mymod:node",{
|
||||
description = "This is a node",
|
||||
tiles = {
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png"
|
||||
},
|
||||
groups = {cracky = 1}
|
||||
})
|
||||
{% endhighlight %}
|
||||
minetest.register_node("mymod:node",{
|
||||
description = "This is a node",
|
||||
tiles = {
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png"
|
||||
},
|
||||
groups = {cracky = 1}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
Explain the code here, but there is no need to explain every single line.
|
||||
Use comments and indentation well.
|
||||
Explain the code here, but there is no need to explain every single line.
|
||||
Use comments and indentation well.
|
||||
|
||||
Your Turn
|
||||
---------
|
||||
Your Turn
|
||||
---------
|
||||
|
||||
* **Set Tasks:** Make tasks for the reader to do.
|
||||
* **Start easy, get hard:** Start with easier ones, and work up to harder ones.
|
||||
* **Set Tasks:** Make tasks for the reader to do.
|
||||
* **Start easy, get hard:** Start with easier ones, and work up to harder ones.
|
||||
|
||||
{% endraw %}
|
||||
|
||||
|
@ -23,21 +23,21 @@ blocks.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("aliens:grass", {
|
||||
description = "Alien Grass",
|
||||
light_source = 3, -- The node radiates light. Values can be from 1 to 15
|
||||
tiles = {"aliens_grass.png"},
|
||||
groups = {choppy=1},
|
||||
on_use = minetest.item_eat(20)
|
||||
description = "Alien Grass",
|
||||
light_source = 3, -- The node radiates light. Values can be from 1 to 15
|
||||
tiles = {"aliens_grass.png"},
|
||||
groups = {choppy=1},
|
||||
on_use = minetest.item_eat(20)
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"default:dirt_with_grass"},
|
||||
neighbors = {"default:water_source", "default:water_flowing"},
|
||||
interval = 10.0, -- Run every 10 seconds
|
||||
chance = 50, -- Select every 1 in 50 nodes
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "aliens:grass"})
|
||||
end
|
||||
nodenames = {"default:dirt_with_grass"},
|
||||
neighbors = {"default:water_source", "default:water_flowing"},
|
||||
interval = 10.0, -- Run every 10 seconds
|
||||
chance = 50, -- Select every 1 in 50 nodes
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "aliens:grass"})
|
||||
end
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -26,9 +26,9 @@ minetest.chat_send_all("This is a chat message to all players")
|
||||
Here is an example of how it would appear ingame (there are other messages
|
||||
around it).
|
||||
|
||||
<player1> Look at this entrance
|
||||
This is a chat message to all players
|
||||
<player2> What about it?
|
||||
<player1> Look at this entrance
|
||||
This is a chat message to all players
|
||||
<player2> What about it?
|
||||
|
||||
## Send a message to a certain player
|
||||
|
||||
@ -59,12 +59,12 @@ In order to register a chat command, such as /foo, use register_chatcommand:
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_chatcommand("foo", {
|
||||
privs = {
|
||||
interact = true
|
||||
},
|
||||
func = function(name, param)
|
||||
return true, "You said " .. param .. "!"
|
||||
end
|
||||
privs = {
|
||||
interact = true
|
||||
},
|
||||
func = function(name, param)
|
||||
return true, "You said " .. param .. "!"
|
||||
end
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -74,7 +74,7 @@ Let's do a break down:
|
||||
|
||||
{% highlight lua %}
|
||||
privs = {
|
||||
interact = true
|
||||
interact = true
|
||||
},
|
||||
{% endhighlight %}
|
||||
|
||||
@ -116,8 +116,8 @@ You can use register_on_chat_message, like so:
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
print(name .. " said " .. message)
|
||||
return false
|
||||
print(name .. " said " .. message)
|
||||
return false
|
||||
end)
|
||||
{% endhighlight %}
|
||||
|
||||
@ -130,12 +130,12 @@ player messages, you need to do this:
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
if message:sub(1, 1) == "/" then
|
||||
print(name .. " ran chat command")
|
||||
return false
|
||||
end
|
||||
if message:sub(1, 1) == "/" then
|
||||
print(name .. " ran chat command")
|
||||
return false
|
||||
end
|
||||
|
||||
print(name .. " said " .. message)
|
||||
return false
|
||||
print(name .. " said " .. message)
|
||||
return false
|
||||
end)
|
||||
{% endhighlight %}
|
||||
|
@ -28,21 +28,21 @@ Because of this, I created a library to do this for you.
|
||||
|
||||
{% highlight lua %}
|
||||
ChatCmdBuilder.new("sethp", function(cmd)
|
||||
cmd:sub(":target :hp:int", function(name, target, hp)
|
||||
local player = minetest.get_player_by_name(target)
|
||||
if player then
|
||||
player:set_hp(hp)
|
||||
return true, "Killed " .. target
|
||||
else
|
||||
return false, "Unable to find " .. target
|
||||
end
|
||||
end)
|
||||
cmd:sub(":target :hp:int", function(name, target, hp)
|
||||
local player = minetest.get_player_by_name(target)
|
||||
if player then
|
||||
player:set_hp(hp)
|
||||
return true, "Killed " .. target
|
||||
else
|
||||
return false, "Unable to find " .. target
|
||||
end
|
||||
end)
|
||||
end, {
|
||||
description = "Set hp of player",
|
||||
privs = {
|
||||
kick = true
|
||||
-- ^ probably better to register a custom priv
|
||||
}
|
||||
description = "Set hp of player",
|
||||
privs = {
|
||||
kick = true
|
||||
-- ^ probably better to register a custom priv
|
||||
}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -94,7 +94,7 @@ function in order.
|
||||
|
||||
{% highlight lua %}
|
||||
cmd:sub(":target :hp:int", function(name, target, hp)
|
||||
-- subcommand function
|
||||
-- subcommand function
|
||||
end)
|
||||
{% endhighlight %}
|
||||
|
||||
@ -118,55 +118,55 @@ Here is an example that creates a chat command that allows us to do this:
|
||||
{% highlight lua %}
|
||||
local admin_log
|
||||
local function load()
|
||||
admin_log = {}
|
||||
admin_log = {}
|
||||
end
|
||||
local function save()
|
||||
-- todo
|
||||
-- todo
|
||||
end
|
||||
load()
|
||||
|
||||
ChatCmdBuilder.new("admin", function(cmd)
|
||||
cmd:sub("kill :name", function(name, target)
|
||||
local player = minetest.get_player_by_name(target)
|
||||
if player then
|
||||
player:set_hp(0)
|
||||
return true, "Killed " .. target
|
||||
else
|
||||
return false, "Unable to find " .. target
|
||||
end
|
||||
end)
|
||||
cmd:sub("kill :name", function(name, target)
|
||||
local player = minetest.get_player_by_name(target)
|
||||
if player then
|
||||
player:set_hp(0)
|
||||
return true, "Killed " .. target
|
||||
else
|
||||
return false, "Unable to find " .. target
|
||||
end
|
||||
end)
|
||||
|
||||
cmd:sub("move :name to :pos:pos", function(name, target, pos)
|
||||
local player = minetest.get_player_by_name(target)
|
||||
if player then
|
||||
player:setpos(pos)
|
||||
return true, "Moved " .. target .. " to " .. minetest.pos_to_string(pos)
|
||||
else
|
||||
return false, "Unable to find " .. target
|
||||
end
|
||||
end)
|
||||
cmd:sub("move :name to :pos:pos", function(name, target, pos)
|
||||
local player = minetest.get_player_by_name(target)
|
||||
if player then
|
||||
player:setpos(pos)
|
||||
return true, "Moved " .. target .. " to " .. minetest.pos_to_string(pos)
|
||||
else
|
||||
return false, "Unable to find " .. target
|
||||
end
|
||||
end)
|
||||
|
||||
cmd:sub("log :username", function(name, target)
|
||||
local log = admin_log[target]
|
||||
if log then
|
||||
return true, table.concat(log, "\n")
|
||||
else
|
||||
return false, "No entries for " .. target
|
||||
end
|
||||
end)
|
||||
cmd:sub("log :username", function(name, target)
|
||||
local log = admin_log[target]
|
||||
if log then
|
||||
return true, table.concat(log, "\n")
|
||||
else
|
||||
return false, "No entries for " .. target
|
||||
end
|
||||
end)
|
||||
|
||||
cmd:sub("log :username :message", function(name, target, message)
|
||||
local log = admin_log[target] or {}
|
||||
table.insert(log, message)
|
||||
admin_log[target] = log
|
||||
save()
|
||||
return true, "Logged"
|
||||
end)
|
||||
cmd:sub("log :username :message", function(name, target, message)
|
||||
local log = admin_log[target] or {}
|
||||
table.insert(log, message)
|
||||
admin_log[target] = log
|
||||
save()
|
||||
return true, "Logged"
|
||||
end)
|
||||
end, {
|
||||
description = "Admin tools",
|
||||
privs = {
|
||||
kick = true,
|
||||
ban = true
|
||||
}
|
||||
description = "Admin tools",
|
||||
privs = {
|
||||
kick = true,
|
||||
ban = true
|
||||
}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
@ -31,19 +31,19 @@ learning curve as lots of its features are hidden away.
|
||||
### Use the pencil tool to edit individual pixels
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}/static/pixel_art_gimp_pencil.png" alt="Pencil in GIMP">
|
||||
<figcaption>
|
||||
Pencil in GIMP
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/pixel_art_gimp_pencil.png" alt="Pencil in GIMP">
|
||||
<figcaption>
|
||||
Pencil in GIMP
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
### Set the rubber to hard edge
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}/static/pixel_art_gimp_rubber.png" alt="Rubber in GIMP">
|
||||
<figcaption>
|
||||
Rubber in GIMP
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/pixel_art_gimp_rubber.png" alt="Rubber in GIMP">
|
||||
<figcaption>
|
||||
Rubber in GIMP
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
## Common Mistakes
|
||||
|
@ -27,13 +27,13 @@ Mod names can be made up of letters, numbers, or underscores. The folder a mod i
|
||||
in needs to be called the same as the mod name.
|
||||
|
||||
### Mod Folder Structure
|
||||
Mod name (eg: "mymod")
|
||||
- init.lua - the main scripting code file, which is run when the game loads.
|
||||
- (optional) depends.txt - a list of mod names that needs to be loaded before this mod.
|
||||
- (optional) textures/ - place images here, commonly in the format modname_itemname.png
|
||||
- (optional) sounds/ - place sounds in here
|
||||
- (optional) models/ - place 3d models in here
|
||||
...and any other lua files to be included by init.lua
|
||||
Mod name (eg: "mymod")
|
||||
- init.lua - the main scripting code file, which is run when the game loads.
|
||||
- (optional) depends.txt - a list of mod names that needs to be loaded before this mod.
|
||||
- (optional) textures/ - place images here, commonly in the format modname_itemname.png
|
||||
- (optional) sounds/ - place sounds in here
|
||||
- (optional) models/ - place 3d models in here
|
||||
...and any other lua files to be included by init.lua
|
||||
|
||||
Only the init.lua file is required in a mod for it to run on game load; however,
|
||||
the other items are needed by some mods to perform their functionality.
|
||||
@ -45,9 +45,9 @@ needs to be loaded before this mod.
|
||||
|
||||
**depends.txt**
|
||||
|
||||
modone
|
||||
modtwo
|
||||
modthree?
|
||||
modone
|
||||
modtwo
|
||||
modthree?
|
||||
|
||||
As you can see, each modname is on its own line.
|
||||
|
||||
@ -64,43 +64,43 @@ They are useful if you want to supply multiple mods to a player but don't
|
||||
want to make them download each one individually.
|
||||
|
||||
### Mod Pack Folder Structure
|
||||
modpackfolder/
|
||||
- modone/
|
||||
- modtwo/
|
||||
- modthree/
|
||||
- modfour/
|
||||
- modpack.txt – signals that this is a mod pack, content does not matter
|
||||
modpackfolder/
|
||||
- modone/
|
||||
- modtwo/
|
||||
- modthree/
|
||||
- modfour/
|
||||
- modpack.txt – signals that this is a mod pack, content does not matter
|
||||
|
||||
## Example Time
|
||||
|
||||
Are you confused? Don't worry, here is an example putting all of this together.
|
||||
|
||||
### Mod Folder
|
||||
mymod/
|
||||
- textures/
|
||||
- - mymod_node.png
|
||||
- init.lua
|
||||
- depends.txt
|
||||
mymod/
|
||||
- textures/
|
||||
- - mymod_node.png
|
||||
- init.lua
|
||||
- depends.txt
|
||||
|
||||
|
||||
### depends.txt
|
||||
default
|
||||
default
|
||||
|
||||
### init.lua
|
||||
{% highlight lua %}
|
||||
print("This file will be run at load time!")
|
||||
|
||||
minetest.register_node("mymod:node", {
|
||||
description = "This is a node",
|
||||
tiles = {
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png"
|
||||
},
|
||||
groups = {cracky = 1}
|
||||
description = "This is a node",
|
||||
tiles = {
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png",
|
||||
"mymod_node.png"
|
||||
},
|
||||
groups = {cracky = 1}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -7,10 +7,10 @@ root: ../../
|
||||
## Introduction
|
||||
|
||||
<figure class="right_image">
|
||||
<img src="{{ page.root }}/static/formspec_example.png" alt="Furnace Inventory">
|
||||
<figcaption>
|
||||
Screenshot of furnace formspec, labelled.
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/formspec_example.png" alt="Furnace Inventory">
|
||||
<figcaption>
|
||||
Screenshot of furnace formspec, labelled.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
In this chapter we will learn how to create a formspec and display it to the user.
|
||||
@ -32,7 +32,7 @@ tend to disrupt game play.
|
||||
Formspecs have a rather weird syntax.
|
||||
They consist of a series of tags which are in the following form:
|
||||
|
||||
element_type[param1;param2;...]
|
||||
element_type[param1;param2;...]
|
||||
|
||||
Firstly the element type is declared, and then the attributes are given
|
||||
in square brackets.
|
||||
@ -42,7 +42,7 @@ as size or background).
|
||||
|
||||
Here are two elements, of types foo and bar.
|
||||
|
||||
foo[param1]bar[param1]
|
||||
foo[param1]bar[param1]
|
||||
|
||||
### Size[w, h]
|
||||
|
||||
@ -53,7 +53,7 @@ The reason this is used is because it is independent on screen resolution -
|
||||
The form should work just as well on large screens as small screens.
|
||||
You can use decimals in sizes and co-ordinates.
|
||||
|
||||
size[5,2]
|
||||
size[5,2]
|
||||
|
||||
Co-ordinates and sizes only use one attribute.
|
||||
The x and y values are separated by a comma, as you can see above.
|
||||
@ -64,7 +64,7 @@ This is a textbox element. Most other elements have a similar style of attribute
|
||||
The "name" attribute is used in callbacks to get the submitted information.
|
||||
The others are pretty self-explaintary.
|
||||
|
||||
field[1,1;3,1;firstname;Firstname;]
|
||||
field[1,1;3,1;firstname;Firstname;]
|
||||
|
||||
It is perfectly valid to not define an attribute, like above.
|
||||
|
||||
@ -78,7 +78,7 @@ It is near line 1019, at time of writing.
|
||||
|
||||
Here is a generalized way to show a formspec
|
||||
|
||||
minetest.show_formspec(playername, formname, formspec)
|
||||
minetest.show_formspec(playername, formname, formspec)
|
||||
|
||||
Formnames should be itemnames, however that is not enforced.
|
||||
There is no need to override a formspec here, formspecs are not registered like
|
||||
@ -90,23 +90,23 @@ and see if the callback is relevant.
|
||||
### Example
|
||||
|
||||
<figure class="right_image">
|
||||
<img src="{{ page.root }}/static/formspec_name.png" alt="Name Formspec">
|
||||
<figcaption>
|
||||
The formspec generated by<br />
|
||||
the example's code
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/formspec_name.png" alt="Name Formspec">
|
||||
<figcaption>
|
||||
The formspec generated by<br />
|
||||
the example's code
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
{% highlight lua %}
|
||||
-- Show form when the /formspec command is used.
|
||||
minetest.register_chatcommand("formspec", {
|
||||
func = function(name, param)
|
||||
minetest.show_formspec(name, "mymod:form",
|
||||
"size[4,3]" ..
|
||||
"label[0,0;Hello, " .. name .. "]" ..
|
||||
"field[1,1.5;3,1;name;Name;]" ..
|
||||
"button_exit[1,2;2,1;exit;Save]")
|
||||
end
|
||||
func = function(name, param)
|
||||
minetest.show_formspec(name, "mymod:form",
|
||||
"size[4,3]" ..
|
||||
"label[0,0;Hello, " .. name .. "]" ..
|
||||
"field[1,1.5;3,1;name;Name;]" ..
|
||||
"button_exit[1,2;2,1;exit;Save]")
|
||||
end
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -126,29 +126,29 @@ Let's expand on the above example.
|
||||
{% highlight lua %}
|
||||
-- Show form when the /formspec command is used.
|
||||
minetest.register_chatcommand("formspec", {
|
||||
func = function(name, param)
|
||||
minetest.show_formspec(name, "mymod:form",
|
||||
"size[4,3]" ..
|
||||
"label[0,0;Hello, " .. name .. "]" ..
|
||||
"field[1,1.5;3,1;name;Name;]" ..
|
||||
"button_exit[1,2;2,1;exit;Save]")
|
||||
end
|
||||
func = function(name, param)
|
||||
minetest.show_formspec(name, "mymod:form",
|
||||
"size[4,3]" ..
|
||||
"label[0,0;Hello, " .. name .. "]" ..
|
||||
"field[1,1.5;3,1;name;Name;]" ..
|
||||
"button_exit[1,2;2,1;exit;Save]")
|
||||
end
|
||||
})
|
||||
|
||||
-- Register callback
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "mymod:form" then
|
||||
-- Formname is not mymod:form,
|
||||
-- exit callback.
|
||||
return false
|
||||
end
|
||||
if formname ~= "mymod:form" then
|
||||
-- Formname is not mymod:form,
|
||||
-- exit callback.
|
||||
return false
|
||||
end
|
||||
|
||||
-- Send message to player.
|
||||
minetest.chat_send_player(player:get_player_name(), "You said: " .. fields.name .. "!")
|
||||
-- Send message to player.
|
||||
minetest.chat_send_player(player:get_player_name(), "You said: " .. fields.name .. "!")
|
||||
|
||||
-- Return true to stop other minetest.register_on_player_receive_fields
|
||||
-- from receiving this submission.
|
||||
return true
|
||||
-- Return true to stop other minetest.register_on_player_receive_fields
|
||||
-- from receiving this submission.
|
||||
return true
|
||||
end)
|
||||
{% endhighlight %}
|
||||
|
||||
@ -176,8 +176,8 @@ for a clicked button.
|
||||
-- An example of what fields could contain,
|
||||
-- using the above code
|
||||
{
|
||||
name = "Foo Bar",
|
||||
exit = true
|
||||
name = "Foo Bar",
|
||||
exit = true
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
@ -198,21 +198,21 @@ Let's say you are making a form to handle land protection information.
|
||||
local land_formspec_context = {}
|
||||
|
||||
minetest.register_chatcommand("land", {
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
minetest.chat_send_player(name, "Incorrect parameters - supply a land ID")
|
||||
return
|
||||
end
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
minetest.chat_send_player(name, "Incorrect parameters - supply a land ID")
|
||||
return
|
||||
end
|
||||
|
||||
-- Save information
|
||||
land_formspec_context[name] = {id = param}
|
||||
-- Save information
|
||||
land_formspec_context[name] = {id = param}
|
||||
|
||||
minetest.show_formspec(name, "mylandowner:edit",
|
||||
"size[4,4]" ..
|
||||
"field[1,1;3,1;plot;Plot Name;]" ..
|
||||
"field[1,2;3,1;owner;Owner;]" ..
|
||||
"button_exit[1,3;2,1;exit;Save]")
|
||||
end
|
||||
minetest.show_formspec(name, "mylandowner:edit",
|
||||
"size[4,4]" ..
|
||||
"field[1,1;3,1;plot;Plot Name;]" ..
|
||||
"field[1,2;3,1;owner;Owner;]" ..
|
||||
"button_exit[1,3;2,1;exit;Save]")
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
@ -221,25 +221,25 @@ minetest.register_chatcommand("land", {
|
||||
-- Step 2) retrieve context when player submits the form
|
||||
--
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "mylandowner:edit" then
|
||||
return false
|
||||
end
|
||||
if formname ~= "mylandowner:edit" then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Load information
|
||||
local context = land_formspec_context[player:get_player_name()]
|
||||
-- Load information
|
||||
local context = land_formspec_context[player:get_player_name()]
|
||||
|
||||
if context then
|
||||
minetest.chat_send_player(player:get_player_name(), "Id " .. context.id .. " is now called " ..
|
||||
fields.plot .. " and owned by " .. fields.owner)
|
||||
if context then
|
||||
minetest.chat_send_player(player:get_player_name(), "Id " .. context.id .. " is now called " ..
|
||||
fields.plot .. " and owned by " .. fields.owner)
|
||||
|
||||
-- Delete context if it is no longer going to be used
|
||||
land_formspec_context[player:get_player_name()] = nil
|
||||
-- Delete context if it is no longer going to be used
|
||||
land_formspec_context[player:get_player_name()] = nil
|
||||
|
||||
return true
|
||||
else
|
||||
-- Fail gracefully if the context does not exist.
|
||||
minetest.chat_send_player(player:get_player_name(), "Something went wrong, try again.")
|
||||
end
|
||||
return true
|
||||
else
|
||||
-- Fail gracefully if the context does not exist.
|
||||
minetest.chat_send_player(player:get_player_name(), "Something went wrong, try again.")
|
||||
end
|
||||
end)
|
||||
{% endhighlight %}
|
||||
|
||||
@ -252,20 +252,20 @@ the player the chest formspec.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("mymod:rightclick", {
|
||||
description = "Rightclick me!",
|
||||
tiles = {"mymod_rightclick.png"},
|
||||
groups = {cracky = 1},
|
||||
after_place_node = function(pos, placer)
|
||||
-- This function is run when the chest node is placed.
|
||||
-- The following code sets the formspec for chest.
|
||||
-- Meta is a way of storing data onto a node.
|
||||
description = "Rightclick me!",
|
||||
tiles = {"mymod_rightclick.png"},
|
||||
groups = {cracky = 1},
|
||||
after_place_node = function(pos, placer)
|
||||
-- This function is run when the chest node is placed.
|
||||
-- The following code sets the formspec for chest.
|
||||
-- Meta is a way of storing data onto a node.
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"size[5,5]"..
|
||||
"label[1,1;This is shown on right click]"..
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"size[5,5]"..
|
||||
"label[1,1;This is shown on right click]"..
|
||||
"field[1,2;2,1;x;x;]")
|
||||
end,
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if(fields.quit) then return end
|
||||
print(fields.x)
|
||||
|
@ -5,10 +5,10 @@ root: ../../
|
||||
---
|
||||
|
||||
<div class="notice">
|
||||
<h2>Experimental Feature</h2>
|
||||
<h2>Experimental Feature</h2>
|
||||
|
||||
The HUD feature will probably be rewritten in an upcoming Minetest release.
|
||||
Be aware that you may need to update your mods if the API is changed.
|
||||
The HUD feature will probably be rewritten in an upcoming Minetest release.
|
||||
Be aware that you may need to update your mods if the API is changed.
|
||||
</div>
|
||||
|
||||
## Introduction
|
||||
@ -84,11 +84,11 @@ Here is our earlier example, but with comments to explain each part:
|
||||
|
||||
{% highlight lua %}
|
||||
local idx = player:hud_add({
|
||||
hud_elem_type = "text", -- This is a text element
|
||||
position = {x = 1, y = 0},
|
||||
offset = {x=-100, y = 20},
|
||||
scale = {x = 100, y = 100}, -- Maximum size of text, crops off any out of these bounds
|
||||
text = "My Text" -- The actual text shown
|
||||
hud_elem_type = "text", -- This is a text element
|
||||
position = {x = 1, y = 0},
|
||||
offset = {x=-100, y = 20},
|
||||
scale = {x = 100, y = 100}, -- Maximum size of text, crops off any out of these bounds
|
||||
text = "My Text" -- The actual text shown
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -99,12 +99,12 @@ Colors are in [Hexadecimal form](http://www.colorpicker.com/).
|
||||
|
||||
{% highlight lua %}
|
||||
local idx = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = {x = 1, y = 0},
|
||||
offset = {x=-100, y = 20},
|
||||
scale = {x = 100, y = 100},
|
||||
text = "My Text",
|
||||
number = 0xFF0000 -- Red
|
||||
hud_elem_type = "text",
|
||||
position = {x = 1, y = 0},
|
||||
offset = {x=-100, y = 20},
|
||||
scale = {x = 100, y = 100},
|
||||
text = "My Text",
|
||||
number = 0xFF0000 -- Red
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -13,21 +13,21 @@ This chapter assumes that you already know how to create and manipulate
|
||||
|
||||
* Basic Concepts.
|
||||
* Types of Inventories.
|
||||
* Player Inventories.
|
||||
* Node Inventories.
|
||||
* Detached Inventories.
|
||||
* Player Inventories.
|
||||
* Node Inventories.
|
||||
* Detached Inventories.
|
||||
* InvRef and Lists.
|
||||
* Type of inventory.
|
||||
* List sizes.
|
||||
* List is empty.
|
||||
* Lua Tables.
|
||||
* Lua Tables for Lists.
|
||||
* Type of inventory.
|
||||
* List sizes.
|
||||
* List is empty.
|
||||
* Lua Tables.
|
||||
* Lua Tables for Lists.
|
||||
* InvRef, Items and Stacks.
|
||||
* Adding to a list.
|
||||
* Checking for room.
|
||||
* Taking items.
|
||||
* Contains.
|
||||
* Manipulating Stacks.
|
||||
* Adding to a list.
|
||||
* Checking for room.
|
||||
* Taking items.
|
||||
* Contains.
|
||||
* Manipulating Stacks.
|
||||
|
||||
## Basic Concepts
|
||||
|
||||
@ -45,17 +45,17 @@ There are three ways you can get inventories:
|
||||
* **Detached Inventories** - an inventory which is not attached to a node or player.
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}/static/inventories_lists.png" alt="The player inventory formspec, with annotated list names.">
|
||||
<figcaption>
|
||||
This image shows the two inventories visible when you press i.
|
||||
The gray boxes are inventory lists.<br />
|
||||
The creative inventory, left (in red) is detached and it made up of a
|
||||
single list.<br />
|
||||
The player inventory, right (in blue) is a player inventory
|
||||
and is made up of three lists.<br />
|
||||
Note that the trash can is a <a href="formspecs.html">formspec</a>
|
||||
element, and is not part of the inventory.
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/inventories_lists.png" alt="The player inventory formspec, with annotated list names.">
|
||||
<figcaption>
|
||||
This image shows the two inventories visible when you press i.
|
||||
The gray boxes are inventory lists.<br />
|
||||
The creative inventory, left (in red) is detached and it made up of a
|
||||
single list.<br />
|
||||
The player inventory, right (in blue) is a player inventory
|
||||
and is made up of three lists.<br />
|
||||
Note that the trash can is a <a href="formspecs.html">formspec</a>
|
||||
element, and is not part of the inventory.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
|
||||
@ -124,11 +124,11 @@ They also have a width, which is used to divide them into a grid.
|
||||
|
||||
{% highlight lua %}
|
||||
if inv:set_size("main", 32) then
|
||||
inv:set_width("main", 8)
|
||||
print("size: " .. inv.get_size("main"))
|
||||
print("width: " .. inv:get_width("main"))
|
||||
inv:set_width("main", 8)
|
||||
print("size: " .. inv.get_size("main"))
|
||||
print("width: " .. inv:get_width("main"))
|
||||
else
|
||||
print("Error!")
|
||||
print("Error!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -140,7 +140,7 @@ a list doesn't have a width or height, only the maximum number of stacks/slots.-
|
||||
|
||||
{% highlight lua %}
|
||||
if inv:is_empty("main") then
|
||||
print("The list is empty!")
|
||||
print("The list is empty!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -156,20 +156,20 @@ It will be in this form:
|
||||
|
||||
{% highlight lua %}
|
||||
{
|
||||
list_one = {
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
-- inv:get_size("list_one") elements
|
||||
},
|
||||
list_two = {
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
-- inv:get_size("list_two") elements
|
||||
}
|
||||
list_one = {
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
-- inv:get_size("list_one") elements
|
||||
},
|
||||
list_two = {
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
-- inv:get_size("list_two") elements
|
||||
}
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
@ -193,11 +193,11 @@ It will be in this form:
|
||||
|
||||
{% highlight lua %}
|
||||
{
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
-- inv:get_size("list_one") elements
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
ItemStack,
|
||||
-- inv:get_size("list_one") elements
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
@ -217,7 +217,7 @@ Please note that the sizes of lists will not change.
|
||||
local stack = ItemStack("default:stone 99")
|
||||
local leftover = inv:add_item("main", stack)
|
||||
if leftover:get_count() > 0 then
|
||||
print("Inventory is full! " .. leftover:get_count() .. " items weren't added")
|
||||
print("Inventory is full! " .. leftover:get_count() .. " items weren't added")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -227,7 +227,7 @@ end
|
||||
|
||||
{% highlight lua %}
|
||||
if not inv:room_for_item("main", stack) then
|
||||
print("Not enough room!")
|
||||
print("Not enough room!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -246,7 +246,7 @@ are stacks of 99 + 95 + 6.
|
||||
|
||||
{% highlight lua %}
|
||||
if not inv:contains_item(listname, stack) then
|
||||
print("Item not in inventory!")
|
||||
print("Item not in inventory!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -33,9 +33,9 @@ You could alternatively create a blank ItemStack and fill it using methods:
|
||||
{% highlight lua %}
|
||||
local items = ItemStack()
|
||||
if items:set_name("default:dirt") then
|
||||
items:set_count(99)
|
||||
items:set_count(99)
|
||||
else
|
||||
print("An error occured!")
|
||||
print("An error occured!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -57,10 +57,10 @@ print(items:get_name()) -- default:stone
|
||||
print(items:get_count()) -- 99
|
||||
|
||||
if items:set_name("default:dirt") then
|
||||
print(items:get_name()) -- default:dirt
|
||||
print(items:get_count()) -- 99
|
||||
print(items:get_name()) -- default:dirt
|
||||
print(items:get_count()) -- 99
|
||||
else
|
||||
error("This shouldn't happen")
|
||||
error("This shouldn't happen")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -10,10 +10,10 @@ In this chapter we will talk about scripting in Lua, the tools required,
|
||||
and go over some techniques which you will probably find useful.
|
||||
|
||||
* Tools
|
||||
* Recommended Editors
|
||||
* Integrated Programming Environments
|
||||
* Recommended Editors
|
||||
* Integrated Programming Environments
|
||||
* Coding in Lua
|
||||
* Selection
|
||||
* Selection
|
||||
* Programming
|
||||
* Local and Global
|
||||
* Including other Lua Scripts
|
||||
@ -26,17 +26,17 @@ depending on what they mean. This allows you to spot mistakes.
|
||||
|
||||
{% highlight lua %}
|
||||
function ctf.post(team,msg)
|
||||
if not ctf.team(team) then
|
||||
return false
|
||||
end
|
||||
if not ctf.team(team).log then
|
||||
ctf.team(team).log = {}
|
||||
end
|
||||
if not ctf.team(team) then
|
||||
return false
|
||||
end
|
||||
if not ctf.team(team).log then
|
||||
ctf.team(team).log = {}
|
||||
end
|
||||
|
||||
table.insert(ctf.team(team).log,1,msg)
|
||||
ctf.save()
|
||||
table.insert(ctf.team(team).log,1,msg)
|
||||
ctf.save()
|
||||
|
||||
return true
|
||||
return true
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -69,7 +69,7 @@ One such IDE is Eclipse with the Koneki Lua plugin:
|
||||
## Coding in Lua
|
||||
|
||||
<div class="notice">
|
||||
This section is a Work in Progress. May be unclear.
|
||||
This section is a Work in Progress. May be unclear.
|
||||
</div>
|
||||
|
||||
Programs are a series of commands that run one after another.
|
||||
@ -138,9 +138,9 @@ The most basic selection is the if statement. It looks like this:
|
||||
local random_number = math.random(1, 100) -- Between 1 and 100.
|
||||
|
||||
if random_number > 50 then
|
||||
print("Woohoo!")
|
||||
print("Woohoo!")
|
||||
else
|
||||
print("No!")
|
||||
print("No!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -166,7 +166,7 @@ That doesn't contain every possible operator, and you can combine operators like
|
||||
|
||||
{% highlight lua %}
|
||||
if not A and B then
|
||||
print("Yay!")
|
||||
print("Yay!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -180,7 +180,7 @@ local A = 5
|
||||
local is_equal = (A == 5)
|
||||
|
||||
if is_equal then
|
||||
print("Is equal!")
|
||||
print("Is equal!")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -211,13 +211,13 @@ A local variable is only accessible from where it is defined. Here are some exam
|
||||
local one = 1
|
||||
|
||||
function myfunc()
|
||||
-- Accessible from within this function
|
||||
local two = one + one
|
||||
-- Accessible from within this function
|
||||
local two = one + one
|
||||
|
||||
if two == one then
|
||||
-- Accessible from within this if statement
|
||||
local three = one + two
|
||||
end
|
||||
if two == one then
|
||||
-- Accessible from within this if statement
|
||||
local three = one + two
|
||||
end
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -227,7 +227,7 @@ Whereas global variables can be accessed from anywhere in the script file, and f
|
||||
my_global_variable = "blah"
|
||||
|
||||
function one()
|
||||
my_global_variable = "three"
|
||||
my_global_variable = "three"
|
||||
end
|
||||
|
||||
print(my_global_variable) -- Output: "blah"
|
||||
@ -243,11 +243,11 @@ Local variables must be identified as such.
|
||||
|
||||
{% highlight lua %}
|
||||
function one()
|
||||
foo = "bar"
|
||||
foo = "bar"
|
||||
end
|
||||
|
||||
function two()
|
||||
print(dump(foo)) -- Output: "bar"
|
||||
print(dump(foo)) -- Output: "bar"
|
||||
end
|
||||
|
||||
one()
|
||||
@ -260,17 +260,17 @@ which show it is a string.
|
||||
|
||||
This is sloppy coding, and Minetest will in fact warn you about this:
|
||||
|
||||
[WARNING] Assigment to undeclared global 'foo' inside function at init.lua:2
|
||||
[WARNING] Assigment to undeclared global 'foo' inside function at init.lua:2
|
||||
|
||||
To correct this, use "local":
|
||||
|
||||
{% highlight lua %}
|
||||
function one()
|
||||
local foo = "bar"
|
||||
local foo = "bar"
|
||||
end
|
||||
|
||||
function two()
|
||||
print(dump(foo)) -- Output: nil
|
||||
print(dump(foo)) -- Output: nil
|
||||
end
|
||||
|
||||
one()
|
||||
@ -286,7 +286,7 @@ as other mods could have functions of the same name.
|
||||
|
||||
{% highlight lua %}
|
||||
local function foo(bar)
|
||||
return bar * 2
|
||||
return bar * 2
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -297,7 +297,7 @@ you add them all into a table with the same name as the mod:
|
||||
mymod = {}
|
||||
|
||||
function mymod.foo(bar)
|
||||
return "foo" .. bar
|
||||
return "foo" .. bar
|
||||
end
|
||||
|
||||
-- In another mod, or script:
|
||||
|
@ -5,10 +5,10 @@ root: ../../
|
||||
---
|
||||
|
||||
<div class="notice">
|
||||
<h2>This chapter is incomplete</h2>
|
||||
<h2>This chapter is incomplete</h2>
|
||||
|
||||
Some drawtypes have not been explained yet,
|
||||
and placeholder images are being used.
|
||||
Some drawtypes have not been explained yet,
|
||||
and placeholder images are being used.
|
||||
</div>
|
||||
|
||||
## Introduction
|
||||
@ -25,12 +25,12 @@ the title of the sections, except in lower case.
|
||||
* Normal
|
||||
* Airlike
|
||||
* Liquid
|
||||
* FlowingLiquid
|
||||
* FlowingLiquid
|
||||
* Glasslike
|
||||
* Glasslike_Framed
|
||||
* Glasslike_Framed_Optional
|
||||
* Glasslike_Framed_Optional
|
||||
* Allfaces
|
||||
* Allfaces_Optional
|
||||
* Allfaces_Optional
|
||||
* Torchlike
|
||||
* Nodebox
|
||||
|
||||
@ -46,10 +46,10 @@ This article is not complete yet. These drawtypes are missing:
|
||||
## Normal
|
||||
|
||||
<figure class="right_image">
|
||||
<img src="{{ page.root }}/static/drawtype_normal.png" alt="Normal Drawtype">
|
||||
<figcaption>
|
||||
Normal Drawtype
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/drawtype_normal.png" alt="Normal Drawtype">
|
||||
<figcaption>
|
||||
Normal Drawtype
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
This is, well, the normal drawtypes.
|
||||
@ -59,18 +59,18 @@ Notice how you don't need to declare the drawtype.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("mymod:diamond", {
|
||||
description = "Alien Diamond",
|
||||
tiles = {
|
||||
"mymod_diamond_up.png",
|
||||
"mymod_diamond_down.png",
|
||||
"mymod_diamond_right.png",
|
||||
"mymod_diamond_left.png",
|
||||
"mymod_diamond_back.png",
|
||||
"mymod_diamond_front.png"
|
||||
},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3},
|
||||
drop = "mymod:diamond_fragments"
|
||||
description = "Alien Diamond",
|
||||
tiles = {
|
||||
"mymod_diamond_up.png",
|
||||
"mymod_diamond_down.png",
|
||||
"mymod_diamond_right.png",
|
||||
"mymod_diamond_left.png",
|
||||
"mymod_diamond_back.png",
|
||||
"mymod_diamond_front.png"
|
||||
},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3},
|
||||
drop = "mymod:diamond_fragments"
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -81,34 +81,34 @@ These nodes are see through and thus have no textures.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("myair:air", {
|
||||
description = "MyAir (you hacker you!)",
|
||||
drawtype = "airlike",
|
||||
description = "MyAir (you hacker you!)",
|
||||
drawtype = "airlike",
|
||||
|
||||
paramtype = "light",
|
||||
-- ^ Allows light to propagate through the node with the
|
||||
-- light value falling by 1 per node.
|
||||
paramtype = "light",
|
||||
-- ^ Allows light to propagate through the node with the
|
||||
-- light value falling by 1 per node.
|
||||
|
||||
sunlight_propagates = true, -- Sunlight shines through
|
||||
walkable = false, -- Would make the player collide with the air node
|
||||
pointable = false, -- You can't select the node
|
||||
diggable = false, -- You can't dig the node
|
||||
buildable_to = true, -- Nodes can be replace this node.
|
||||
-- (you can place a node and remove the air node
|
||||
-- that used to be there)
|
||||
sunlight_propagates = true, -- Sunlight shines through
|
||||
walkable = false, -- Would make the player collide with the air node
|
||||
pointable = false, -- You can't select the node
|
||||
diggable = false, -- You can't dig the node
|
||||
buildable_to = true, -- Nodes can be replace this node.
|
||||
-- (you can place a node and remove the air node
|
||||
-- that used to be there)
|
||||
|
||||
air_equivalent = true,
|
||||
drop = "",
|
||||
groups = {not_in_creative_inventory=1}
|
||||
air_equivalent = true,
|
||||
drop = "",
|
||||
groups = {not_in_creative_inventory=1}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
## Liquid
|
||||
|
||||
<figure class="right_image">
|
||||
<img src="{{ page.root }}/static/drawtype_liquid.png" alt="Liquid Drawtype">
|
||||
<figcaption>
|
||||
Liquid Drawtype
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/drawtype_liquid.png" alt="Liquid Drawtype">
|
||||
<figcaption>
|
||||
Liquid Drawtype
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
These nodes are complete liquid nodes, the liquid flows outwards from position
|
||||
@ -118,63 +118,63 @@ For each liquid node you should also have a flowing liquid node.
|
||||
{% highlight lua %}
|
||||
-- Some properties have been removed as they are beyond the scope of this chapter.
|
||||
minetest.register_node("default:water_source", {
|
||||
drawtype = "liquid",
|
||||
paramtype = "light",
|
||||
drawtype = "liquid",
|
||||
paramtype = "light",
|
||||
|
||||
inventory_image = minetest.inventorycube("default_water.png"),
|
||||
-- ^ this is required to stop the inventory image from being animated
|
||||
inventory_image = minetest.inventorycube("default_water.png"),
|
||||
-- ^ this is required to stop the inventory image from being animated
|
||||
|
||||
tiles = {
|
||||
{
|
||||
name = "default_water_source_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 2.0
|
||||
}
|
||||
}
|
||||
},
|
||||
tiles = {
|
||||
{
|
||||
name = "default_water_source_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 2.0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
special_tiles = {
|
||||
-- New-style water source material (mostly unused)
|
||||
{
|
||||
name = "default_water_source_animated.png",
|
||||
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0},
|
||||
backface_culling = false,
|
||||
}
|
||||
},
|
||||
special_tiles = {
|
||||
-- New-style water source material (mostly unused)
|
||||
{
|
||||
name = "default_water_source_animated.png",
|
||||
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0},
|
||||
backface_culling = false,
|
||||
}
|
||||
},
|
||||
|
||||
--
|
||||
-- Behavior
|
||||
--
|
||||
walkable = false, -- The player falls through
|
||||
pointable = false, -- The player can't highlight it
|
||||
diggable = false, -- The player can't dig it
|
||||
buildable_to = true, -- Nodes can be replace this node
|
||||
--
|
||||
-- Behavior
|
||||
--
|
||||
walkable = false, -- The player falls through
|
||||
pointable = false, -- The player can't highlight it
|
||||
diggable = false, -- The player can't dig it
|
||||
buildable_to = true, -- Nodes can be replace this node
|
||||
|
||||
alpha = 160,
|
||||
alpha = 160,
|
||||
|
||||
--
|
||||
-- Liquid Properties
|
||||
--
|
||||
drowning = 1,
|
||||
liquidtype = "source",
|
||||
--
|
||||
-- Liquid Properties
|
||||
--
|
||||
drowning = 1,
|
||||
liquidtype = "source",
|
||||
|
||||
liquid_alternative_flowing = "default:water_flowing",
|
||||
-- ^ when the liquid is flowing
|
||||
liquid_alternative_flowing = "default:water_flowing",
|
||||
-- ^ when the liquid is flowing
|
||||
|
||||
liquid_alternative_source = "default:water_source",
|
||||
-- ^ when the liquid is a source
|
||||
liquid_alternative_source = "default:water_source",
|
||||
-- ^ when the liquid is a source
|
||||
|
||||
liquid_viscosity = WATER_VISC,
|
||||
-- ^ how fast
|
||||
liquid_viscosity = WATER_VISC,
|
||||
-- ^ how fast
|
||||
|
||||
liquid_range = 8,
|
||||
-- ^ how far
|
||||
liquid_range = 8,
|
||||
-- ^ how far
|
||||
|
||||
post_effect_color = {a=64, r=100, g=100, b=200},
|
||||
-- ^ color of screen when the player is submerged
|
||||
post_effect_color = {a=64, r=100, g=100, b=200},
|
||||
-- ^ color of screen when the player is submerged
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -186,32 +186,32 @@ the same as the above example.
|
||||
## Glasslike
|
||||
|
||||
<figure class="right_image">
|
||||
<img src="{{ page.root }}/static/drawtype_glasslike.png" alt="Glasslike Drawtype">
|
||||
<figcaption>
|
||||
Glasslike Drawtype
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/drawtype_glasslike.png" alt="Glasslike Drawtype">
|
||||
<figcaption>
|
||||
Glasslike Drawtype
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
When you place multiple glasslike nodes together, you'll notice that the internal
|
||||
edges are hidden, like this:
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}/static/drawtype_glasslike_edges.png" alt="Glasslike's Edges">
|
||||
<figcaption>
|
||||
Glasslike's Edges
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/drawtype_glasslike_edges.png" alt="Glasslike's Edges">
|
||||
<figcaption>
|
||||
Glasslike's Edges
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("default:obsidian_glass", {
|
||||
description = "Obsidian Glass",
|
||||
drawtype = "glasslike",
|
||||
tiles = {"default_obsidian_glass.png"},
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
sunlight_propagates = true,
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
groups = {cracky=3,oddly_breakable_by_hand=3},
|
||||
description = "Obsidian Glass",
|
||||
drawtype = "glasslike",
|
||||
tiles = {"default_obsidian_glass.png"},
|
||||
paramtype = "light",
|
||||
is_ground_content = false,
|
||||
sunlight_propagates = true,
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
groups = {cracky=3,oddly_breakable_by_hand=3},
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -221,26 +221,26 @@ This makes the node's edge go around the whole thing with a 3D effect, rather
|
||||
than individual nodes, like the following:
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}/static/drawtype_glasslike_framed.png" alt="Glasslike_framed's Edges">
|
||||
<figcaption>
|
||||
Glasslike_Framed's Edges
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/drawtype_glasslike_framed.png" alt="Glasslike_framed's Edges">
|
||||
<figcaption>
|
||||
Glasslike_Framed's Edges
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("default:glass", {
|
||||
description = "Glass",
|
||||
drawtype = "glasslike_framed",
|
||||
description = "Glass",
|
||||
drawtype = "glasslike_framed",
|
||||
|
||||
tiles = {"default_glass.png", "default_glass_detail.png"},
|
||||
inventory_image = minetest.inventorycube("default_glass.png"),
|
||||
tiles = {"default_glass.png", "default_glass_detail.png"},
|
||||
inventory_image = minetest.inventorycube("default_glass.png"),
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true, -- Sunlight can shine through block
|
||||
is_ground_content = false, -- Stops caves from being generated over this node.
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true, -- Sunlight can shine through block
|
||||
is_ground_content = false, -- Stops caves from being generated over this node.
|
||||
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
||||
sounds = default.node_sound_glass_defaults()
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
||||
sounds = default.node_sound_glass_defaults()
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -251,10 +251,10 @@ minetest.register_node("default:glass", {
|
||||
## Allfaces
|
||||
|
||||
<figure class="right_image">
|
||||
<img src="{{ page.root }}/static/drawtype_allfaces.png" alt="Allfaces drawtype">
|
||||
<figcaption>
|
||||
Allfaces drawtype
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/drawtype_allfaces.png" alt="Allfaces drawtype">
|
||||
<figcaption>
|
||||
Allfaces drawtype
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
Allfaces nodes are partially transparent nodes - they have holes on
|
||||
@ -264,9 +264,9 @@ Leaves in vanilla minetest_game use this drawtype.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("default:leaves", {
|
||||
description = "Leaves",
|
||||
drawtype = "allfaces_optional",
|
||||
tiles = {"default_leaves.png"}
|
||||
description = "Leaves",
|
||||
drawtype = "allfaces_optional",
|
||||
tiles = {"default_leaves.png"}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -285,38 +285,38 @@ items which need to have different textures depending on where they are placed.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("foobar:torch", {
|
||||
description = "Foobar Torch",
|
||||
drawtype = "torchlike",
|
||||
tiles = {
|
||||
{"foobar_torch_floor.png"},
|
||||
{"foobar_torch_ceiling.png"},
|
||||
{"foobar_torch_wall.png"}
|
||||
},
|
||||
inventory_image = "foobar_torch_floor.png",
|
||||
wield_image = "default_torch_floor.png",
|
||||
light_source = LIGHT_MAX-1,
|
||||
description = "Foobar Torch",
|
||||
drawtype = "torchlike",
|
||||
tiles = {
|
||||
{"foobar_torch_floor.png"},
|
||||
{"foobar_torch_ceiling.png"},
|
||||
{"foobar_torch_wall.png"}
|
||||
},
|
||||
inventory_image = "foobar_torch_floor.png",
|
||||
wield_image = "default_torch_floor.png",
|
||||
light_source = LIGHT_MAX-1,
|
||||
|
||||
-- Determines how the torch is selected, ie: the wire box around it.
|
||||
-- each value is { x1, y1, z1, x2, y2, z2 }
|
||||
-- (x1, y1, y1) is the bottom front left corner
|
||||
-- (x2, y2, y2) is the opposite - top back right.
|
||||
-- Similar to the nodebox format.
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
|
||||
wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
|
||||
wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
|
||||
}
|
||||
-- Determines how the torch is selected, ie: the wire box around it.
|
||||
-- each value is { x1, y1, z1, x2, y2, z2 }
|
||||
-- (x1, y1, y1) is the bottom front left corner
|
||||
-- (x2, y2, y2) is the opposite - top back right.
|
||||
-- Similar to the nodebox format.
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
|
||||
wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
|
||||
wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
|
||||
}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
## Nodebox
|
||||
|
||||
<figure class="right_image">
|
||||
<img src="{{ page.root }}/static/drawtype_nodebox.gif" alt="Nodebox drawtype">
|
||||
<figcaption>
|
||||
Nodebox drawtype
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/drawtype_nodebox.gif" alt="Nodebox drawtype">
|
||||
<figcaption>
|
||||
Nodebox drawtype
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
Nodeboxes allow you to create a node which is not cubic, but is instead made out
|
||||
@ -324,15 +324,15 @@ of as many cuboids as you like.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("stairs:stair_stone", {
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
||||
{-0.5, 0, 0, 0.5, 0.5, 0.5},
|
||||
},
|
||||
}
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
||||
{-0.5, 0, 0, 0.5, 0.5, 0.5},
|
||||
},
|
||||
}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -357,24 +357,24 @@ Sometimes you want different nodeboxes for when it is placed on the floor, wall,
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("default:sign_wall", {
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "wallmounted",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "wallmounted",
|
||||
|
||||
-- Ceiling
|
||||
wall_top = {
|
||||
{-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}
|
||||
},
|
||||
-- Ceiling
|
||||
wall_top = {
|
||||
{-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}
|
||||
},
|
||||
|
||||
-- Floor
|
||||
wall_bottom = {
|
||||
{-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}
|
||||
},
|
||||
-- Floor
|
||||
wall_bottom = {
|
||||
{-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}
|
||||
},
|
||||
|
||||
-- Wall
|
||||
wall_side = {
|
||||
{-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}
|
||||
}
|
||||
},
|
||||
-- Wall
|
||||
wall_side = {
|
||||
{-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}
|
||||
}
|
||||
},
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
@ -53,11 +53,11 @@ local meta = minetest.get_meta(pos)
|
||||
local value = meta:get_string("key")
|
||||
|
||||
if value then
|
||||
print(value)
|
||||
print(value)
|
||||
else
|
||||
-- value == nil
|
||||
-- metadata of key "key" does not exist
|
||||
print(value)
|
||||
-- value == nil
|
||||
-- metadata of key "key" does not exist
|
||||
print(value)
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -75,9 +75,9 @@ In order to do booleans, you should use `get_string` and `minetest.is_yes`:
|
||||
local value = minetest.is_yes(meta:get_string("key"))
|
||||
|
||||
if value then
|
||||
print("is yes")
|
||||
print("is yes")
|
||||
else
|
||||
print("is no")
|
||||
print("is no")
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -23,7 +23,7 @@ Each item, whether that be a node, craftitem, tool, or entity, has an item strin
|
||||
This is sometimes referred to as registered name or just name.
|
||||
A string in programming terms is a piece of text.
|
||||
|
||||
modname:itemname
|
||||
modname:itemname
|
||||
|
||||
The modname is the name of the folder your mod is in.
|
||||
You may call the itemname anything you like; however, it should be relevant to
|
||||
@ -55,8 +55,8 @@ They are used in recipes to create other items, or they can be used by the playe
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craftitem("mymod:diamond_fragments", {
|
||||
description = "Alien Diamond Fragments",
|
||||
inventory_image = "mymod_diamond_fragments.png"
|
||||
description = "Alien Diamond Fragments",
|
||||
inventory_image = "mymod_diamond_fragments.png"
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -70,9 +70,9 @@ Foods are items that cure health. To create a food item you need to define the o
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craftitem("mymod:mudpie", {
|
||||
description = "Alien Mud Pie",
|
||||
inventory_image = "myfood_mudpie.png",
|
||||
on_use = minetest.item_eat(20)
|
||||
description = "Alien Mud Pie",
|
||||
inventory_image = "myfood_mudpie.png",
|
||||
on_use = minetest.item_eat(20)
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -83,7 +83,7 @@ Hitpoints don't have to be integers (whole numbers), they can be decimals.
|
||||
Sometimes you may want a food to be replaced with another item when being eaten,
|
||||
for example smaller pieces of cake or bones after eating meat. To do this, use:
|
||||
|
||||
minetest.item_eat(hp, replace_with_item)
|
||||
minetest.item_eat(hp, replace_with_item)
|
||||
|
||||
Where replace_with_item is an item string.
|
||||
|
||||
@ -94,28 +94,28 @@ such as send a message to the player?
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craftitem("mymod:mudpie", {
|
||||
description = "Alien Mud Pie",
|
||||
inventory_image = "myfood_mudpie.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
hp_change = 20
|
||||
replace_with_item = nil
|
||||
description = "Alien Mud Pie",
|
||||
inventory_image = "myfood_mudpie.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
hp_change = 20
|
||||
replace_with_item = nil
|
||||
|
||||
minetest.chat_send_player(user:get_player_name(), "You ate an alien mud pie!")
|
||||
minetest.chat_send_player(user:get_player_name(), "You ate an alien mud pie!")
|
||||
|
||||
-- Support for hunger mods using minetest.register_on_item_eat
|
||||
for _ , callback in pairs(minetest.registered_on_item_eats) do
|
||||
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
||||
if result then
|
||||
return result
|
||||
end
|
||||
end
|
||||
-- Support for hunger mods using minetest.register_on_item_eat
|
||||
for _ , callback in pairs(minetest.registered_on_item_eats) do
|
||||
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
||||
if result then
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
if itemstack:take_item() ~= nil then
|
||||
user:set_hp(user:get_hp() + hp_change)
|
||||
end
|
||||
if itemstack:take_item() ~= nil then
|
||||
user:set_hp(user:get_hp() + hp_change)
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -133,10 +133,10 @@ definition table; however, you need to set the textures for the faces of the cub
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("mymod:diamond", {
|
||||
description = "Alien Diamond",
|
||||
tiles = {"mymod_diamond.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=3, stone=1}
|
||||
description = "Alien Diamond",
|
||||
tiles = {"mymod_diamond.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=3, stone=1}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -155,19 +155,19 @@ a negative direction means that it is facing negative co-ordinates.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_node("mymod:diamond", {
|
||||
description = "Alien Diamond",
|
||||
tiles = {
|
||||
"mymod_diamond_up.png",
|
||||
"mymod_diamond_down.png",
|
||||
"mymod_diamond_right.png",
|
||||
"mymod_diamond_left.png",
|
||||
"mymod_diamond_back.png",
|
||||
"mymod_diamond_front.png"
|
||||
},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3},
|
||||
drop = "mymod:diamond_fragments"
|
||||
-- ^ Rather than dropping diamond, drop mymod:diamond_fragments
|
||||
description = "Alien Diamond",
|
||||
tiles = {
|
||||
"mymod_diamond_up.png",
|
||||
"mymod_diamond_down.png",
|
||||
"mymod_diamond_right.png",
|
||||
"mymod_diamond_left.png",
|
||||
"mymod_diamond_back.png",
|
||||
"mymod_diamond_front.png"
|
||||
},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3},
|
||||
drop = "mymod:diamond_fragments"
|
||||
-- ^ Rather than dropping diamond, drop mymod:diamond_fragments
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -182,7 +182,7 @@ identified by the ``type`` property.
|
||||
* shapeless - It doesn't matter where the ingredients are,
|
||||
just that there is the right amount.
|
||||
* cooking - Recipes for the furnace to use.
|
||||
* fuel - Defines items which can be burned in furnaces.
|
||||
* fuel - Defines items which can be burned in furnaces.
|
||||
* tool_repair - Used to allow the repairing of tools.
|
||||
|
||||
Craft recipes do not use Item Strings to uniquely identify themselves.
|
||||
@ -196,12 +196,12 @@ right place for it to work.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craft({
|
||||
output = "mymod:diamond_chair 99",
|
||||
recipe = {
|
||||
{"mymod:diamond_fragments", "", ""},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments", ""},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments", ""}
|
||||
}
|
||||
output = "mymod:diamond_chair 99",
|
||||
recipe = {
|
||||
{"mymod:diamond_fragments", "", ""},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments", ""},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments", ""}
|
||||
}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -219,12 +219,12 @@ allows the recipe to be crafted if it was all moved one place to the right.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craft({
|
||||
output = "mymod:diamond_chair",
|
||||
recipe = {
|
||||
{"mymod:diamond_fragments", ""},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments"},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments"}
|
||||
}
|
||||
output = "mymod:diamond_chair",
|
||||
recipe = {
|
||||
{"mymod:diamond_fragments", ""},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments"},
|
||||
{"mymod:diamond_fragments", "mymod:diamond_fragments"}
|
||||
}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -237,9 +237,9 @@ need to be in any specific place for it to work.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mymod:diamond",
|
||||
recipe = {"mymod:diamond_fragments", "mymod:diamond_fragments", "mymod:diamond_fragments"}
|
||||
type = "shapeless",
|
||||
output = "mymod:diamond",
|
||||
recipe = {"mymod:diamond_fragments", "mymod:diamond_fragments", "mymod:diamond_fragments"}
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -256,10 +256,10 @@ For example, you use a cooking recipe to turn ores into bars.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "mymod:diamond_fragments",
|
||||
recipe = "default:coalblock",
|
||||
cooktime = 10,
|
||||
type = "cooking",
|
||||
output = "mymod:diamond_fragments",
|
||||
recipe = "default:coalblock",
|
||||
cooktime = 10,
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -279,9 +279,9 @@ what can be burned in furnaces and other cooking tools from mods.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "mymod:diamond",
|
||||
burntime = 300,
|
||||
type = "fuel",
|
||||
recipe = "mymod:diamond",
|
||||
burntime = 300,
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -21,13 +21,13 @@ puts the caller in low G:
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_chatcommand("antigravity", {
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
player:set_physics_override({
|
||||
gravity = 0.1 -- set gravity to 10% of its original value
|
||||
-- (0.1 * 9.81)
|
||||
})
|
||||
end
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
player:set_physics_override({
|
||||
gravity = 0.1 -- set gravity to 10% of its original value
|
||||
-- (0.1 * 9.81)
|
||||
})
|
||||
end
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
|
@ -44,8 +44,8 @@ given to them.
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_privilege("vote", {
|
||||
description = "Can vote on issues",
|
||||
give_to_singleplayer = true
|
||||
description = "Can vote on issues",
|
||||
give_to_singleplayer = true
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -54,7 +54,7 @@ value when not specified:
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.register_privilege("vote", {
|
||||
description = "Can vote on issues"
|
||||
description = "Can vote on issues"
|
||||
})
|
||||
{% endhighlight %}
|
||||
|
||||
@ -64,8 +64,8 @@ There is a quicker way of checking that a player has all the required privileges
|
||||
|
||||
{% highlight lua %}
|
||||
local has, missing = minetest.check_player_privs(player_or_name, {
|
||||
interact = true,
|
||||
vote = true })
|
||||
interact = true,
|
||||
vote = true })
|
||||
{% endhighlight %}
|
||||
|
||||
`has` is true if the player has all the privileges needed.\\
|
||||
@ -74,18 +74,18 @@ of missing privileges<sup>[checking needed]</sup>.
|
||||
|
||||
{% highlight lua %}
|
||||
if minetest.check_player_privs(name, {interact=true, vote=true}) then
|
||||
print("Player has all privs!")
|
||||
print("Player has all privs!")
|
||||
else
|
||||
print("Player is missing some privs!")
|
||||
print("Player is missing some privs!")
|
||||
end
|
||||
|
||||
local has, missing = minetest.check_player_privs(name, {
|
||||
interact = true,
|
||||
vote = true })
|
||||
interact = true,
|
||||
vote = true })
|
||||
if has then
|
||||
print("Player has all privs!")
|
||||
print("Player has all privs!")
|
||||
else
|
||||
print("Player is missing privs: " .. dump(missing))
|
||||
print("Player is missing privs: " .. dump(missing))
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -103,9 +103,9 @@ Running that example may give the following:
|
||||
|
||||
{% highlight lua %}
|
||||
{
|
||||
fly = true,
|
||||
interact = true,
|
||||
shout = true
|
||||
fly = true,
|
||||
interact = true,
|
||||
shout = true
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
@ -113,8 +113,8 @@ To set a player's privs, you use `minetest.set_player_privs`:
|
||||
|
||||
{% highlight lua %}
|
||||
minetest.set_player_privs(name, {
|
||||
interact = true,
|
||||
shout = true })
|
||||
interact = true,
|
||||
shout = true })
|
||||
{% endhighlight %}
|
||||
|
||||
To grant a player some privs, you would use a mixture of those two:
|
||||
@ -128,12 +128,12 @@ minetest.set_player_privs(name, privs)
|
||||
## Adding privileges to basic_privs
|
||||
|
||||
<div class="notice">
|
||||
<h2>Workaround / PR pending</h2>
|
||||
<h2>Workaround / PR pending</h2>
|
||||
|
||||
This is a workaround for a missing feature.
|
||||
I have submitted a
|
||||
<a href="https://github.com/minetest/minetest/pull/3976">pull request / patch</a>
|
||||
to make it so you don't need to edit builtin to add a priv to basic_privs.
|
||||
This is a workaround for a missing feature.
|
||||
I have submitted a
|
||||
<a href="https://github.com/minetest/minetest/pull/3976">pull request / patch</a>
|
||||
to make it so you don't need to edit builtin to add a priv to basic_privs.
|
||||
</div>
|
||||
|
||||
To allow people with basic_privs to grant and revoke your priv, you'll
|
||||
@ -143,8 +143,8 @@ In both grant and revoke, change the following if statement:
|
||||
|
||||
{% highlight lua %}
|
||||
if priv ~= "interact" and priv ~= "shout" and
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
@ -152,7 +152,7 @@ For example, to add vote:
|
||||
|
||||
{% highlight lua %}
|
||||
if priv ~= "interact" and priv ~= "shout" and priv ~= "vote" and
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
@ -42,29 +42,29 @@ You license your code under LGPL 2.1 and your art under CC-BY-SA.
|
||||
|
||||
Add this copyright notice to your README.txt, or as a new file called LICENSE.txt
|
||||
|
||||
License for Code
|
||||
----------------
|
||||
License for Code
|
||||
----------------
|
||||
|
||||
Copyright (C) 2010-2013 Your Name <emailaddress>
|
||||
Copyright (C) 2010-2013 Your Name <emailaddress>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
License for Textures, Models and Sounds
|
||||
---------------------------------------
|
||||
License for Textures, Models and Sounds
|
||||
---------------------------------------
|
||||
|
||||
CC-BY-SA 3.0 UNPORTED. Created by Your Name
|
||||
CC-BY-SA 3.0 UNPORTED. Created by Your Name
|
||||
|
||||
### WTFPL or CC0
|
||||
|
||||
@ -97,8 +97,8 @@ Be concise without being too vague. This is displayed in the mod store.
|
||||
|
||||
For example:
|
||||
|
||||
GOOD: Adds soups, cakes, bakes and juices. The food mod which supports the most ingredients.
|
||||
BAD: The food mod for Minetest.
|
||||
GOOD: Adds soups, cakes, bakes and juices. The food mod which supports the most ingredients.
|
||||
BAD: The food mod for Minetest.
|
||||
|
||||
### screenshot.png
|
||||
|
||||
@ -152,10 +152,10 @@ On the create a topic page, see below, go to the "Upload Attachment" tab at the
|
||||
Click browse and select the zipped file. I suggest that you enter the version of your mod in the comment field.
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}/static/releasing_attachments.png" alt="Upload Attachment">
|
||||
<figcaption>
|
||||
Upload Attachment tab.
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/releasing_attachments.png" alt="Upload Attachment">
|
||||
<figcaption>
|
||||
Upload Attachment tab.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
## Forum Topic
|
||||
@ -184,30 +184,30 @@ You should also include screenshots of your mod in action, if relevant.
|
||||
Here is an example. The Minetest forum uses bbcode for formating.
|
||||
|
||||
|
||||
Adds magic, rainbows and other special things.
|
||||
Adds magic, rainbows and other special things.
|
||||
|
||||
See download attached.
|
||||
See download attached.
|
||||
|
||||
[b]Version:[/b] 1.1
|
||||
[b]License:[/b] LGPL 2.1 or later
|
||||
[b]Version:[/b] 1.1
|
||||
[b]License:[/b] LGPL 2.1 or later
|
||||
|
||||
Dependencies: default mod (found in minetest_game)
|
||||
Dependencies: default mod (found in minetest_game)
|
||||
|
||||
Report bugs or request help on the forum topic.
|
||||
Report bugs or request help on the forum topic.
|
||||
|
||||
[h]Installation[/h]
|
||||
[h]Installation[/h]
|
||||
|
||||
Unzip the archive, rename the folder to to modfoldername and
|
||||
place it in minetest/mods/minetest/
|
||||
Unzip the archive, rename the folder to to modfoldername and
|
||||
place it in minetest/mods/minetest/
|
||||
|
||||
( GNU/Linux: If you use a system-wide installation place
|
||||
it in ~/.minetest/mods/minetest/. )
|
||||
( GNU/Linux: If you use a system-wide installation place
|
||||
it in ~/.minetest/mods/minetest/. )
|
||||
|
||||
( If you only want this to be used in a single world, place
|
||||
the folder in worldmods/ in your worlddirectory. )
|
||||
( If you only want this to be used in a single world, place
|
||||
the folder in worldmods/ in your worlddirectory. )
|
||||
|
||||
For further information or help see:
|
||||
[url]http://wiki.minetest.com/wiki/Installing_Mods[/url]
|
||||
For further information or help see:
|
||||
[url]http://wiki.minetest.com/wiki/Installing_Mods[/url]
|
||||
|
||||
If you modify the above example for your mod topic, remember to
|
||||
change "modfldername" to the name of the folder your mod should be
|
||||
@ -224,16 +224,16 @@ Subject of topic must be in one of these formats:
|
||||
### Profit
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}/static/releasing_profit.png" alt="Profit">
|
||||
<figcaption style="display:none;">
|
||||
Profit
|
||||
</figcaption>
|
||||
<img src="{{ page.root }}/static/releasing_profit.png" alt="Profit">
|
||||
<figcaption style="display:none;">
|
||||
Profit
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
## Appendix: Readme and Forum Generator
|
||||
|
||||
<noscript>
|
||||
<p>Javascript is required for this section!</p>
|
||||
<p>Javascript is required for this section!</p>
|
||||
</noscript>
|
||||
|
||||
Title: <input id="t_title" value="My Super Special Mod"><br />
|
||||
@ -264,10 +264,10 @@ Unzip the archive, rename the folder to mysuperspecial and
|
||||
place it in minetest/mods/
|
||||
|
||||
( GNU/Linux: If you use a system-wide installation place
|
||||
it in ~/.minetest/mods/. )
|
||||
it in ~/.minetest/mods/. )
|
||||
|
||||
( If you only want this to be used in a single world, place
|
||||
the folder in worldmods/ in your worlddirectory. )
|
||||
the folder in worldmods/ in your worlddirectory. )
|
||||
|
||||
For further information or help see:
|
||||
http://wiki.minetest.com/wiki/Installing_Mods</code></pre>
|
||||
@ -287,92 +287,92 @@ Unzip the archive, rename the folder to mysuperspecial and
|
||||
place it in minetest/mods/
|
||||
|
||||
( GNU/Linux: If you use a system-wide installation place
|
||||
it in ~/.minetest/mods/. )
|
||||
it in ~/.minetest/mods/. )
|
||||
|
||||
( If you only want this to be used in a single world, place
|
||||
the folder in worldmods/ in your worlddirectory. )
|
||||
the folder in worldmods/ in your worlddirectory. )
|
||||
|
||||
For further information or help see:
|
||||
http://wiki.minetest.com/wiki/Installing_Mods</code></pre>
|
||||
|
||||
<script src="http://blog.rubenwardy.com/static/jquery.min.js"></script>
|
||||
<script>function regen() {
|
||||
var title = $("#t_title").val();
|
||||
var name = $("#t_name").val();
|
||||
var desc = $("#t_desc").val();
|
||||
var version = $("#t_version").val();
|
||||
var license = $("#t_license").val();
|
||||
var dep = $("#t_dep").val();
|
||||
var add = $("#t_add").val();
|
||||
var title = $("#t_title").val();
|
||||
var name = $("#t_name").val();
|
||||
var desc = $("#t_desc").val();
|
||||
var version = $("#t_version").val();
|
||||
var license = $("#t_license").val();
|
||||
var dep = $("#t_dep").val();
|
||||
var add = $("#t_add").val();
|
||||
|
||||
var download = $("#t_download").val();
|
||||
var download = $("#t_download").val();
|
||||
|
||||
{
|
||||
var res = ((title.length > 0) ? title : name) + "\n";
|
||||
var header_count = res.length - 1;
|
||||
for (var i = 0; i < header_count; i++) {
|
||||
res += "=";
|
||||
}
|
||||
res += "\n\n";
|
||||
{
|
||||
var res = ((title.length > 0) ? title : name) + "\n";
|
||||
var header_count = res.length - 1;
|
||||
for (var i = 0; i < header_count; i++) {
|
||||
res += "=";
|
||||
}
|
||||
res += "\n\n";
|
||||
|
||||
res += desc + "\n\n";
|
||||
res += desc + "\n\n";
|
||||
|
||||
if (version != "") {
|
||||
res += "Version: " + version + "\n";
|
||||
}
|
||||
if (version != "") {
|
||||
res += "Version: " + version + "\n";
|
||||
}
|
||||
|
||||
res += "License: " + license + "\n";
|
||||
res += "Dependencies: " + dep + "\n\n";
|
||||
res += "License: " + license + "\n";
|
||||
res += "Dependencies: " + dep + "\n\n";
|
||||
|
||||
if (add != "") {
|
||||
res += add + "\n\n";
|
||||
}
|
||||
if (add != "") {
|
||||
res += add + "\n\n";
|
||||
}
|
||||
|
||||
res += "Installation\n------------\n\nUnzip the archive, rename the folder to ";
|
||||
res += name + " and\nplace it in minetest/mods/\n\n";
|
||||
res += "Installation\n------------\n\nUnzip the archive, rename the folder to ";
|
||||
res += name + " and\nplace it in minetest/mods/\n\n";
|
||||
|
||||
res += "( GNU/Linux: If you use a system-wide installation place\n" +
|
||||
"\tit in ~/.minetest/mods/. )\n\n" +
|
||||
"( If you only want this to be used in a single world, place\n" +
|
||||
"\tthe folder in worldmods/ in your worlddirectory. )\n\n" +
|
||||
"For further information or help see:\n" +
|
||||
"http://wiki.minetest.com/wiki/Installing_Mods\n";
|
||||
res += "( GNU/Linux: If you use a system-wide installation place\n" +
|
||||
"\tit in ~/.minetest/mods/. )\n\n" +
|
||||
"( If you only want this to be used in a single world, place\n" +
|
||||
"\tthe folder in worldmods/ in your worlddirectory. )\n\n" +
|
||||
"For further information or help see:\n" +
|
||||
"http://wiki.minetest.com/wiki/Installing_Mods\n";
|
||||
|
||||
$("#readme").text(res);
|
||||
}
|
||||
$("#readme").text(res);
|
||||
}
|
||||
|
||||
{
|
||||
var res = desc + "\n\n";
|
||||
{
|
||||
var res = desc + "\n\n";
|
||||
|
||||
if (version != "") {
|
||||
res += "[b]Version:[/b] " + version + "\n";
|
||||
}
|
||||
if (version != "") {
|
||||
res += "[b]Version:[/b] " + version + "\n";
|
||||
}
|
||||
|
||||
res += "[b]License:[/b] " + license + "\n";
|
||||
res += "[b]Dependencies:[/b] " + dep + "\n";
|
||||
res += "[b]License:[/b] " + license + "\n";
|
||||
res += "[b]Dependencies:[/b] " + dep + "\n";
|
||||
|
||||
res += "[b]Download:[/b] " + download + "\n\n";
|
||||
res += "[b]Download:[/b] " + download + "\n\n";
|
||||
|
||||
if (add != "") {
|
||||
res += add + "\n\n";
|
||||
}
|
||||
if (add != "") {
|
||||
res += add + "\n\n";
|
||||
}
|
||||
|
||||
res += "[h]Installation[/h]\n\nUnzip the archive, rename the folder to ";
|
||||
res += name + " and\nplace it in minetest/mods/\n\n";
|
||||
res += "[h]Installation[/h]\n\nUnzip the archive, rename the folder to ";
|
||||
res += name + " and\nplace it in minetest/mods/\n\n";
|
||||
|
||||
res += "( GNU/Linux: If you use a system-wide installation place\n" +
|
||||
"\tit in ~/.minetest/mods/. )\n\n" +
|
||||
"( If you only want this to be used in a single world, place\n" +
|
||||
"\tthe folder in worldmods/ in your worlddirectory. )\n\n" +
|
||||
"For further information or help see:\n" +
|
||||
"http://wiki.minetest.com/wiki/Installing_Mods\n";
|
||||
res += "( GNU/Linux: If you use a system-wide installation place\n" +
|
||||
"\tit in ~/.minetest/mods/. )\n\n" +
|
||||
"( If you only want this to be used in a single world, place\n" +
|
||||
"\tthe folder in worldmods/ in your worlddirectory. )\n\n" +
|
||||
"For further information or help see:\n" +
|
||||
"http://wiki.minetest.com/wiki/Installing_Mods\n";
|
||||
|
||||
$("#forum").text(res);
|
||||
}
|
||||
$("#forum").text(res);
|
||||
}
|
||||
}
|
||||
|
||||
$(function() {
|
||||
jQuery('input').on('input propertychange paste', regen);
|
||||
jQuery('textarea').on('input propertychange paste', regen);
|
||||
jQuery('input').on('input propertychange paste', regen);
|
||||
jQuery('textarea').on('input propertychange paste', regen);
|
||||
});
|
||||
</script>
|
||||
|
14
en/index.md
14
en/index.md
@ -45,12 +45,12 @@ Written by rubenwardy.\\
|
||||
License: [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)
|
||||
|
||||
<!--<form class="leave_comment" action="http://pooleapp.com/stash/74bf2dfb-4c01-423c-b48a-e002ed70bbc1/" method="post">
|
||||
<input type="hidden" name="redirect_to"
|
||||
value="http://rubenwardy.com/minetest_modding_book/thank_you.html" />
|
||||
Nickname (optional): <input class="name" name="name" placeholder="Your Name" type="text"><br />
|
||||
Contact method (email or forum name, optional): <input name="contact" type="text"><br />
|
||||
Feedback:
|
||||
<textarea name="comment" required="" style="display:block;min-width: 90%;min-height:100px;"></textarea>
|
||||
<input type="hidden" name="redirect_to"
|
||||
value="http://rubenwardy.com/minetest_modding_book/thank_you.html" />
|
||||
Nickname (optional): <input class="name" name="name" placeholder="Your Name" type="text"><br />
|
||||
Contact method (email or forum name, optional): <input name="contact" type="text"><br />
|
||||
Feedback:
|
||||
<textarea name="comment" required="" style="display:block;min-width: 90%;min-height:100px;"></textarea>
|
||||
|
||||
<input value="Leave Feedback" type="submit">
|
||||
<input value="Leave Feedback" type="submit">
|
||||
</form>-->
|
||||
|
Loading…
Reference in New Issue
Block a user