Compare commits
5 Commits
04753b8ff6
...
d66da62fdb
Author | SHA1 | Date |
---|---|---|
rubenwardy | d66da62fdb | |
rubenwardy | 899eb5a939 | |
rubenwardy | 161fbeaafe | |
rubenwardy | 7a34ea5b31 | |
rubenwardy | 5b22b677e7 |
|
@ -113,14 +113,13 @@ A variable will be only one of the following types and can change type after an
|
|||
assignment.
|
||||
It's good practice to make sure a variable is only ever nil or a single non-nil type.
|
||||
|
||||
| Type | Description | Example |
|
||||
|----------|----------------------------------------------------|-------------------------------------------|
|
||||
| Type | Description | Example |
|
||||
|----------|---------------------------------|----------------|
|
||||
| Nil | Not initialised. The variable is empty, it has no value | `local A`, `D = nil` |
|
||||
|
||||
| Number | A whole or decimal number. | `local A = 4` |
|
||||
| String | A piece of text | `local D = "one two three" |
|
||||
| Boolean | True or False | `local is_true = false`, `local E = (1 == 1)` |
|
||||
| Table | Lists | Explained below |
|
||||
| Number | A whole or decimal number. | `local A = 4` |
|
||||
| String | A piece of text | `local D = "one two three"` |
|
||||
| Boolean | True or False | `local is_true = false`, `local E = (1 == 1)` |
|
||||
| Table | Lists | Explained below |
|
||||
| Function | Can run. May require inputs and may return a value | `local result = func(1, 2, 3)` |
|
||||
|
||||
### Arithmetic Operators
|
||||
|
|
|
@ -9,18 +9,21 @@ redirect_from: /en/chapters/creating_textures.html
|
|||
|
||||
## Introduction
|
||||
|
||||
Being able to create and optimise textures for Minetest is a useful skill
|
||||
when developing mods. There are many techniques relevant to working on
|
||||
pixel art textures, and understanding these techniques will greatly improve
|
||||
the quality of the textures you create for Minetest.
|
||||
Being able to create and optimise textures is a very useful skill when
|
||||
developing for Minetest.
|
||||
There are many techniques relevant to working on pixel art textures,
|
||||
and understanding these techniques will greatly improve
|
||||
the quality of the textures you create.
|
||||
|
||||
* [Resources](#resources)
|
||||
* [Learning to Draw](#learning-to-draw)
|
||||
* [Techniques](#techniques)
|
||||
* [Editors](#editors)
|
||||
|
||||
## Resources
|
||||
## Learning to Draw
|
||||
|
||||
* [16×16 Pixel Art Tutorial](http://www.photonstorm.com/art/tutorials-art/16x16-pixel-art-tutorial)
|
||||
Teaching how to draw good pixel art is out of scope of this book.
|
||||
|
||||
* [16×16 Pixel Art Tutorial on photonstorm.com](http://www.photonstorm.com/art/tutorials-art/16x16-pixel-art-tutorial)
|
||||
|
||||
## Techniques
|
||||
|
||||
|
@ -36,14 +39,14 @@ level of precision and control.
|
|||
|
||||
Textures used for nodes should generally be designed to tile. This means
|
||||
when you place multiple nodes with the same texture together, the edges line
|
||||
up correctly:
|
||||
up correctly.
|
||||
|
||||
[IMAGE NEEDED - cobblestone that tiles correctly]
|
||||
<!-- IMAGE NEEDED - cobblestone that tiles correctly -->
|
||||
|
||||
If you fail to match the edges correctly, the result is far less pleasing
|
||||
to look at:
|
||||
to look at.
|
||||
|
||||
[IMAGE NEEDED - node that doesn't tile correctly]
|
||||
<!-- IMAGE NEEDED - node that doesn't tile correctly -->
|
||||
|
||||
### Transparency
|
||||
|
||||
|
@ -76,8 +79,4 @@ When using GIMP, the pencil tool can be selected from the Toolbox:
|
|||
<img src="{{ page.root }}//static/pixel_art_gimp_pencil.png" alt="Pencil in GIMP">
|
||||
</figure>
|
||||
|
||||
It's also advisable to select the Hard edge checkbox for the eraser tool:
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}//static/pixel_art_gimp_rubber.png" alt="Eraser in GIMP">
|
||||
</figure>
|
||||
It's also advisable to select the Hard edge checkbox for the eraser tool.
|
||||
|
|
|
@ -189,9 +189,27 @@ This means that staticdata could be empty.
|
|||
Finally, you need to register the type table using the aptly named `register_entity`.
|
||||
|
||||
```lua
|
||||
minetest.register_entity("9_entities:myentity", MyEntity)
|
||||
minetest.register_entity("mymod:entity", MyEntity)
|
||||
```
|
||||
|
||||
The entity can be spawned by a mod like so:
|
||||
|
||||
```lua
|
||||
local pos = { x = 1, y = 2, z = 3 }
|
||||
local obj = minetest.add_entity(pos, "mymod:entity", nil)
|
||||
```
|
||||
|
||||
The third parameter is the initial staticdata.
|
||||
To set the message, you can use the entity table method:
|
||||
|
||||
```lua
|
||||
obj:get_luaentity():set_message("hello!")
|
||||
```
|
||||
|
||||
Players with the *give* [privilege](../players/privileges.html) can
|
||||
use a [chat command](../players/chat.html) to spawn entities:
|
||||
|
||||
/spawnentity mymod:entity
|
||||
|
||||
## Attachments
|
||||
|
||||
|
|
|
@ -15,32 +15,17 @@ an API that allows you to add and otherwise manage the pages shown.
|
|||
Whilst SFINV by default shows pages as tabs, pages are called "pages" as
|
||||
it's entirely possible that a mod or game decides to show them in
|
||||
some other format instead.
|
||||
For example, multiple pages could be shown on one view.
|
||||
|
||||
* [Registering a Page](#registering-a-page)
|
||||
* [A more complex example](#a-more-complex-example)
|
||||
* [Receiving events](#receiving-events)
|
||||
* [Conditionally showing to players](#conditionally-showing-to-players)
|
||||
* [on_enter and on_leave callbacks](#on_enter-and-on_leave-callbacks)
|
||||
|
||||
## Registering a Page
|
||||
|
||||
So, to register a page you need to call the aptly named `sfinv.register_page`
|
||||
function with the page's name, and its definition. Here is a minimal example:
|
||||
|
||||
```lua
|
||||
sfinv.register_page("mymod:hello", {
|
||||
title = "Hello!",
|
||||
get = function(self, player, context)
|
||||
-- TODO: implement this
|
||||
end
|
||||
})
|
||||
```
|
||||
|
||||
You can also override an existing page using `sfinv.override_page`.
|
||||
|
||||
If you ran the above code and clicked the page's tab, it would probably crash
|
||||
as sfinv is expecting a response from the `get` method. So let's add a response
|
||||
to fix that:
|
||||
SFINV provides the aptly named `sfinv.register_page` function to create pages.
|
||||
Simply call the function with the page's name, and its definition:
|
||||
|
||||
```lua
|
||||
sfinv.register_page("mymod:hello", {
|
||||
|
@ -52,19 +37,10 @@ sfinv.register_page("mymod:hello", {
|
|||
})
|
||||
```
|
||||
|
||||
The `make_formspec` function surrounds your formspec with sfinv's formspec code.
|
||||
The fourth parameter, currently set as `true`, determines whether or not the
|
||||
The `make_formspec` function surrounds your formspec with SFINV's formspec code.
|
||||
The fourth parameter, currently set as `true`, determines whether the
|
||||
player's inventory is shown.
|
||||
|
||||
<figure>
|
||||
<img src="{{ page.root }}//static/sfinv_hello_world.png" alt="Furnace Inventory">
|
||||
<figcaption>
|
||||
Your first sfinv page! Not exactly very exciting, though.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
### A more complex example
|
||||
|
||||
Let's make things more exciting. Here is the code for the formspec generation
|
||||
part of a player admin tab. This tab will allow admins to kick or ban players by
|
||||
selecting them in a list and clicking a button.
|
||||
|
@ -185,7 +161,7 @@ is_in_nav = function(self, player, context)
|
|||
end,
|
||||
```
|
||||
|
||||
If you only need to check one priv or want to perform an and, you should use
|
||||
If you only need to check one priv or want to perform an 'and', you should use
|
||||
`minetest.check_player_privs()` instead of `get_player_privs`.
|
||||
|
||||
Note that the `is_in_nav` is only called when the player's inventory formspec is
|
||||
|
@ -198,33 +174,41 @@ we need to do that whenever kick or ban is granted or revoked to a player:
|
|||
|
||||
```lua
|
||||
local function on_grant_revoke(grantee, granter, priv)
|
||||
if priv == "kick" or priv == "ban" then
|
||||
local player = minetest.get_player_by_name(grantee)
|
||||
if player then
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
end
|
||||
if priv ~= "kick" and priv ~= "ban" then
|
||||
return
|
||||
end
|
||||
|
||||
local player = minetest.get_player_by_name(grantee)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
local context = sfinv.get_or_create_context(player)
|
||||
if context.page ~= "myadmin:myadmin" then
|
||||
return
|
||||
end
|
||||
|
||||
sfinv.set_player_inventory_formspec(player, context)
|
||||
end
|
||||
|
||||
-- Check that the function exists,
|
||||
-- in order to support older Minetest versions
|
||||
if minetest.register_on_priv_grant then
|
||||
minetest.register_on_priv_grant(on_grant_revoke)
|
||||
minetest.register_on_priv_revoke(on_grant_revoke)
|
||||
end
|
||||
minetest.register_on_priv_grant(on_grant_revoke)
|
||||
minetest.register_on_priv_revoke(on_grant_revoke)
|
||||
```
|
||||
|
||||
## on_enter and on_leave callbacks
|
||||
|
||||
You can run code when a player enters (your tab becomes selected) or
|
||||
leaves (another tab is about to be selected) your tab.
|
||||
A player *enters* a tab when the tab is selected, and *leaves* a
|
||||
tab when another tab is about to be selected.
|
||||
It's possible for multiple pages to be selected if a custom theme is
|
||||
used.
|
||||
|
||||
Please note that you can't cancel these, as it would be a bad user experience
|
||||
if you could.
|
||||
Note that these events may not be triggered by the player.
|
||||
The player may not even have the formspec open at that time.
|
||||
For example, on_enter is called for the home page when a player
|
||||
joins the game even before they open their inventory.
|
||||
|
||||
Also, note that the inventory may not be visible at the time
|
||||
these callbacks are called. For example, on_enter is called for the home page
|
||||
when a player joins the game even before they open their inventory!
|
||||
It's not possible to cancel a page change, as that would potentially
|
||||
confuse the player.
|
||||
|
||||
```lua
|
||||
on_enter = function(self, player, context)
|
||||
|
@ -238,4 +222,23 @@ end,
|
|||
|
||||
## Adding to an existing page
|
||||
|
||||
{% include notice.html level="warning" title="To Do" message="This section will be added soon™. This placeholder is just to let you know that it is possible!" %}
|
||||
To add content to an existing page, you will need to override the page
|
||||
and modify the returned formspec.
|
||||
|
||||
```lua
|
||||
local old_func = sfinv.registered_pages["sfinv:crafting"].get
|
||||
sfinv.override_page("sfinv:crafting", {
|
||||
get = function(self, player, context, ...)
|
||||
local ret = old_func(self, player, context, ...)
|
||||
|
||||
if type(ret) == "table" then
|
||||
ret.formspec = ret.formspec .. "label[0,0;Hello]"
|
||||
else
|
||||
-- Backwards compatibility
|
||||
ret = ret .. "label[0,0;Hello]"
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
})
|
||||
```
|
||||
|
|
|
@ -3,8 +3,6 @@ title: Security
|
|||
layout: default
|
||||
root: ../..
|
||||
idx: 7.25
|
||||
description: Use LuaCheck to find errors
|
||||
redirect_from: /en/chapters/luacheck.html
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
|
Loading…
Reference in New Issue