1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-30 19:22:14 +00:00

Merge remote-tracking branch 'upstream/master' into Visuals-Vol-2

This commit is contained in:
Gefüllte Taubenbrust 2025-08-04 17:41:50 +02:00
commit 66aeedc74d
667 changed files with 34156 additions and 87678 deletions

View file

@ -25,16 +25,16 @@ Contributions are welcome! Here's how you can help:
the work, to avoid disappointment. the work, to avoid disappointment.
You may also benefit from discussing on our IRC development channel You may also benefit from discussing on our IRC development channel
[#luanti-dev](http://www.luanti.org/irc/). Note that a proper IRC client [#luanti-dev](https://docs.luanti.org/about/irc/). Note that a proper IRC client
is required to speak on this channel. is required to speak on this channel.
3. Start coding! 3. Start coding!
- Refer to the - Refer to the
[Lua API](https://github.com/luanti-org/luanti/blob/master/doc/lua_api.md), [Lua API](https://github.com/luanti-org/luanti/blob/master/doc/lua_api.md),
[Developer Wiki](https://dev.luanti.org/) and other [Luanti Documentation](https://docs.luanti.org/) and other
[documentation](https://github.com/luanti-org/luanti/tree/master/doc). [documentation](https://github.com/luanti-org/luanti/tree/master/doc).
- Follow the [C/C++](https://dev.luanti.org/Code_style_guidelines) and - Follow the [C/C++](https://docs.luanti.org/for-engine-devs/code-style-guidelines/) and
[Lua](https://dev.luanti.org/Lua_code_style_guidelines) code style guidelines. [Lua](https://docs.luanti.org/for-engine-devs/lua-code-style-guidelines/) code style guidelines.
- Check your code works as expected and document any changes to the Lua API. - Check your code works as expected and document any changes to the Lua API.
- To avoid conflicting changes between contributions, do not do the following manually. They will be done before each release. - To avoid conflicting changes between contributions, do not do the following manually. They will be done before each release.
- Run `updatepo.sh` or update `luanti.po{,t}` even if your code adds new translatable strings. - Run `updatepo.sh` or update `luanti.po{,t}` even if your code adds new translatable strings.
@ -64,8 +64,8 @@ Contributions are welcome! Here's how you can help:
picture of the project. picture of the project.
2. It works. 2. It works.
3. It follows the code style for 3. It follows the code style for
[C/C++](https://dev.luanti.org/Code_style_guidelines) or [C/C++](https://docs.luanti.org/for-engine-devs/code-style-guidelines/) or
[Lua](https://dev.luanti.org/Lua_code_style_guidelines). [Lua](https://docs.luanti.org/for-engine-devs/lua-code-style-guidelines/).
4. The code's interfaces are well designed, regardless of other aspects that 4. The code's interfaces are well designed, regardless of other aspects that
might need more work in the future. might need more work in the future.
5. It uses protocols and formats which include the required compatibility. 5. It uses protocols and formats which include the required compatibility.
@ -106,7 +106,7 @@ the project page with a list of current languages
Builtin (the component which contains things like server messages, chat command Builtin (the component which contains things like server messages, chat command
descriptions, privilege descriptions) is translated separately; it needs to be descriptions, privilege descriptions) is translated separately; it needs to be
translated by editing a `.tr` text file. See translated by editing a `.tr` text file. See
[Translation](https://dev.luanti.org/Translation) for more information. [Translation](https://docs.luanti.org/for-creators/translation/) for more information.
## Donations ## Donations
@ -116,11 +116,11 @@ methods on [our website](http://www.luanti.org/development/#donate).
# Maintaining # Maintaining
* This is a concise version of the * This is a concise version of the
[Rules & Guidelines](https://dev.luanti.org/engine-dev-process/) on the developer wiki.* [Rules & Guidelines](https://docs.luanti.org/for-engine-devs/) on the Luanti Documentation.*
These notes are for those who have push access Luanti (core developers / maintainers). These notes are for those who have push access Luanti (core developers / maintainers).
- See the [project organisation](https://dev.luanti.org/Organisation) for the people involved. - See the [project organisation](https://docs.luanti.org/for-engine-devs/organization/) for the people involved.
## Concept approvals and roadmaps ## Concept approvals and roadmaps
@ -169,4 +169,4 @@ Submit a :+1: (+1) or "Looks good" comment to show you believe the pull-request
## Releasing a new version ## Releasing a new version
*Refer to [dev.luanti.org/Releasing_Luanti](https://dev.luanti.org/Releasing_Luanti)* *Refer to [docs.luanti.org/for-engine-devs/releasing-luanti](https://docs.luanti.org/for-engine-devs/releasing-luanti/)*

View file

@ -14,6 +14,7 @@ on:
- 'cmake/Modules/**' - 'cmake/Modules/**'
- 'po/**.po' - 'po/**.po'
- 'util/ci/**' - 'util/ci/**'
- 'util/helper_mod/**'
- '.github/workflows/linux.yml' - '.github/workflows/linux.yml'
pull_request: pull_request:
paths: paths:
@ -27,6 +28,7 @@ on:
- 'cmake/Modules/**' - 'cmake/Modules/**'
- 'po/**.po' - 'po/**.po'
- 'util/ci/**' - 'util/ci/**'
- 'util/helper_mod/**'
- '.github/workflows/linux.yml' - '.github/workflows/linux.yml'
env: env:
@ -76,6 +78,8 @@ jobs:
env: env:
CC: gcc-14 CC: gcc-14
CXX: g++-14 CXX: g++-14
# just to check that they compile correctly
CMAKE_FLAGS: '-DBUILD_BENCHMARKS=1'
- name: Test - name: Test
run: | run: |
@ -132,16 +136,16 @@ jobs:
run: | run: |
./util/test_multiplayer.sh ./util/test_multiplayer.sh
# Build with prometheus-cpp (server-only) # Build with prometheus-cpp (server-only), also runs on ARM64
clang_11_prometheus: clang_prometheus_arm:
name: "clang_11 (PROMETHEUS=1)" name: "clang (with Prometheus, ARM64)"
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04-arm
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install deps - name: Install deps
run: | run: |
source ./util/ci/common.sh source ./util/ci/common.sh
install_linux_deps clang-11 install_linux_deps --headless clang libluajit-5.1-dev
- name: Build prometheus-cpp - name: Build prometheus-cpp
run: ./util/ci/build_prometheus_cpp.sh run: ./util/ci/build_prometheus_cpp.sh
@ -150,8 +154,8 @@ jobs:
run: | run: |
./util/ci/build.sh ./util/ci/build.sh
env: env:
CC: clang-11 CC: clang
CXX: clang++-11 CXX: clang++
CMAKE_FLAGS: "-DENABLE_PROMETHEUS=1 -DBUILD_CLIENT=0 -DENABLE_CURSES=0" CMAKE_FLAGS: "-DENABLE_PROMETHEUS=1 -DBUILD_CLIENT=0 -DENABLE_CURSES=0"
- name: Test - name: Test

View file

@ -14,7 +14,7 @@ set(CLANG_MINIMUM_VERSION "7.0.1")
# You should not need to edit these manually, use util/bump_version.sh # You should not need to edit these manually, use util/bump_version.sh
set(VERSION_MAJOR 5) set(VERSION_MAJOR 5)
set(VERSION_MINOR 12) set(VERSION_MINOR 14)
set(VERSION_PATCH 0) set(VERSION_PATCH 0)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string") set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")

View file

@ -28,7 +28,7 @@ Table of Contents
Further documentation Further documentation
---------------------- ----------------------
- Website: https://www.luanti.org/ - Website: https://www.luanti.org/
- Wiki: https://wiki.luanti.org/ - Luanti Documentation: https://docs.luanti.org/
- Forum: https://forum.luanti.org/ - Forum: https://forum.luanti.org/
- GitHub: https://github.com/luanti-org/luanti/ - GitHub: https://github.com/luanti-org/luanti/
- [Developer documentation](doc/developing/) - [Developer documentation](doc/developing/)

View file

@ -8,4 +8,5 @@
<string name="unzip_notification_description">Menos de 1 minuto…</string> <string name="unzip_notification_description">Menos de 1 minuto…</string>
<string name="ime_dialog_done">Feito</string> <string name="ime_dialog_done">Feito</string>
<string name="no_web_browser">Non se atopou ningún navegador web</string> <string name="no_web_browser">Non se atopou ningún navegador web</string>
<string name="game_notification_title">Luanti está en funcionamento</string>
</resources> </resources>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">לואנטי</string>
<string name="loading">טוען…</string>
<string name="notification_channel_name">הודעה כללית</string>
<string name="notification_channel_description">התראות מלואנטי</string>
<string name="unzip_notification_title">טוען לואנטי</string>
<string name="game_notification_title">לואנטי רץ</string>
<string name="ime_dialog_done">בוצע</string>
<string name="no_web_browser">לא נמצא דפדפן אינטרנט</string>
<string name="unzip_notification_description">פחות מדקה אחת…</string>
</resources>

View file

@ -8,4 +8,5 @@
<string name="notification_channel_description">Obvestilo od Luantia</string> <string name="notification_channel_description">Obvestilo od Luantia</string>
<string name="ime_dialog_done">Končano!l</string> <string name="ime_dialog_done">Končano!l</string>
<string name="unzip_notification_title">Nalaganje Luantia</string> <string name="unzip_notification_title">Nalaganje Luantia</string>
<string name="game_notification_title">Luanti deluje</string>
</resources> </resources>

View file

@ -8,4 +8,5 @@
<string name="unzip_notification_description">Менше за 1 хвилину…</string> <string name="unzip_notification_description">Менше за 1 хвилину…</string>
<string name="ime_dialog_done">Готово</string> <string name="ime_dialog_done">Готово</string>
<string name="notification_channel_description">Сповіщення від Luanti</string> <string name="notification_channel_description">Сповіщення від Luanti</string>
</resources> <string name="game_notification_title">Luanti працює</string>
</resources>

View file

@ -8,4 +8,5 @@
<string name="unzip_notification_description">不到1分钟…</string> <string name="unzip_notification_description">不到1分钟…</string>
<string name="ime_dialog_done">完成</string> <string name="ime_dialog_done">完成</string>
<string name="no_web_browser">未找到网页浏览器</string> <string name="no_web_browser">未找到网页浏览器</string>
<string name="game_notification_title">Luanti正在运行</string>
</resources> </resources>

View file

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
project.ext.set("versionMajor", 5) // Version Major project.ext.set("versionMajor", 5) // Version Major
project.ext.set("versionMinor", 12) // Version Minor project.ext.set("versionMinor", 14) // Version Minor
project.ext.set("versionPatch", 0) // Version Patch project.ext.set("versionPatch", 0) // Version Patch
// ^ keep in sync with cmake // ^ keep in sync with cmake

View file

@ -438,11 +438,28 @@ function make.key(setting)
if value == "" then if value == "" then
return height return height
end end
local critical_keys = {
keymap_drop = true,
keymap_dig = true,
keymap_place = true,
}
for _, o in ipairs(core.full_settingtypes) do for _, o in ipairs(core.full_settingtypes) do
if o.type == "key" and o.name ~= setting.name and core.are_keycodes_equal(core.settings:get(o.name), value) then if o.type == "key" and o.name ~= setting.name and
table.insert(fs, ("label[0,%f;%s]"):format(height + 0.3, core.are_keycodes_equal(core.settings:get(o.name), value) then
core.colorize(mt_color_orange, fgettext([[Conflicts with "$1"]], fgettext(o.readable_name)))))
height = height + 0.6 local is_current_close_world = setting.name == "keymap_close_world"
local is_other_close_world = o.name == "keymap_close_world"
local is_current_critical = critical_keys[setting.name]
local is_other_critical = critical_keys[o.name]
if (is_other_critical or is_current_critical) or
(not is_current_close_world and not is_other_close_world) then
table.insert(fs, ("label[0,%f;%s]"):format(height + 0.3,
core.colorize(mt_color_orange, fgettext([[Conflicts with "$1"]], fgettext(o.readable_name)))))
height = height + 0.6
end
end end
end end
return height return height
@ -454,12 +471,12 @@ function make.key(setting)
get_formspec = function(self, avail_w) get_formspec = function(self, avail_w)
self.resettable = core.settings:has(setting.name) self.resettable = core.settings:has(setting.name)
local btn_bind_width = math.max(2.5, avail_w/2) local btn_bind_width = math.max(2.5, avail_w / 2)
local value = core.settings:get(setting.name) local value = core.settings:get(setting.name)
local fs = { local fs = {
("label[0,0.4;%s]"):format(get_label(setting)), ("label[0,0.4;%s]"):format(get_label(setting)),
("button_key[%f,0;%f,0.8;%s;%s]"):format( ("button_key[%f,0;%f,0.8;%s;%s]"):format(
btn_bind_width, btn_bind_width-0.8, btn_bind_width, btn_bind_width - 0.8,
btn_bind, core.formspec_escape(value)), btn_bind, core.formspec_escape(value)),
("image_button[%f,0;0.8,0.8;%s;%s;]"):format(avail_w - 0.8, ("image_button[%f,0;0.8,0.8;%s;%s;]"):format(avail_w - 0.8,
core.formspec_escape(defaulttexturedir .. "clear.png"), core.formspec_escape(defaulttexturedir .. "clear.png"),

View file

@ -16,7 +16,7 @@ local minetest_example_header = [[
# to the program, eg. "luanti.exe --config ../minetest.conf.example". # to the program, eg. "luanti.exe --config ../minetest.conf.example".
# Further documentation: # Further documentation:
# https://wiki.luanti.org/ # https://docs.luanti.org/
]] ]]
@ -44,15 +44,18 @@ local function create_minetest_conf_example(settings)
insert(result, rep("#", entry.level)) insert(result, rep("#", entry.level))
insert(result, "# " .. entry.name .. "\n\n") insert(result, "# " .. entry.name .. "\n\n")
end end
else else -- any `type` as listed in `settingtypes.txt`
local group_format = false local group_format = false
if entry.noise_params and entry.values then if entry.noise_params and entry.values then
if entry.type == "noise_params_2d" or entry.type == "noise_params_3d" then if entry.type == "noise_params_2d" or entry.type == "noise_params_3d" then
group_format = true group_format = true
end end
end end
if entry.comment ~= "" then
for _, comment_line in ipairs(entry.comment:split("\n", true)) do local comment = entry.comment ~= "" and entry.comment
or entry.readable_name -- fallback to the short description
if comment ~= "" then
for _, comment_line in ipairs(comment:split("\n", true)) do
if comment_line == "" then if comment_line == "" then
insert(result, "#\n") insert(result, "#\n")
else else
@ -102,23 +105,45 @@ end
local translation_file_header = [[ local translation_file_header = [[
// This file is automatically generated // This file is automatically generated
// It contains a bunch of fake gettext calls, to tell xgettext about the strings in config files // It contains a bunch of fake gettext calls, to tell xgettext about the strings in config files
// To update it, refer to the bottom of builtin/mainmenu/dlg_settings_advanced.lua // To update it, refer to the bottom of builtin/common/settings/init.lua
fake_function() {]] fake_function() {]]
local function add_translation_string(result, str, seen)
if seen[str] then
return
end
seen[str] = true
-- Prevent gettext from interpreting e.g. "50% of volume" as C-formatted string
-- Documentation: https://www.gnu.org/software/gettext/manual/html_node/c_002dformat-Flag.html
local force_no_c_format = str:find("%", 1, true)
local prefix = force_no_c_format and "/* xgettext:no-c-format */ " or ""
local have_newlines = str:find("\n", 1, true)
if have_newlines then
-- Formatting as "%q" inserts literal newlines. But we want '\n'.
-- Hence, use "%s" and escape relevant characters manually.
str = str:gsub("\n", "\\n")
str = str:gsub("\"", "\\\"")
insert(result, sprintf("\t%sgettext(\"%s\");", prefix, str))
else
insert(result, sprintf("\t%sgettext(%q);", prefix, str))
end
end
local function create_translation_file(settings) local function create_translation_file(settings)
local seen = {} -- to deduplicate entries
local result = { translation_file_header } local result = { translation_file_header }
for _, entry in ipairs(settings) do for _, entry in ipairs(settings) do
if entry.type == "category" then if entry.type == "category" then
insert(result, sprintf("\tgettext(%q);", entry.name)) add_translation_string(result, entry.name, seen)
else else
if entry.readable_name then if entry.readable_name then
insert(result, sprintf("\tgettext(%q);", entry.readable_name)) add_translation_string(result, entry.readable_name, seen)
end end
if entry.comment ~= "" then if entry.comment ~= "" then
local comment_escaped = entry.comment:gsub("\n", "\\n") add_translation_string(result, entry.comment, seen)
comment_escaped = comment_escaped:gsub("\"", "\\\"")
insert(result, "\tgettext(\"" .. comment_escaped .. "\");")
end end
end end
end end

View file

@ -19,12 +19,14 @@ function meta:__newindex(name, value)
return return
end end
local info = getinfo(2, "Sl") local info = getinfo(2, "Sl")
local desc = ("%s:%d"):format(info.short_src, info.currentline) if info ~= nil then
local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name) local desc = ("%s:%d"):format(info.short_src, info.currentline)
if not warned[warn_key] and info.what ~= "main" and info.what ~= "C" then local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
core.log("warning", ("Assignment to undeclared global %q inside a function at %s.") if not warned[warn_key] and info.what ~= "main" and info.what ~= "C" then
:format(name, desc)) core.log("warning", ("Assignment to undeclared global %q inside a function at %s.")
warned[warn_key] = true :format(name, desc))
warned[warn_key] = true
end
end end
declared[name] = true declared[name] = true
end end
@ -35,6 +37,9 @@ function meta:__index(name)
return return
end end
local info = getinfo(2, "Sl") local info = getinfo(2, "Sl")
if info == nil then
return
end
local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name) local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
if not warned[warn_key] and info.what ~= "C" then if not warned[warn_key] and info.what ~= "C" then
core.log("warning", ("Undeclared global variable %q accessed at %s:%s") core.log("warning", ("Undeclared global variable %q accessed at %s:%s")

View file

@ -432,7 +432,32 @@ describe("vector", function()
assert.True(almost_equal({x = 1, y = 0, z = 0}, assert.True(almost_equal({x = 1, y = 0, z = 0},
vector.rotate({x = 1, y = 0, z = 0}, {x = math.pi / 123, y = 0, z = 0}))) vector.rotate({x = 1, y = 0, z = 0}, {x = math.pi / 123, y = 0, z = 0})))
end) end)
it("is counterclockwise", function() it("rotation order is Z-X-Y", function()
local r = vector.new(1, 2, 3)
for _, v in ipairs({
vector.new(1, 0, 0),
vector.new(0, 1, 0),
vector.new(0, 0, 1),
}) do
local expected = v:rotate(r)
local function try(order)
local rotated = v
for axis in order:gmatch(".") do
local r_axis = vector.zero()
r_axis[axis] = r[axis]
rotated = vector.rotate(rotated, r_axis)
end
return almost_equal(rotated, expected)
end
assert.False(try("xyz"))
assert.False(try("xzy"))
assert.False(try("yxz"))
assert.False(try("yzx"))
assert.True(try("zxy"))
assert.False(try("zyx"))
end
end)
it("is right handed", function()
local v_before1 = {x = 0, y = 1, z = -1} local v_before1 = {x = 0, y = 1, z = -1}
local v_after1 = vector.rotate(v_before1, {x = math.pi / 4, y = 0, z = 0}) local v_after1 = vector.rotate(v_before1, {x = math.pi / 4, y = 0, z = 0})
assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0})) assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0}))

View file

@ -118,7 +118,7 @@ function ui.update()
if (active_toplevel_ui_elements > 1) then if (active_toplevel_ui_elements > 1) then
core.log("warning", "more than one active ui ".. core.log("warning", "more than one active ui "..
"element, self most likely isn't intended") "element, this most likely isn't intended")
end end
if (active_toplevel_ui_elements == 0) then if (active_toplevel_ui_elements == 0) then

View file

@ -47,6 +47,7 @@ core.features = {
particle_blend_clip = true, particle_blend_clip = true,
remove_item_match_meta = true, remove_item_match_meta = true,
httpfetch_additional_methods = true, httpfetch_additional_methods = true,
object_guids = true,
} }
function core.has_feature(arg) function core.has_feature(arg)

View file

@ -740,16 +740,16 @@ core.noneitemdef_default = { -- This is used for the hand and unknown items
-- --
local get_node_raw = core.get_node_raw local get_node_raw = core.get_node_raw
core.get_node_raw = nil local get_name_from_content_id = core.get_name_from_content_id
function core.get_node(pos) function core.get_node(pos)
local content, param1, param2 = get_node_raw(pos.x, pos.y, pos.z) local content, param1, param2 = get_node_raw(pos.x, pos.y, pos.z)
return {name = core.get_name_from_content_id(content), param1 = param1, param2 = param2} return {name = get_name_from_content_id(content), param1 = param1, param2 = param2}
end end
function core.get_node_or_nil(pos) function core.get_node_or_nil(pos)
local content, param1, param2, pos_ok = get_node_raw(pos.x, pos.y, pos.z) local content, param1, param2, pos_ok = get_node_raw(pos.x, pos.y, pos.z)
return pos_ok and return pos_ok and
{name = core.get_name_from_content_id(content), param1 = param1, param2 = param2} {name = get_name_from_content_id(content), param1 = param1, param2 = param2}
or nil or nil
end end

View file

@ -130,6 +130,7 @@ core.protocol_versions = {
["5.10.0"] = 46, ["5.10.0"] = 46,
["5.11.0"] = 47, ["5.11.0"] = 47,
["5.12.0"] = 48, ["5.12.0"] = 48,
["5.13.0"] = 49,
} }
setmetatable(core.protocol_versions, {__newindex = function() setmetatable(core.protocol_versions, {__newindex = function()

View file

@ -3,18 +3,61 @@
-- SPDX-License-Identifier: LGPL-2.1-or-later -- SPDX-License-Identifier: LGPL-2.1-or-later
local function get_info_formspec(size, padding, text) local function get_description_hypertext(package, info, loading_error)
return table.concat({ -- Screenshots and description
"formspec_version[6]", local hypertext = "<big><b>" .. core.hypertext_escape(package.short_description) .. "</b></big>\n"
"size[", size.x, ",", size.y, "]",
"padding[0,0]",
"bgcolor[;true]",
"label[4,4.35;", text, "]", local screenshots = info and info.screenshots or {{url = package.thumbnail}}
"container[", padding.x, ",", size.y - 0.8 - padding.y, "]",
"button[0,0;2,0.8;back;", fgettext("Back"), "]", local winfo = core.get_window_info()
"container_end[]", local fs_to_px = winfo.size.x / winfo.max_formspec_size.x
}) for i, ss in ipairs(screenshots) do
local path = get_screenshot(package, ss.url, 2)
hypertext = hypertext .. "<action name=\"ss_".. i .. "\"><img name=\"" ..
core.hypertext_escape(path) .. "\" width=" .. (3 * fs_to_px) ..
" height=" .. (2 * fs_to_px) .. "></action>"
if i ~= #screenshots then
hypertext = hypertext .. "<img name=\"blank.png\" width=" .. (0.25 * fs_to_px) ..
" height=" .. (2.25 * fs_to_px).. ">"
end
end
if info then
hypertext = hypertext .. "\n" .. info.long_description.head
local first = true
local function add_link_button(label, name)
if info[name] then
if not first then
hypertext = hypertext .. " | "
end
hypertext = hypertext .. "<action name=link_" .. name .. ">" .. label .. "</action>"
info.long_description.links["link_" .. name] = info[name]
first = false
end
end
add_link_button(hgettext("Donate"), "donate_url")
add_link_button(hgettext("Website"), "website")
add_link_button(hgettext("Source"), "repo")
add_link_button(hgettext("Issue Tracker"), "issue_tracker")
add_link_button(hgettext("Translate"), "translation_url")
add_link_button(hgettext("Forum Topic"), "forum_url")
hypertext = hypertext .. "\n\n" .. info.long_description.body
elseif loading_error then
hypertext = hypertext .. "\n\n" .. hgettext("Error loading package information")
else
hypertext = hypertext .. "\n\n" .. hgettext("Loading...")
end
-- Fix the path to blank.png. This is needed for bullet indentation,
-- and also used for screenshot spacing.
hypertext = hypertext:gsub("<img name=\"?blank.png\"? ",
"<img name=\"" .. core.hypertext_escape(defaulttexturedir) .. "blank.png\" ")
return hypertext
end end
@ -41,18 +84,10 @@ local function get_formspec(data)
assert(data.package.name == info.name) assert(data.package.name == info.name)
data.info = info data.info = info
-- note: get_full_package_info can also return cached info immediately
ui.update() ui.update()
end) end)
end end
-- get_full_package_info can return cached info immediately, so
-- check to see if that happened
if not data.info then
if data.loading_error then
return get_info_formspec(size, window_padding, fgettext("Error loading package information"))
end
return get_info_formspec(size, window_padding, fgettext("Loading..."))
end
end end
-- Check installation status -- Check installation status
@ -60,10 +95,14 @@ local function get_formspec(data)
local info = data.info local info = data.info
local info_line = local info_line
fgettext("by $1 — $2 downloads — +$3 / $4 / -$5", if info then
info_line = fgettext_ne("by $1 — $2 downloads — +$3 / $4 / -$5",
info.author, info.downloads, info.author, info.downloads,
info.reviews.positive, info.reviews.neutral, info.reviews.negative) info.reviews.positive, info.reviews.neutral, info.reviews.negative)
else
info_line = fgettext_ne("by $1", package.author)
end
local bottom_buttons_y = H - 0.8 local bottom_buttons_y = H - 0.8
@ -79,7 +118,7 @@ local function get_formspec(data)
"button[", W - 3, ",", bottom_buttons_y, ";3,0.8;open_contentdb;", fgettext("ContentDB page"), "]", "button[", W - 3, ",", bottom_buttons_y, ";3,0.8;open_contentdb;", fgettext("ContentDB page"), "]",
"style_type[label;font_size=+24;font=bold]", "style_type[label;font_size=+24;font=bold]",
"label[0,0.4;", core.formspec_escape(info.title), "]", "label[0,0.4;", core.formspec_escape(package.title), "]",
"style_type[label;font_size=;font=]", "style_type[label;font_size=;font=]",
"label[0,1.2;", core.formspec_escape(info_line), "]", "label[0,1.2;", core.formspec_escape(info_line), "]",
@ -100,11 +139,13 @@ local function get_formspec(data)
formspec[#formspec + 1] = "image_button[5,0;1,1;" .. core.formspec_escape(defaulttexturedir) formspec[#formspec + 1] = "image_button[5,0;1,1;" .. core.formspec_escape(defaulttexturedir)
formspec[#formspec + 1] = "cdb_queued.png;queued;]" formspec[#formspec + 1] = "cdb_queued.png;queued;]"
elseif not package.path then elseif not package.path then
local label = info and fgettext("Install [$1]", info.download_size) or
fgettext("Install")
formspec[#formspec + 1] = "style[install;bgcolor=green]" formspec[#formspec + 1] = "style[install;bgcolor=green]"
formspec[#formspec + 1] = "button[" formspec[#formspec + 1] = "button["
formspec[#formspec + 1] = right_button_rect formspec[#formspec + 1] = right_button_rect
formspec[#formspec + 1] =";install;" formspec[#formspec + 1] =";install;"
formspec[#formspec + 1] = fgettext("Install [$1]", info.download_size) formspec[#formspec + 1] = label
formspec[#formspec + 1] = "]" formspec[#formspec + 1] = "]"
else else
if package.installed_release < package.release then if package.installed_release < package.release then
@ -125,13 +166,15 @@ local function get_formspec(data)
formspec[#formspec + 1] = "]" formspec[#formspec + 1] = "]"
end end
local review_count = info.reviews.positive + info.reviews.neutral + info.reviews.negative
local current_tab = data.current_tab or 1 local current_tab = data.current_tab or 1
local tab_titles = { local tab_titles = {
fgettext("Description"), fgettext("Description"),
fgettext("Information"),
fgettext("Reviews") .. core.formspec_escape(" [" .. review_count .. "]"),
} }
if info then
local review_count = info.reviews.positive + info.reviews.neutral + info.reviews.negative
table.insert(tab_titles, fgettext("Information"))
table.insert(tab_titles, fgettext("Reviews") .. core.formspec_escape(" [" .. review_count .. "]"))
end
local tab_body_height = bottom_buttons_y - 2.8 local tab_body_height = bottom_buttons_y - 2.8
@ -147,59 +190,21 @@ local function get_formspec(data)
}) })
if current_tab == 1 then if current_tab == 1 then
-- Screenshots and description local hypertext = get_description_hypertext(package, info, data.loading_error)
local hypertext = "<big><b>" .. core.hypertext_escape(info.short_description) .. "</b></big>\n"
local winfo = core.get_window_info()
local fs_to_px = winfo.size.x / winfo.max_formspec_size.x
for i, ss in ipairs(info.screenshots) do
local path = get_screenshot(package, ss.url, 2)
hypertext = hypertext .. "<action name=\"ss_".. i .. "\"><img name=\"" ..
core.hypertext_escape(path) .. "\" width=" .. (3 * fs_to_px) ..
" height=" .. (2 * fs_to_px) .. "></action>"
if i ~= #info.screenshots then
hypertext = hypertext .. "<img name=\"blank.png\" width=" .. (0.25 * fs_to_px) ..
" height=" .. (2.25 * fs_to_px).. ">"
end
end
hypertext = hypertext .. "\n" .. info.long_description.head
local first = true
local function add_link_button(label, name)
if info[name] then
if not first then
hypertext = hypertext .. " | "
end
hypertext = hypertext .. "<action name=link_" .. name .. ">" .. core.hypertext_escape(label) .. "</action>"
info.long_description.links["link_" .. name] = info[name]
first = false
end
end
add_link_button(fgettext("Donate"), "donate_url")
add_link_button(fgettext("Website"), "website")
add_link_button(fgettext("Source"), "repo")
add_link_button(fgettext("Issue Tracker"), "issue_tracker")
add_link_button(fgettext("Translate"), "translation_url")
add_link_button(fgettext("Forum Topic"), "forum_url")
hypertext = hypertext .. "\n\n" .. info.long_description.body
-- Fix the path to blank.png. This is needed for bullet indentation.
hypertext = hypertext:gsub("<img name=\"?blank.png\"? ",
"<img name=\"" .. core.hypertext_escape(defaulttexturedir) .. "blank.png\" ")
table.insert_all(formspec, { table.insert_all(formspec, {
"hypertext[0,0;", W, ",", tab_body_height - 0.375, "hypertext[0,0;", W, ",", tab_body_height - 0.375,
";desc;", core.formspec_escape(hypertext), "]", ";desc;", core.formspec_escape(hypertext), "]",
}) })
elseif current_tab == 2 then elseif current_tab == 2 then
assert(info)
local hypertext = info.info_hypertext.head .. info.info_hypertext.body local hypertext = info.info_hypertext.head .. info.info_hypertext.body
table.insert_all(formspec, { table.insert_all(formspec, {
"hypertext[0,0;", W, ",", tab_body_height - 0.375, "hypertext[0,0;", W, ",", tab_body_height - 0.375,
";info;", core.formspec_escape(hypertext), "]", ";info;", core.formspec_escape(hypertext), "]",
}) })
elseif current_tab == 3 then elseif current_tab == 3 then
assert(info)
if not package.reviews and not data.reviews_error and not data.reviews_loading then if not package.reviews and not data.reviews_error and not data.reviews_loading then
data.reviews_loading = true data.reviews_loading = true
@ -286,10 +291,6 @@ local function handle_submit(this, fields)
return true return true
end end
if not info then
return false
end
if fields.open_contentdb then if fields.open_contentdb then
local version = core.get_version() local version = core.get_version()
local url = core.settings:get("contentdb_url") .. "/packages/" .. package.url_part .. local url = core.settings:get("contentdb_url") .. "/packages/" .. package.url_part ..
@ -312,6 +313,12 @@ local function handle_submit(this, fields)
return true return true
end end
-- The events handled below are only valid if the package info has finished
-- loading.
if not info then
return false
end
if fields.tabs then if fields.tabs then
this.data.current_tab = tonumber(fields.tabs) this.data.current_tab = tonumber(fields.tabs)
return true return true

View file

@ -114,9 +114,12 @@ function update_detector.get_all()
local ret = {} local ret = {}
local all_content = pkgmgr.get_all() local all_content = pkgmgr.get_all()
for _, content in ipairs(all_content) do for _, content in ipairs(all_content) do
assert(content.path and content.path ~= "")
local cdb_id = pkgmgr.get_contentdb_id(content) local cdb_id = pkgmgr.get_contentdb_id(content)
if cdb_id then -- Do not consider content that we cannot modify to be out-of-date.
-- This would be technically correct but confusing for the user.
if cdb_id and core.may_modify_path(content.path) then
-- The backend will account for aliases in `latest_releases` -- The backend will account for aliases in `latest_releases`
local latest_release = latest_releases[cdb_id] local latest_release = latest_releases[cdb_id]
if not latest_release and content.type == "game" then if not latest_release and content.type == "game" then

View file

@ -48,12 +48,11 @@
"#": "For updating active/previous contributors, see the script in ./util/gather_git_credits.py", "#": "For updating active/previous contributors, see the script in ./util/gather_git_credits.py",
"contributors": [ "contributors": [
"Erich Schubert", "Erich Schubert",
"wrrrzr", "Lucas OH",
"siliconsniffer", "Xeno333",
"JosiahWI",
"veprogames",
"Miguel P.L", "Miguel P.L",
"AFCMS" "siliconsniffer",
"JosiahWI"
], ],
"previous_contributors": [ "previous_contributors": [
"Ælla Chiana Moskopp (erle) <erle@dieweltistgarnichtso.net> [Logo]", "Ælla Chiana Moskopp (erle) <erle@dieweltistgarnichtso.net> [Logo]",

View file

@ -33,13 +33,13 @@ end
local function buttonhandler(this, fields) local function buttonhandler(this, fields)
if fields.reconfigure then if fields.reconfigure then
local parent = this.parent
close_dialog(this) close_dialog(this)
local maintab = ui.find_by_name("maintab")
local dlg = create_settings_dlg("controls_keyboard_and_mouse") local dlg = create_settings_dlg("controls_keyboard_and_mouse")
dlg:set_parent(maintab) dlg:set_parent(parent)
maintab:hide() parent:hide()
dlg:show() dlg:show()
return true return true
@ -74,7 +74,7 @@ local function create_rebind_keys_dlg()
return dlg return dlg
end end
function migrate_keybindings() function migrate_keybindings(parent)
-- Show migration dialog if the user upgraded from an earlier version -- Show migration dialog if the user upgraded from an earlier version
-- and this has not yet been shown before, *or* if keys settings had to be changed -- and this has not yet been shown before, *or* if keys settings had to be changed
if core.is_first_run then if core.is_first_run then
@ -95,14 +95,14 @@ function migrate_keybindings()
end end
if not has_migration then if not has_migration then
return return parent
end end
local maintab = ui.find_by_name("maintab")
local dlg = create_rebind_keys_dlg() local dlg = create_rebind_keys_dlg()
dlg:set_parent(maintab) dlg:set_parent(parent)
maintab:hide() parent:hide()
dlg:show() dlg:show()
ui.update() ui.update()
return dlg
end end

View file

@ -11,7 +11,7 @@
local SETTING_NAME = "no_mtg_notification" local SETTING_NAME = "no_mtg_notification"
function check_reinstall_mtg() function check_reinstall_mtg(parent)
-- used to be in minetest.conf -- used to be in minetest.conf
if core.settings:get_bool(SETTING_NAME) then if core.settings:get_bool(SETTING_NAME) then
cache_settings:set_bool(SETTING_NAME, true) cache_settings:set_bool(SETTING_NAME, true)
@ -19,14 +19,14 @@ function check_reinstall_mtg()
end end
if cache_settings:get_bool(SETTING_NAME) then if cache_settings:get_bool(SETTING_NAME) then
return return parent
end end
local games = core.get_games() local games = core.get_games()
for _, game in ipairs(games) do for _, game in ipairs(games) do
if game.id == "minetest" then if game.id == "minetest" then
cache_settings:set_bool(SETTING_NAME, true) cache_settings:set_bool(SETTING_NAME, true)
return return parent
end end
end end
@ -40,16 +40,16 @@ function check_reinstall_mtg()
end end
if not mtg_world_found then if not mtg_world_found then
cache_settings:set_bool(SETTING_NAME, true) cache_settings:set_bool(SETTING_NAME, true)
return return parent
end end
local maintab = ui.find_by_name("maintab")
local dlg = create_reinstall_mtg_dlg() local dlg = create_reinstall_mtg_dlg()
dlg:set_parent(maintab) dlg:set_parent(parent)
maintab:hide() parent:hide()
dlg:show() dlg:show()
ui.update() ui.update()
return dlg
end end
local function get_formspec(dialogdata) local function get_formspec(dialogdata)
@ -74,22 +74,22 @@ end
local function buttonhandler(this, fields) local function buttonhandler(this, fields)
if fields.reinstall then if fields.reinstall then
local parent = this.parent
-- Don't set "no_mtg_notification" here so that the dialog will be shown -- Don't set "no_mtg_notification" here so that the dialog will be shown
-- again if downloading MTG fails for whatever reason. -- again if downloading MTG fails for whatever reason.
this:delete() this:delete()
local maintab = ui.find_by_name("maintab")
local dlg = create_contentdb_dlg(nil, "minetest/minetest") local dlg = create_contentdb_dlg(nil, "minetest/minetest")
dlg:set_parent(maintab) dlg:set_parent(parent)
maintab:hide() parent:hide()
dlg:show() dlg:show()
return true return true
end end
if fields.dismiss then if fields.dismiss then
cache_settings:set_bool("no_mtg_notification", true) cache_settings:set_bool(SETTING_NAME, true)
this:delete() this:delete()
return true return true
end end

View file

@ -112,8 +112,12 @@ local function init_globals()
tv_main:show() tv_main:show()
ui.update() ui.update()
check_reinstall_mtg() -- synchronous, chain parents to only show one at a time
migrate_keybindings() local parent = tv_main
parent = migrate_keybindings(parent)
check_reinstall_mtg(parent)
-- asynchronous, will only be shown if we're still on "maintab"
check_new_version() check_new_version()
end end

View file

@ -182,23 +182,17 @@ invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false
[**Keybindings] [**Keybindings]
# Key for moving the player forward.
keymap_forward (Move forward) key SYSTEM_SCANCODE_26 keymap_forward (Move forward) key SYSTEM_SCANCODE_26
# Key for moving the player backward.
# Will also disable autoforward, when active. # Will also disable autoforward, when active.
keymap_backward (Move backward) key SYSTEM_SCANCODE_22 keymap_backward (Move backward) key SYSTEM_SCANCODE_22
# Key for moving the player left.
keymap_left (Move left) key SYSTEM_SCANCODE_4 keymap_left (Move left) key SYSTEM_SCANCODE_4
# Key for moving the player right.
keymap_right (Move right) key SYSTEM_SCANCODE_7 keymap_right (Move right) key SYSTEM_SCANCODE_7
# Key for jumping.
keymap_jump (Jump) key SYSTEM_SCANCODE_44 keymap_jump (Jump) key SYSTEM_SCANCODE_44
# Key for sneaking.
# Also used for climbing down and descending in water if aux1_descends is disabled. # Also used for climbing down and descending in water if aux1_descends is disabled.
keymap_sneak (Sneak) key SYSTEM_SCANCODE_225 keymap_sneak (Sneak) key SYSTEM_SCANCODE_225
@ -210,13 +204,11 @@ keymap_dig (Dig/punch/use) key KEY_LBUTTON
# (Note: The actual meaning might vary on a per-game basis.) # (Note: The actual meaning might vary on a per-game basis.)
keymap_place (Place/use) key KEY_RBUTTON keymap_place (Place/use) key KEY_RBUTTON
# Key for opening the inventory.
keymap_inventory (Open inventory) key SYSTEM_SCANCODE_12 keymap_inventory (Open inventory) key SYSTEM_SCANCODE_12
# Key for moving fast in fast mode. # Key for moving fast in fast mode.
keymap_aux1 (Aux1) key SYSTEM_SCANCODE_8 keymap_aux1 (Aux1) key SYSTEM_SCANCODE_8
# Key for opening the chat window.
keymap_chat (Open chat) key SYSTEM_SCANCODE_23 keymap_chat (Open chat) key SYSTEM_SCANCODE_23
# Key for opening the chat window to type commands. # Key for opening the chat window to type commands.
@ -225,70 +217,48 @@ keymap_cmd (Command) key SYSTEM_SCANCODE_56
# Key for opening the chat window to type local commands. # Key for opening the chat window to type local commands.
keymap_cmd_local (Local command) key SYSTEM_SCANCODE_55 keymap_cmd_local (Local command) key SYSTEM_SCANCODE_55
# Key for toggling unlimited view range. keymap_rangeselect (Toggle unlimited view range) key
keymap_rangeselect (Range select) key
# Key for toggling flying.
keymap_freemove (Toggle fly) key SYSTEM_SCANCODE_14 keymap_freemove (Toggle fly) key SYSTEM_SCANCODE_14
# Key for toggling pitch move mode.
keymap_pitchmove (Toggle pitchmove) key keymap_pitchmove (Toggle pitchmove) key
# Key for toggling fast mode.
keymap_fastmove (Toggle fast) key SYSTEM_SCANCODE_13 keymap_fastmove (Toggle fast) key SYSTEM_SCANCODE_13
# Key for toggling noclip mode.
keymap_noclip (Toggle noclip) key SYSTEM_SCANCODE_11 keymap_noclip (Toggle noclip) key SYSTEM_SCANCODE_11
# Key for selecting the next item in the hotbar.
keymap_hotbar_next (Hotbar: select next item) key SYSTEM_SCANCODE_17 keymap_hotbar_next (Hotbar: select next item) key SYSTEM_SCANCODE_17
# Key for selecting the previous item in the hotbar.
keymap_hotbar_previous (Hotbar: select previous item) key SYSTEM_SCANCODE_5 keymap_hotbar_previous (Hotbar: select previous item) key SYSTEM_SCANCODE_5
# Key for muting the game.
keymap_mute (Mute) key SYSTEM_SCANCODE_16 keymap_mute (Mute) key SYSTEM_SCANCODE_16
# Key for increasing the volume.
keymap_increase_volume (Increase volume) key keymap_increase_volume (Increase volume) key
# Key for decreasing the volume.
keymap_decrease_volume (Decrease volume) key keymap_decrease_volume (Decrease volume) key
# Key for toggling autoforward.
keymap_autoforward (Toggle automatic forward) key keymap_autoforward (Toggle automatic forward) key
# Key for toggling cinematic mode.
keymap_cinematic (Toggle cinematic mode) key keymap_cinematic (Toggle cinematic mode) key
# Key for toggling display of minimap.
keymap_minimap (Toggle minimap) key SYSTEM_SCANCODE_25 keymap_minimap (Toggle minimap) key SYSTEM_SCANCODE_25
# Key for taking screenshots.
keymap_screenshot (Screenshot) key SYSTEM_SCANCODE_69 keymap_screenshot (Screenshot) key SYSTEM_SCANCODE_69
# Key for toggling fullscreen mode.
keymap_fullscreen (Toggle fullscreen) key SYSTEM_SCANCODE_68 keymap_fullscreen (Toggle fullscreen) key SYSTEM_SCANCODE_68
# Key for dropping the currently selected item.
keymap_drop (Drop item) key SYSTEM_SCANCODE_20 keymap_drop (Drop item) key SYSTEM_SCANCODE_20
# Key to use view zoom when possible.
keymap_zoom (Zoom) key SYSTEM_SCANCODE_29 keymap_zoom (Zoom) key SYSTEM_SCANCODE_29
# Key for toggling the display of the HUD.
keymap_toggle_hud (Toggle HUD) key SYSTEM_SCANCODE_58 keymap_toggle_hud (Toggle HUD) key SYSTEM_SCANCODE_58
# Key for toggling the display of chat.
keymap_toggle_chat (Toggle chat log) key SYSTEM_SCANCODE_59 keymap_toggle_chat (Toggle chat log) key SYSTEM_SCANCODE_59
# Key for toggling the display of the large chat console. keymap_console (Toggle large chat console) key SYSTEM_SCANCODE_67
keymap_console (Large chat console) key SYSTEM_SCANCODE_67
# Key for toggling the display of fog.
keymap_toggle_fog (Toggle fog) key SYSTEM_SCANCODE_60 keymap_toggle_fog (Toggle fog) key SYSTEM_SCANCODE_60
# Key for toggling the display of debug info.
keymap_toggle_debug (Toggle debug info) key SYSTEM_SCANCODE_62 keymap_toggle_debug (Toggle debug info) key SYSTEM_SCANCODE_62
# Key for toggling the display of the profiler. Used for development. # Key for toggling the display of the profiler. Used for development.
@ -297,109 +267,78 @@ keymap_toggle_profiler (Toggle profiler) key SYSTEM_SCANCODE_63
# Key for toggling the display of mapblock boundaries. # Key for toggling the display of mapblock boundaries.
keymap_toggle_block_bounds (Toggle block bounds) key keymap_toggle_block_bounds (Toggle block bounds) key
# Key for switching between first- and third-person camera.
keymap_camera_mode (Toggle camera mode) key SYSTEM_SCANCODE_6 keymap_camera_mode (Toggle camera mode) key SYSTEM_SCANCODE_6
# Key for increasing the viewing range.
keymap_increase_viewing_range_min (Increase view range) key SYSTEM_SCANCODE_46 keymap_increase_viewing_range_min (Increase view range) key SYSTEM_SCANCODE_46
# Key for decreasing the viewing range.
keymap_decrease_viewing_range_min (Decrease view range) key SYSTEM_SCANCODE_45 keymap_decrease_viewing_range_min (Decrease view range) key SYSTEM_SCANCODE_45
# Key for selecting the first hotbar slot. # Modifier key bind for closing your world.
# Requires ESC + the selected key to work.
keymap_close_world (Return to Main Menu) key
keymap_slot1 (Hotbar slot 1) key SYSTEM_SCANCODE_30 keymap_slot1 (Hotbar slot 1) key SYSTEM_SCANCODE_30
# Key for selecting the second hotbar slot.
keymap_slot2 (Hotbar slot 2) key SYSTEM_SCANCODE_31 keymap_slot2 (Hotbar slot 2) key SYSTEM_SCANCODE_31
# Key for selecting the third hotbar slot.
keymap_slot3 (Hotbar slot 3) key SYSTEM_SCANCODE_32 keymap_slot3 (Hotbar slot 3) key SYSTEM_SCANCODE_32
# Key for selecting the fourth hotbar slot.
keymap_slot4 (Hotbar slot 4) key SYSTEM_SCANCODE_33 keymap_slot4 (Hotbar slot 4) key SYSTEM_SCANCODE_33
# Key for selecting the fifth hotbar slot.
keymap_slot5 (Hotbar slot 5) key SYSTEM_SCANCODE_34 keymap_slot5 (Hotbar slot 5) key SYSTEM_SCANCODE_34
# Key for selecting the sixth hotbar slot.
keymap_slot6 (Hotbar slot 6) key SYSTEM_SCANCODE_35 keymap_slot6 (Hotbar slot 6) key SYSTEM_SCANCODE_35
# Key for selecting the seventh hotbar slot.
keymap_slot7 (Hotbar slot 7) key SYSTEM_SCANCODE_36 keymap_slot7 (Hotbar slot 7) key SYSTEM_SCANCODE_36
# Key for selecting the eighth hotbar slot.
keymap_slot8 (Hotbar slot 8) key SYSTEM_SCANCODE_37 keymap_slot8 (Hotbar slot 8) key SYSTEM_SCANCODE_37
# Key for selecting the ninth hotbar slot.
keymap_slot9 (Hotbar slot 9) key SYSTEM_SCANCODE_38 keymap_slot9 (Hotbar slot 9) key SYSTEM_SCANCODE_38
# Key for selecting the tenth hotbar slot.
keymap_slot10 (Hotbar slot 10) key SYSTEM_SCANCODE_39 keymap_slot10 (Hotbar slot 10) key SYSTEM_SCANCODE_39
# Key for selecting the 11th hotbar slot.
keymap_slot11 (Hotbar slot 11) key keymap_slot11 (Hotbar slot 11) key
# Key for selecting the 12th hotbar slot.
keymap_slot12 (Hotbar slot 12) key keymap_slot12 (Hotbar slot 12) key
# Key for selecting the 13th hotbar slot.
keymap_slot13 (Hotbar slot 13) key keymap_slot13 (Hotbar slot 13) key
# Key for selecting the 14th hotbar slot.
keymap_slot14 (Hotbar slot 14) key keymap_slot14 (Hotbar slot 14) key
# Key for selecting the 15th hotbar slot.
keymap_slot15 (Hotbar slot 15) key keymap_slot15 (Hotbar slot 15) key
# Key for selecting the 16th hotbar slot.
keymap_slot16 (Hotbar slot 16) key keymap_slot16 (Hotbar slot 16) key
# Key for selecting the 17th hotbar slot.
keymap_slot17 (Hotbar slot 17) key keymap_slot17 (Hotbar slot 17) key
# Key for selecting the 18th hotbar slot.
keymap_slot18 (Hotbar slot 18) key keymap_slot18 (Hotbar slot 18) key
# Key for selecting the 19th hotbar slot.
keymap_slot19 (Hotbar slot 19) key keymap_slot19 (Hotbar slot 19) key
# Key for selecting the 20th hotbar slot.
keymap_slot20 (Hotbar slot 20) key keymap_slot20 (Hotbar slot 20) key
# Key for selecting the 21st hotbar slot.
keymap_slot21 (Hotbar slot 21) key keymap_slot21 (Hotbar slot 21) key
# Key for selecting the 22nd hotbar slot.
keymap_slot22 (Hotbar slot 22) key keymap_slot22 (Hotbar slot 22) key
# Key for selecting the 23rd hotbar slot.
keymap_slot23 (Hotbar slot 23) key keymap_slot23 (Hotbar slot 23) key
# Key for selecting the 24th hotbar slot.
keymap_slot24 (Hotbar slot 24) key keymap_slot24 (Hotbar slot 24) key
# Key for selecting the 25th hotbar slot.
keymap_slot25 (Hotbar slot 25) key keymap_slot25 (Hotbar slot 25) key
# Key for selecting the 26th hotbar slot.
keymap_slot26 (Hotbar slot 26) key keymap_slot26 (Hotbar slot 26) key
# Key for selecting the 27th hotbar slot.
keymap_slot27 (Hotbar slot 27) key keymap_slot27 (Hotbar slot 27) key
# Key for selecting the 28th hotbar slot.
keymap_slot28 (Hotbar slot 28) key keymap_slot28 (Hotbar slot 28) key
# Key for selecting the 29th hotbar slot.
keymap_slot29 (Hotbar slot 29) key keymap_slot29 (Hotbar slot 29) key
# Key for selecting the 30th hotbar slot.
keymap_slot30 (Hotbar slot 30) key keymap_slot30 (Hotbar slot 30) key
# Key for selecting the 31st hotbar slot.
keymap_slot31 (Hotbar slot 31) key keymap_slot31 (Hotbar slot 31) key
# Key for selecting the 32nd hotbar slot.
keymap_slot32 (Hotbar slot 32) key keymap_slot32 (Hotbar slot 32) key
[*Touchscreen] [*Touchscreen]
@ -2104,11 +2043,11 @@ transparency_sorting_group_by_buffers (Transparency Sorting Group by Buffers) bo
cloud_radius (Cloud radius) int 12 8 62 cloud_radius (Cloud radius) int 12 8 62
# Delay between mesh updates on the client in ms. Increasing this will slow # Delay between mesh updates on the client in ms. Increasing this will slow
# down the rate of mesh updates, thus reducing jitter on slower clients. # down the rate of mesh updates, which can help reduce jitter.
mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50 mesh_generation_interval (Mapblock mesh generation delay) int 0 0 25
# Number of threads to use for mesh generation. # Number of threads to use for mesh generation.
# Value of 0 (default) will let Luanti autodetect the number of available threads. # Value of 0 (default) will let Luanti automatically choose the number of threads.
mesh_generation_threads (Mapblock mesh generation threads) int 0 0 8 mesh_generation_threads (Mapblock mesh generation threads) int 0 0 8
# All mesh buffers with less than this number of vertices will be merged # All mesh buffers with less than this number of vertices will be merged

60
doc/README.md Normal file
View file

@ -0,0 +1,60 @@
# Documentation
This directory contains mostly reference documentation for the Luanti engine.
For a less prescriptive and more guiding documentation, also look at:
https://docs.luanti.org
Note that the inner workings of the engine are not well documented. It's most
often better to read the code.
Markdown files are written in a way that they can also be read in plain text.
When modifying, please keep it that way!
Here is a list with descriptions of relevant files:
## Server Modding
- [lua_api.md](lua_api.md): Server Modding API reference. (Not only the Lua part,
but also file structure and everything else.)
If you want to make a mod or game, look here!
A rendered version is also available at <https://api.luanti.org/>.
- [builtin_entities.md](builtin_entities.md): Doc for entities predefined by the
engine (in builtin), i.e. dropped items and falling nodes.
## Client-Side Content
- [texture_packs.md](texture_packs.md): Layout and description of Luanti's
texture packs structure and configuration.
- [client_lua_api.md](client_lua_api.md): Client-Provided Client-Side Modding
(CPCSM) API reference.
## Mainmenu scripting
- [menu_lua_api.md](menu_lua_api.md): API reference for the mainmenu scripting
environment.
- [fst_api.txt](fst_api.txt): Formspec Toolkit API, included in builtin for the
main menu.
## Formats and Protocols
- [world_format.md](world_format.md): Structure of Luanti world directories and
format of the files therein.
Note: If you want to write your own deserializer, it will be easier to read
the `serialize()` and `deSerialize()` functions of the various structures in
C++, e.g. `MapBlock::deSerialize()`.
- [protocol.txt](protocol.txt): *Rough* outline of Luanti's network protocol.
## Misc.
- [compiling/](compiling/): Compilation instructions, and options.
- [ides/](ides/): Instructions for configuring certain IDEs for engine development.
- [developing/](developing/): Information about Luanti development.
Note: [developing/profiling.md](developing/profiling.md) can be useful for
modders and server owners!
- [android.md](android.md): Android quirks.
- [direction.md](direction.md): Information related to the future direction of
Luanti. Commonly referred to as the roadmap document.
- [breakages.md](breakages.md): List of planned breakages for the next major
release, i.e. 6.0.0.
- [docker_server.md](docker_server.md): Information about our Docker server
images in the ghcr.

View file

@ -42,7 +42,7 @@ configuration file can usually be found at:
* After 5.4.2: * After 5.4.2:
* `/sdcard/Android/data/net.minetest.minetest/` or `/storage/emulated/0/Android/data/net.minetest.minetest/` if stored on the device * `/sdcard/Android/data/net.minetest.minetest/` or `/storage/emulated/0/Android/data/net.minetest.minetest/` if stored on the device
* `/storage/emulated/(varying folder name)/Android/data/net.minetest.minetest/` if stored on the SD card * `/storage/emulated/(varying folder name)/Android/data/net.minetest.minetest/` if stored on the SD card
* [Learn more about Android directory](https://wiki.luanti.org/Accessing_Android_Data_Directory) * [Learn more about Android directory](https://docs.luanti.org/for-players/mobile/)
## Useful settings ## Useful settings

View file

@ -25,3 +25,4 @@ This list is largely advisory and items may be reevaluated once the time comes.
* remove built-in knockback and related functions entirely * remove built-in knockback and related functions entirely
* remove `safe` parameter from `core.serialize`, always enforce `safe = true`. * remove `safe` parameter from `core.serialize`, always enforce `safe = true`.
possibly error when `loadstring` calls are encountered in `core.deserialize`. possibly error when `loadstring` calls are encountered in `core.deserialize`.
* introduce strict type checking for all instances of `v3s16` / `v3f` read from Lua

View file

@ -1,12 +1,15 @@
Luanti Lua Client Modding API Reference 5.12.0 Luanti Lua Client Modding API Reference 5.14.0
============================================== ==============================================
**WARNING**: if you're looking for the `minetest` namespace (e.g. `minetest.something`), **WARNING**: if you're looking for the `minetest` namespace (e.g. `minetest.something`),
it's now called `core` due to the renaming of Luanti (formerly Minetest). it's now called `core` due to the renaming of Luanti (formerly Minetest).
`minetest` will keep existing as an alias, so that old code won't break. `minetest` will keep existing as an alias, so that old code won't break.
Note that `core` has already existed since version 0.4.10, so you can use it
safely without breaking backwards compatibility.
* More information at <http://www.luanti.org/> * More information at <http://www.luanti.org/>
* Developer Wiki: <https://dev.luanti.org/> * Additional documentation: <https://docs.luanti.org/>
Introduction Introduction
------------ ------------

View file

@ -1,26 +1,27 @@
# Developer documentation # Developer documentation
## Wiki ## Luanti Documentation
Some important development docs are found in the wiki: https://dev.luanti.org/ Some important development docs are found on the docs site: https://docs.luanti.org/
Notable pages: Notable pages:
- [Releasing Luanti](https://dev.luanti.org/Releasing_Luanti) - [Releasing Luanti](https://docs.luanti.org/for-engine-devs/releasing-luanti/)
- [Engine translations](https://dev.luanti.org/Translation#Maintaining_engine_translations) - [Engine translations](https://docs.luanti.org/for-creators/translation/)
- [Changelog](https://dev.luanti.org/Changelog) - [Changelog](https://docs.luanti.org/about/changelog/)
- [Organisation](https://dev.luanti.org/Organisation) - [Organisation](https://docs.luanti.org/for-engine-devs/organization/)
- [Code style guidelines](https://dev.luanti.org/Code_style_guidelines) - [Code style guidelines](https://docs.luanti.org/for-engine-devs/code-style-guidelines/)
and [Lua code style guidelines](https://docs.luanti.org/for-engine-devs/lua-code-style-guidelines/)
## In this folder ## In this folder
- [Developing minetestserver with Docker](docker.md) - [docker.md](docker.md): Developing minetestserver with Docker
- [Android tips & tricks](android.md) - [android.md](android.md): Android tips & tricks
- [OS/library compatibility policy](os-compatibility.md) - [os-compatibility.md](os-compatibility.md): OS/library compatibility policy
- [Miscellaneous](misc.md) - [profiling.md](profiling.md): Profiling instructions
## IRC ## IRC
Oftentimes knowledge hasn't been written down (yet) and your best bet is to ask someone experienced and/or the core developers. Oftentimes knowledge hasn't been written down (yet) and your best bet is to ask someone experienced and/or the core developers.
Feel free to join the [#minetest-dev IRC](https://wiki.luanti.org/IRC) and ask questions related to **engine development**. Feel free to join the [#luanti-dev IRC](https://docs.luanti.org/about/irc/) and ask questions related to **engine development**.

View file

@ -1,4 +1,4 @@
# Miscellaneous # Profiling
## Profiling Luanti on Linux with perf ## Profiling Luanti on Linux with perf

View file

@ -37,7 +37,7 @@ Examples include
[general view distance](https://github.com/luanti-org/luanti/issues/7222). [general view distance](https://github.com/luanti-org/luanti/issues/7222).
This includes work on maintaining This includes work on maintaining
[our Irrlicht fork](https://github.com/minetest/irrlicht), and switching to [our Irrlicht fork](https://github.com/luanti-org/luanti/tree/master/irr), and switching to
alternative libraries to replace Irrlicht functionality as needed alternative libraries to replace Irrlicht functionality as needed
### 2.2 Internal code refactoring ### 2.2 Internal code refactoring

View file

@ -3,8 +3,10 @@ Formspec toolkit api 0.0.3
Formspec toolkit is a set of functions to create basic ui elements. Formspec toolkit is a set of functions to create basic ui elements.
You can find the files in builtin/fstk/.
File: fst/ui.lua
File: fstk/ui.lua
---------------- ----------------
ui.lua adds base ui interface to add additional components to. ui.lua adds base ui interface to add additional components to.
@ -25,7 +27,7 @@ ui.find_by_name(name) --> returns component or nil
^ find a component within ui ^ find a component within ui
^ name: name of component to look for ^ name: name of component to look for
File: fst/tabview.lua File: fstk/tabview.lua
--------------------- ---------------------
tabview_create(name, size, tabheaderpos) --> returns tabview component tabview_create(name, size, tabheaderpos) --> returns tabview component
@ -92,7 +94,7 @@ methods:
* icon: path to icon * icon: path to icon
* on_click(tabview): callback function * on_click(tabview): callback function
File: fst/dialog.lua File: fstk/dialog.lua
--------------------- ---------------------
Only one dialog can be shown at a time. If a dialog is closed it's parent is Only one dialog can be shown at a time. If a dialog is closed it's parent is
gonna be activated and shown again. gonna be activated and shown again.
@ -129,7 +131,7 @@ members:
- parent - parent
^ parent component to return to on exit ^ parent component to return to on exit
File: fst/buttonbar.lua File: fstk/buttonbar.lua
----------------------- -----------------------
buttonbar_create(name, pos, size, bgcolor, cbf_buttonhandler) buttonbar_create(name, pos, size, bgcolor, cbf_buttonhandler)

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
Luanti Lua Mainmenu API Reference 5.12.0 Luanti Lua Mainmenu API Reference 5.14.0
======================================== ========================================
Introduction Introduction
@ -23,8 +23,8 @@ Callbacks
* `core.button_handler(fields)`: called when a button is pressed. * `core.button_handler(fields)`: called when a button is pressed.
* `fields` = `{name1 = value1, name2 = value2, ...}` * `fields` = `{name1 = value1, name2 = value2, ...}`
* `core.event_handler(event)` * `core.event_handler(event)`
* `event`: `"MenuQuit"`, `"KeyEnter"`, `"ExitButton"`, `"EditBoxEnter"` or * `event`: `"MenuQuit"` (derived from `quit`) or `"FullscreenChange"`
`"FullscreenChange"` The main menu may issue custom events, such as `"Refresh"` (server list).
* `core.on_before_close()`: called before the menu is closed, either to exit or * `core.on_before_close()`: called before the menu is closed, either to exit or
to join a game to join a game

View file

@ -3,7 +3,8 @@ Updated 2011-06-18
A custom protocol over UDP. A custom protocol over UDP.
Integers are big endian. Integers are big endian.
Refer to connection.{h,cpp} for further reference. Refer to network/mtp/internal.h, network/networkprotocol.{h,cpp}, and
server/clientiface.h for further reference.
Initialization: Initialization:
- A dummy reliable packet with peer_id=PEER_ID_INEXISTENT=0 is sent to the server: - A dummy reliable packet with peer_id=PEER_ID_INEXISTENT=0 is sent to the server:

View file

@ -401,7 +401,7 @@ See below for description.
Luanti will correct lighting in the day light bank when the block at Luanti will correct lighting in the day light bank when the block at
`(1, 0, 0)` is also loaded. `(1, 0, 0)` is also loaded.
Timestamp and node ID mappings were introduced in map format version 29. Timestamp and node ID mappings come here if map format version >= 29.
* `u32` timestamp * `u32` timestamp
* Timestamp when last saved, as seconds from starting the game. * Timestamp when last saved, as seconds from starting the game.
* `0xffffffff` = invalid/unknown timestamp, nothing should be done with the time * `0xffffffff` = invalid/unknown timestamp, nothing should be done with the time
@ -482,13 +482,7 @@ Timestamp and node ID mappings were introduced in map format version 29.
* `s32` timeout * 1000 * `s32` timeout * 1000
* `s32` elapsed * 1000 * `s32` elapsed * 1000
* Since map format version 25: * Map format version >= 25: see below
* `u8` length of the data of a single timer (always 2+4+4=10)
* `u16` `num_of_timers`
* foreach `num_of_timers`:
* `u16` timer position (`(z*16*16 + y*16 + x)`)
* `s32` timeout * 1000
* `s32` elapsed * 1000
`u8` static object version: `u8` static object version:
* Always 0 * Always 0
@ -516,6 +510,14 @@ Before map format version 29:
* `u16` `name_len` * `u16` `name_len`
* `u8[name_len]` `name` * `u8[name_len]` `name`
Since map format version 25, node timers come here:
* `u8` length of the data of a single timer (always 2+4+4=10)
* `u16` `num_of_timers`
* foreach `num_of_timers`:
* `u16` timer position (`(z*16*16 + y*16 + x)`)
* `s32` timeout * 1000
* `s32` elapsed * 1000
End of File (EOF). End of File (EOF).
# Format of Nodes # Format of Nodes
@ -594,9 +596,11 @@ Object types:
* `s32` yaw * 1000 * `s32` yaw * 1000
Since protocol version 37: Since protocol version 37:
* `u8` `version2` (=1) * `u8` `version2` (=1 or 2)
* `s32` pitch * 1000 * `s32` pitch * 1000
* `s32` roll * 1000 * `s32` roll * 1000
* if version2 >= 2:
* `u8[16]` guid
# Itemstring Format # Itemstring Format

View file

@ -106,7 +106,7 @@ core.register_chatcommand("bench_bulk_set_node", {
core.chat_send_player(name, "Warming up finished, now benchmarking ...") core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local start_time = core.get_us_time() local start_time = core.get_us_time()
for i=1,#pos_list do for i = 1, #pos_list do
core.set_node(pos_list[i], {name = "mapgen_stone"}) core.set_node(pos_list[i], {name = "mapgen_stone"})
end end
local middle_time = core.get_us_time() local middle_time = core.get_us_time()
@ -116,6 +116,7 @@ core.register_chatcommand("bench_bulk_set_node", {
((middle_time - start_time)) / 1000, ((middle_time - start_time)) / 1000,
((end_time - middle_time)) / 1000 ((end_time - middle_time)) / 1000
) )
print(msg)
return true, msg return true, msg
end, end,
}) })
@ -129,16 +130,13 @@ core.register_chatcommand("bench_bulk_get_node", {
return false, "No player." return false, "No player."
end end
local pos_list = get_positions_cube(player:get_pos()) local pos_list = get_positions_cube(player:get_pos())
local dummy = 0
local function bench() local function bench()
local start_time = core.get_us_time() local start_time = core.get_us_time()
for i=1,#pos_list do for i = 1, #pos_list do
local n = core.get_node(pos_list[i]) local n = core.get_node(pos_list[i])
-- Make sure the name lookup is never optimized away. -- Make sure the name lookup is not optimized away (can this even happen?)
-- Table allocation might still be omitted. But only accessing dummy = dummy + #n.name
-- the name of a node is a common pattern anyways.
if n.name == "benchmarks:nonexistent_node" then
error("should never happen")
end
end end
return core.get_us_time() - start_time return core.get_us_time() - start_time
end end
@ -151,6 +149,115 @@ core.register_chatcommand("bench_bulk_get_node", {
local msg = string.format("Benchmark results: core.get_node loop 1: %.2f ms", local msg = string.format("Benchmark results: core.get_node loop 1: %.2f ms",
result_us / 1000) result_us / 1000)
print(msg)
return true, msg
end,
})
core.register_chatcommand("bench_bulk_get_node_raw", {
params = "",
description = "Benchmark: Bulk-get 99×99×99 nodes with raw API",
func = function(name, param)
local player = core.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos_list = get_positions_cube(player:get_pos())
local dummy = 0
local function bench()
local start_time = core.get_us_time()
for i = 1, #pos_list do
local pos_i = pos_list[i]
local nid = core.get_node_raw(pos_i.x, pos_i.y, pos_i.z)
-- Make sure the result is not optimized away
dummy = dummy + nid
end
return core.get_us_time() - start_time
end
core.chat_send_player(name, "Benchmarking core.get_node_raw. Warming up ...")
bench()
core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local result_us = bench()
local msg = string.format("Benchmark results: core.get_node_raw loop 1: %.2f ms",
result_us / 1000)
print(msg)
return true, msg
end,
})
core.register_chatcommand("bench_bulk_get_node_raw2", {
params = "",
description = "Benchmark: Bulk-get 99×99×99 nodes with raw API and lookup names",
func = function(name, param)
local player = core.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos_list = get_positions_cube(player:get_pos())
local dummy = 0
local function bench()
local start_time = core.get_us_time()
for i = 1, #pos_list do
local pos_i = pos_list[i]
local nid = core.get_node_raw(pos_i.x, pos_i.y, pos_i.z)
local name = core.get_name_from_content_id(nid)
-- Make sure the name lookup is not optimized away
dummy = dummy + #name
end
return core.get_us_time() - start_time
end
core.chat_send_player(name, "Benchmarking core.get_node_raw+get_name_from_content_id. Warming up ...")
bench()
core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local result_us = bench()
local msg = string.format("Benchmark results: core.get_node_raw+get_name_from_content_id loop 1: %.2f ms",
result_us / 1000)
print(msg)
return true, msg
end,
})
core.register_chatcommand("bench_bulk_get_node_vm", {
params = "",
description = "Benchmark: Bulk-get 99×99×99 nodes with voxel manipulator",
func = function(name, param)
local player = core.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos = player:get_pos()
local dummy = 0
local function bench()
local start_time = core.get_us_time()
local vm = core.get_voxel_manip(pos:offset(1,1,1), pos:offset(100,100,100))
local data = vm:get_data()
local mid_time = core.get_us_time()
-- Note that the VManip will actually retrieve more than just the 100³ nodes
-- and also we don't need to iterate pos_list here, so it's not an entirely
-- fair comparison.
for i = 1, 99*99*99 do
local nid = data[i]
-- Make sure the table lookup is not optimized away
dummy = dummy + nid
end
return core.get_us_time() - start_time, mid_time - start_time
end
core.chat_send_player(name, "Benchmarking core.get_voxel_vmanip+get_data+loop . Warming up ...")
bench()
core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local result_us, get_data_us = bench()
local msg = string.format("Benchmark results: core.get_voxel_vmanip+get_data+loop loop 1: %.2f ms of which get_data() %.2f ms",
result_us / 1000, get_data_us / 1000)
print(msg)
return true, msg return true, msg
end, end,
}) })
@ -174,7 +281,7 @@ core.register_chatcommand("bench_bulk_swap_node", {
core.chat_send_player(name, "Warming up finished, now benchmarking ...") core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local start_time = core.get_us_time() local start_time = core.get_us_time()
for i=1,#pos_list do for i = 1, #pos_list do
core.swap_node(pos_list[i], {name = "mapgen_stone"}) core.swap_node(pos_list[i], {name = "mapgen_stone"})
end end
local middle_time = core.get_us_time() local middle_time = core.get_us_time()
@ -184,6 +291,7 @@ core.register_chatcommand("bench_bulk_swap_node", {
((middle_time - start_time)) / 1000, ((middle_time - start_time)) / 1000,
((end_time - middle_time)) / 1000 ((end_time - middle_time)) / 1000
) )
print(msg)
return true, msg return true, msg
end, end,
}) })

View file

@ -12,4 +12,10 @@ Jordach (CC BY-SA 3.0):
Zeg9 (CC BY-SA 3.0): Zeg9 (CC BY-SA 3.0):
testentities_lava_flan.x testentities_lava_flan.x
testentities_lava_flan.png testentities_lava_flan.png
"Cool Guy":
hecks (refer to irr/LICENSE):
testentities_cool_guy.x
testentities_cool_guy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

File diff suppressed because one or more lines are too long

View file

@ -102,6 +102,19 @@ core.register_entity("testentities:lava_flan", {
end, end,
}) })
core.register_entity("testentities:cool_guy", {
initial_properties = {
visual = "mesh",
mesh = "testentities_cool_guy.x",
textures = {
"testentities_cool_guy.png"
},
},
on_activate = function(self)
self.object:set_animation({x = 0, y = 29}, 30, 0, true)
end,
})
-- Advanced visual tests -- Advanced visual tests
-- An entity for testing animated and yaw-modulated sprites -- An entity for testing animated and yaw-modulated sprites

View file

@ -255,3 +255,17 @@ local function test_item_drop(_, pos)
assert(itemstack_ret:equals(itemstack_src)) assert(itemstack_ret:equals(itemstack_src))
end end
unittests.register("test_item_drop", test_item_drop, {map=true}) unittests.register("test_item_drop", test_item_drop, {map=true})
local function test_entity_guid(_, pos)
local obj0 = core.add_entity(pos, "unittests:dummy")
local obj1 = core.add_entity(pos, "unittests:dummy")
assert(obj0 ~= obj1)
assert(obj0:get_guid() ~= obj1:get_guid())
assert(core.objects_by_guid[obj0:get_guid()] == obj0)
assert(core.objects_by_guid[obj1:get_guid()] == obj1)
obj0:remove()
obj1:remove()
end
unittests.register("test_entity_guid", test_entity_guid, {map=true})

View file

@ -29,6 +29,6 @@ if core.ipc_cas("unittests:mg_once", nil, true) then
end end
core.register_on_generated(function(vm, pos1, pos2, blockseed) core.register_on_generated(function(vm, pos1, pos2, blockseed)
local n = tonumber(core.get_mapgen_setting("chunksize")) * 16 - 1 local cs = core.get_mapgen_chunksize()
assert(pos2:subtract(pos1) == vector.new(n, n, n)) assert(pos2:subtract(pos1) == cs:multiply(core.MAP_BLOCKSIZE):subtract(1))
end) end)

View file

@ -67,18 +67,6 @@ local function test_dynamic_media(cb, player)
end end
unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true}) unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true})
local function test_v3f_metatable(player)
assert(vector.check(player:get_pos()))
end
unittests.register("test_v3f_metatable", test_v3f_metatable, {player=true})
local function test_v3s16_metatable(player, pos)
local node = core.get_node(pos)
local found_pos = core.find_node_near(pos, 0, node.name, true)
assert(vector.check(found_pos))
end
unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true})
local function test_clear_meta(_, pos) local function test_clear_meta(_, pos)
local ref = core.get_meta(pos) local ref = core.get_meta(pos)

View file

@ -204,3 +204,12 @@ local function run_player_hotbar_clamp_tests(player)
player:hud_set_hotbar_itemcount(old_bar_size) player:hud_set_hotbar_itemcount(old_bar_size)
end end
unittests.register("test_player_hotbar_clamp", run_player_hotbar_clamp_tests, {player=true}) unittests.register("test_player_hotbar_clamp", run_player_hotbar_clamp_tests, {player=true})
--
-- Player GUID
--
local function test_player_guid(player)
assert(player:get_guid() == player:get_player_name())
assert(core.objects_by_guid[player:get_guid()] == player)
end
unittests.register("test_player_guid", test_player_guid, {player=true})

View file

@ -1,9 +1,9 @@
IrrlichtMt version 1.9 IrrlichtMt version 1.9
====================== ======================
IrrlichtMt is the 3D engine of [Minetest](https://github.com/minetest). IrrlichtMt is the 3D engine of [Luanti](https://github.com/luanti-org).
It is based on the [Irrlicht Engine](https://irrlicht.sourceforge.io/) but is now developed independently. It is based on the [Irrlicht Engine](https://irrlicht.sourceforge.io/) but is now developed independently.
It is intentionally not compatible to upstream and is planned to be eventually absorbed into Minetest. It is intentionally not compatible to upstream and is planned to be eventually absorbed into Luanti.
Build Build
----- -----

View file

@ -14,8 +14,6 @@
#include "../src/os.h" #include "../src/os.h"
#endif #endif
namespace irr
{
namespace scene namespace scene
{ {
//! Template implementation of the IIndexBuffer interface //! Template implementation of the IIndexBuffer interface
@ -95,4 +93,3 @@ public:
typedef CIndexBuffer<u16> SIndexBuffer; typedef CIndexBuffer<u16> SIndexBuffer;
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -9,8 +9,6 @@
#include "CVertexBuffer.h" #include "CVertexBuffer.h"
#include "CIndexBuffer.h" #include "CIndexBuffer.h"
namespace irr
{
namespace scene namespace scene
{ {
//! Template implementation of the IMeshBuffer interface //! Template implementation of the IMeshBuffer interface
@ -87,7 +85,7 @@ public:
{ {
if (Vertices->getCount()) { if (Vertices->getCount()) {
BoundingBox.reset(Vertices->getPosition(0)); BoundingBox.reset(Vertices->getPosition(0));
const irr::u32 vsize = Vertices->getCount(); const u32 vsize = Vertices->getCount();
for (u32 i = 1; i < vsize; ++i) for (u32 i = 1; i < vsize; ++i)
BoundingBox.addInternalPoint(Vertices->getPosition(i)); BoundingBox.addInternalPoint(Vertices->getPosition(i));
} else } else
@ -146,4 +144,3 @@ typedef CMeshBuffer<video::S3DVertex2TCoords> SMeshBufferLightMap;
//! Meshbuffer with vertices having tangents stored, e.g. for normal mapping //! Meshbuffer with vertices having tangents stored, e.g. for normal mapping
typedef CMeshBuffer<video::S3DVertexTangents> SMeshBufferTangents; typedef CMeshBuffer<video::S3DVertexTangents> SMeshBufferTangents;
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -14,8 +14,6 @@
#include "../src/os.h" #include "../src/os.h"
#endif #endif
namespace irr
{
namespace scene namespace scene
{ {
//! Template implementation of the IVertexBuffer interface //! Template implementation of the IVertexBuffer interface
@ -128,4 +126,3 @@ typedef CVertexBuffer<video::S3DVertex2TCoords> SVertexBufferLightMap;
typedef CVertexBuffer<video::S3DVertexTangents> SVertexBufferTangents; typedef CVertexBuffer<video::S3DVertexTangents> SVertexBufferTangents;
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "irrTypes.h" #include "irrTypes.h"
namespace irr
{
namespace scene namespace scene
{ {
@ -32,4 +30,3 @@ const c8 *const AutomaticCullingNames[] = {
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -4,8 +4,6 @@
#pragma once #pragma once
namespace irr
{
namespace scene namespace scene
{ {
@ -38,4 +36,3 @@ enum E_DEBUG_SCENE_TYPE
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -4,9 +4,6 @@
#pragma once #pragma once
namespace irr
{
//! An enum for the different device types supported by the Irrlicht Engine. //! An enum for the different device types supported by the Irrlicht Engine.
enum E_DEVICE_TYPE enum E_DEVICE_TYPE
{ {
@ -42,5 +39,3 @@ enum E_DEVICE_TYPE
May support hw-acceleration via OpenGL-ES */ May support hw-acceleration via OpenGL-ES */
EIDT_ANDROID, EIDT_ANDROID,
}; };
} // end namespace irr

View file

@ -4,8 +4,6 @@
#pragma once #pragma once
namespace irr
{
namespace video namespace video
{ {
@ -140,4 +138,3 @@ enum E_VIDEO_DRIVER_FEATURE
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -4,8 +4,6 @@
#pragma once #pragma once
namespace irr
{
namespace video namespace video
{ {
@ -36,4 +34,3 @@ enum E_DRIVER_TYPE
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -3,8 +3,6 @@
#pragma once #pragma once
namespace irr
{
namespace gui namespace gui
{ {
@ -31,4 +29,3 @@ enum EFOCUS_FLAG
}; };
} // namespace gui } // namespace gui
} // namespace irr

View file

@ -6,8 +6,6 @@
#include "irrTypes.h" #include "irrTypes.h"
namespace irr
{
namespace gui namespace gui
{ {
enum EGUI_ALIGNMENT enum EGUI_ALIGNMENT
@ -32,4 +30,3 @@ const c8 *const GUIAlignmentNames[] = {
}; };
} // namespace gui } // namespace gui
} // namespace irr

View file

@ -6,8 +6,6 @@
#include "irrTypes.h" #include "irrTypes.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -72,4 +70,3 @@ enum EGUI_ELEMENT_TYPE
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -4,8 +4,6 @@
#pragma once #pragma once
namespace irr
{
namespace scene namespace scene
{ {
@ -37,4 +35,3 @@ enum E_BUFFER_TYPE
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -4,8 +4,6 @@
#pragma once #pragma once
namespace irr
{
namespace video namespace video
{ {
@ -67,4 +65,3 @@ enum E_MATERIAL_PROP
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "irrTypes.h" #include "irrTypes.h"
namespace irr
{
namespace video namespace video
{ {
@ -71,4 +69,3 @@ constexpr u32 numBuiltInMaterials =
sizeof(sBuiltInMaterialTypeNames) / sizeof(char *) - 1; sizeof(sBuiltInMaterialTypeNames) / sizeof(char *) - 1;
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -4,8 +4,6 @@
#pragma once #pragma once
namespace irr
{
namespace scene namespace scene
{ {
@ -40,4 +38,3 @@ enum E_PRIMITIVE_TYPE
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "irrTypes.h" #include "irrTypes.h"
namespace irr
{
namespace io namespace io
{ {
@ -27,4 +25,3 @@ enum EREAD_FILE_TYPE
EFIT_UNKNOWN = MAKE_IRR_ID('u', 'n', 'k', 'n') EFIT_UNKNOWN = MAKE_IRR_ID('u', 'n', 'k', 'n')
}; };
} // end namespace io } // end namespace io
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "irrTypes.h" #include "irrTypes.h"
namespace irr
{
namespace scene namespace scene
{ {
@ -46,4 +44,3 @@ enum ESCENE_NODE_TYPE
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -1,7 +1,5 @@
#pragma once #pragma once
namespace irr
{
namespace video namespace video
{ {
@ -31,4 +29,3 @@ const char *const sBuiltInVertexAttributeNames[] = {
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -6,7 +6,7 @@
#include "SMaterial.h" // MATERIAL_MAX_TEXTURES #include "SMaterial.h" // MATERIAL_MAX_TEXTURES
namespace irr::video namespace video
{ {
//! enumeration for geometry transformation states //! enumeration for geometry transformation states
@ -71,5 +71,5 @@ enum E_FOG_TYPE
EFT_FOG_EXP2 EFT_FOG_EXP2
}; };
} // irr::video } // end namespace video

View file

@ -6,15 +6,13 @@
#include "IMesh.h" #include "IMesh.h"
namespace irr
{
namespace scene namespace scene
{ {
//! Interface for an animated mesh. //! Interface for an animated mesh.
/** There are already simple implementations of this interface available so /** There are already simple implementations of this interface available so
you don't have to implement this interface on your own if you need to: you don't have to implement this interface on your own if you need to:
You might want to use irr::scene::SAnimatedMesh, irr::scene::SMesh, You might want to use scene::SMesh, scene::SMeshBuffer etc.
irr::scene::SMeshBuffer etc. */ */
class IAnimatedMesh : public IMesh class IAnimatedMesh : public IMesh
{ {
public: public:
@ -34,23 +32,8 @@ public:
scene node the mesh is instantiated in.*/ scene node the mesh is instantiated in.*/
virtual void setAnimationSpeed(f32 fps) = 0; virtual void setAnimationSpeed(f32 fps) = 0;
//! Returns the IMesh interface for a frame. //! Returns the type of the animated mesh. Useful for safe downcasts.
/** \param frame: Frame number, >= 0, <= getMaxFrameNumber() E_ANIMATED_MESH_TYPE getMeshType() const = 0;
Linear interpolation is used if this is between two frames.
\return Returns the animated mesh for the given frame */
virtual IMesh *getMesh(f32 frame) = 0;
//! Returns the type of the animated mesh.
/** In most cases it is not necessary to use this method.
This is useful for making a safe downcast. For example,
if getMeshType() returns EAMT_MD2 it's safe to cast the
IAnimatedMesh to IAnimatedMeshMD2.
\returns Type of the mesh. */
E_ANIMATED_MESH_TYPE getMeshType() const override
{
return EAMT_UNKNOWN;
}
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -8,39 +8,10 @@
#include "IBoneSceneNode.h" #include "IBoneSceneNode.h"
#include "IAnimatedMesh.h" #include "IAnimatedMesh.h"
namespace irr
{
namespace scene namespace scene
{ {
enum E_JOINT_UPDATE_ON_RENDER
{
//! do nothing
EJUOR_NONE = 0,
//! get joints positions from the mesh (for attached nodes, etc)
EJUOR_READ,
//! control joint positions in the mesh (eg. ragdolls, or set the animation from animateJoints() )
EJUOR_CONTROL
};
class IAnimatedMeshSceneNode; class IAnimatedMeshSceneNode;
//! Callback interface for catching events of ended animations.
/** Implement this interface and use
IAnimatedMeshSceneNode::setAnimationEndCallback to be able to
be notified if an animation playback has ended.
**/
class IAnimationEndCallBack : public virtual IReferenceCounted
{
public:
//! Will be called when the animation playback has ended.
/** See IAnimatedMeshSceneNode::setAnimationEndCallback for
more information.
\param node: Node of which the animation has ended. */
virtual void OnAnimationEnd(IAnimatedMeshSceneNode *node) = 0;
};
//! Scene node capable of displaying an animated mesh. //! Scene node capable of displaying an animated mesh.
class IAnimatedMeshSceneNode : public ISceneNode class IAnimatedMeshSceneNode : public ISceneNode
{ {
@ -120,11 +91,10 @@ public:
/** When true the animations are played looped */ /** When true the animations are played looped */
virtual bool getLoopMode() const = 0; virtual bool getLoopMode() const = 0;
//! Sets a callback interface which will be called if an animation playback has ended. //! Will be called right after the joints have been animated,
/** Set this to 0 to disable the callback again. //! but before the transforms have been propagated recursively to children.
Please note that this will only be called when in non looped virtual void setOnAnimateCallback(
mode, see IAnimatedMeshSceneNode::setLoopMode(). */ const std::function<void(f32 dtime)> &cb) = 0;
virtual void setAnimationEndCallback(IAnimationEndCallBack *callback = 0) = 0;
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
/** In this way it is possible to change the materials a mesh /** In this way it is possible to change the materials a mesh
@ -139,20 +109,15 @@ public:
virtual void setMesh(IAnimatedMesh *mesh) = 0; virtual void setMesh(IAnimatedMesh *mesh) = 0;
//! Returns the current mesh //! Returns the current mesh
virtual IAnimatedMesh *getMesh(void) = 0; virtual IAnimatedMesh *getMesh() = 0;
//! Set how the joints should be updated on render
virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode) = 0;
//! Sets the transition time in seconds //! Sets the transition time in seconds
/** Note: This needs to enable joints, and setJointmode set to /** Note: You must call animateJoints(), or the mesh will not animate. */
EJUOR_CONTROL. You must call animateJoints(), or the mesh will
not animate. */
virtual void setTransitionTime(f32 Time) = 0; virtual void setTransitionTime(f32 Time) = 0;
//! animates the joints in the mesh based on the current frame. //! animates the joints in the mesh based on the current frame.
/** Also takes in to account transitions. */ /** Also takes in to account transitions. */
virtual void animateJoints(bool CalculateAbsolutePositions = true) = 0; virtual void animateJoints() = 0;
//! render mesh ignoring its transformation. //! render mesh ignoring its transformation.
/** Culling is unaffected. */ /** Culling is unaffected. */
@ -166,4 +131,3 @@ public:
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "ISceneNode.h" #include "ISceneNode.h"
namespace irr
{
namespace scene namespace scene
{ {
class ICameraSceneNode; class ICameraSceneNode;
@ -72,7 +70,7 @@ public:
So we don't know the real boundingboxes before that. Which would be too late for culling. So we don't know the real boundingboxes before that. Which would be too late for culling.
That is why the usual getBoundingBox will return a "safe" boundingbox which is guaranteed That is why the usual getBoundingBox will return a "safe" boundingbox which is guaranteed
to contain the billboard. While this function can return the real one. */ to contain the billboard. While this function can return the real one. */
virtual const core::aabbox3d<f32> &getTransformedBillboardBoundingBox(const irr::scene::ICameraSceneNode *camera) = 0; virtual const core::aabbox3d<f32> &getTransformedBillboardBoundingBox(const scene::ICameraSceneNode *camera) = 0;
//! Get the amount of mesh buffers. //! Get the amount of mesh buffers.
/** \return Amount of mesh buffers (IMeshBuffer) in this mesh. */ /** \return Amount of mesh buffers (IMeshBuffer) in this mesh. */
@ -87,4 +85,3 @@ public:
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -6,91 +6,44 @@
#include "ISceneNode.h" #include "ISceneNode.h"
namespace irr
{
namespace scene namespace scene
{ {
//! Enumeration for different bone animation modes
enum E_BONE_ANIMATION_MODE
{
//! The bone is usually animated, unless it's parent is not animated
EBAM_AUTOMATIC = 0,
//! The bone is animated by the skin, if it's parent is not animated then animation will resume from this bone onward
EBAM_ANIMATED,
//! The bone is not animated by the skin
EBAM_UNANIMATED,
//! Not an animation mode, just here to count the available modes
EBAM_COUNT
};
enum E_BONE_SKINNING_SPACE
{
//! local skinning, standard
EBSS_LOCAL = 0,
//! global skinning
EBSS_GLOBAL,
EBSS_COUNT
};
//! Names for bone animation modes
const c8 *const BoneAnimationModeNames[] = {
"automatic",
"animated",
"unanimated",
0,
};
//! Interface for bones used for skeletal animation. //! Interface for bones used for skeletal animation.
/** Used with SkinnedMesh and IAnimatedMeshSceneNode. */ /** Used with SkinnedMesh and IAnimatedMeshSceneNode. */
class IBoneSceneNode : public ISceneNode class IBoneSceneNode : public ISceneNode
{ {
public: public:
IBoneSceneNode(ISceneNode *parent, ISceneManager *mgr, s32 id = -1) : IBoneSceneNode(ISceneNode *parent, ISceneManager *mgr,
ISceneNode(parent, mgr, id), positionHint(-1), scaleHint(-1), rotationHint(-1) {} s32 id = -1, u32 boneIndex = 0,
const std::optional<std::string> &boneName = std::nullopt)
:
ISceneNode(parent, mgr, id),
BoneIndex(boneIndex)
{
setName(boneName);
}
//! Get the index of the bone //! Returns the index of the bone
virtual u32 getBoneIndex() const = 0; u32 getBoneIndex() const
{
return BoneIndex;
}
//! Sets the animation mode of the bone. //! returns the axis aligned bounding box of this node
/** \return True if successful. (Unused) */ const core::aabbox3d<f32> &getBoundingBox() const override
virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode) = 0; {
return Box;
}
//! Gets the current animation mode of the bone const u32 BoneIndex;
virtual E_BONE_ANIMATION_MODE getAnimationMode() const = 0;
//! Get the axis aligned bounding box of this node // Bogus box; bone scene nodes are not rendered anyways.
const core::aabbox3d<f32> &getBoundingBox() const override = 0; static constexpr core::aabbox3d<f32> Box = {{0, 0, 0}};
//! Returns the relative transformation of the scene node.
// virtual core::matrix4 getRelativeTransformation() const = 0;
//! The animation method.
void OnAnimate(u32 timeMs) override = 0;
//! The render method. //! The render method.
/** Does nothing as bones are not visible. */ /** Does nothing as bones are not visible. */
void render() override {} void render() override {}
//! How the relative transformation of the bone is used
virtual void setSkinningSpace(E_BONE_SKINNING_SPACE space) = 0;
//! How the relative transformation of the bone is used
virtual E_BONE_SKINNING_SPACE getSkinningSpace() const = 0;
//! Updates the absolute position based on the relative and the parents position
virtual void updateAbsolutePositionOfAllChildren() = 0;
s32 positionHint;
s32 scaleHint;
s32 rotationHint;
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "ISceneNode.h" #include "ISceneNode.h"
#include "IEventReceiver.h" #include "IEventReceiver.h"
namespace irr
{
namespace scene namespace scene
{ {
struct SViewFrustum; struct SViewFrustum;
@ -181,4 +179,3 @@ protected:
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -8,8 +8,6 @@
#include "SIrrCreationParameters.h" #include "SIrrCreationParameters.h"
#include <string> #include <string>
namespace irr
{
namespace video namespace video
{ {
// For system specific window contexts (used for OpenGL) // For system specific window contexts (used for OpenGL)
@ -43,7 +41,7 @@ public:
/** This is mostly used internally by IVideoDriver::beginScene(). /** This is mostly used internally by IVideoDriver::beginScene().
But if you want to switch threads which access your OpenGL driver you will have to But if you want to switch threads which access your OpenGL driver you will have to
call this function as follows: call this function as follows:
Old thread gives up context with: activateContext(irr::video::SExposedVideoData()); Old thread gives up context with: activateContext(video::SExposedVideoData());
New thread takes over context with: activateContext(videoDriver->getExposedVideoData()); New thread takes over context with: activateContext(videoDriver->getExposedVideoData());
Note that only 1 thread at a time may access an OpenGL context. */ Note that only 1 thread at a time may access an OpenGL context. */
virtual bool activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero = false) = 0; virtual bool activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero = false) = 0;
@ -56,4 +54,3 @@ public:
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -8,8 +8,6 @@
#include "position2d.h" #include "position2d.h"
#include "rect.h" #include "rect.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -192,4 +190,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "ISceneNode.h" #include "ISceneNode.h"
namespace irr
{
namespace scene namespace scene
{ {
@ -33,4 +31,3 @@ public:
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr

View file

@ -8,8 +8,6 @@
#include "Keycodes.h" #include "Keycodes.h"
#include "irrString.h" #include "irrString.h"
namespace irr
{
//! Enumeration for all event types there are. //! Enumeration for all event types there are.
enum EEVENT_TYPE enum EEVENT_TYPE
{ {
@ -297,7 +295,7 @@ enum EGUI_EVENT_TYPE
}; };
} // end namespace gui } // end namespace gui
//! SEvents hold information about an event. See irr::IEventReceiver for details on event handling. //! SEvents hold information about an event. See IEventReceiver for details on event handling.
struct SEvent struct SEvent
{ {
//! Any kind of GUI event. //! Any kind of GUI event.
@ -444,7 +442,7 @@ struct SEvent
/** Unlike other events, joystick events represent the result of polling /** Unlike other events, joystick events represent the result of polling
* each connected joystick once per run() of the device. Joystick events will * each connected joystick once per run() of the device. Joystick events will
* not be generated by default. If joystick support is available for the * not be generated by default. If joystick support is available for the
* active device, and @ref irr::IrrlichtDevice::activateJoysticks() has been * active device, and @ref IrrlichtDevice::activateJoysticks() has been
* called, an event of this type will be generated once per joystick per * called, an event of this type will be generated once per joystick per
* @ref IrrlichtDevice::run() regardless of whether the state of the joystick * @ref IrrlichtDevice::run() regardless of whether the state of the joystick
* has actually changed. */ * has actually changed. */
@ -553,7 +551,7 @@ struct SEvent
/** Many of the engine's classes inherit IEventReceiver so they are able to /** Many of the engine's classes inherit IEventReceiver so they are able to
process events. Events usually start at a postEventFromUser function and are process events. Events usually start at a postEventFromUser function and are
passed down through a chain of event receivers until OnEvent returns true. See passed down through a chain of event receivers until OnEvent returns true. See
irr::EEVENT_TYPE for a description of where each type of event starts, and the EEVENT_TYPE for a description of where each type of event starts, and the
path it takes through the system. */ path it takes through the system. */
class IEventReceiver class IEventReceiver
{ {
@ -570,13 +568,13 @@ public:
virtual bool OnEvent(const SEvent &event) = 0; virtual bool OnEvent(const SEvent &event) = 0;
}; };
//! Information on a joystick, returned from @ref irr::IrrlichtDevice::activateJoysticks() //! Information on a joystick, returned from @ref IrrlichtDevice::activateJoysticks()
struct SJoystickInfo struct SJoystickInfo
{ {
//! The ID of the joystick //! The ID of the joystick
/** This is an internal Irrlicht index; it does not map directly /** This is an internal Irrlicht index; it does not map directly
* to any particular hardware joystick. It corresponds to the * to any particular hardware joystick. It corresponds to the
* irr::SJoystickEvent Joystick ID. */ * SJoystickEvent Joystick ID. */
u8 Joystick; u8 Joystick;
//! The name that the joystick uses to identify itself. //! The name that the joystick uses to identify itself.
@ -605,5 +603,3 @@ struct SJoystickInfo
POV_HAT_UNKNOWN POV_HAT_UNKNOWN
} PovHat; } PovHat;
}; // struct SJoystickInfo }; // struct SJoystickInfo
} // end namespace irr

View file

@ -7,9 +7,6 @@
#include "IReadFile.h" #include "IReadFile.h"
#include "IFileList.h" #include "IFileList.h"
namespace irr
{
namespace io namespace io
{ {
@ -111,4 +108,3 @@ public:
}; };
} // end namespace io } // end namespace io
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IReferenceCounted.h" #include "IReferenceCounted.h"
#include "path.h" #include "path.h"
namespace irr
{
namespace io namespace io
{ {
@ -85,5 +83,4 @@ public:
virtual void sort() = 0; virtual void sort() = 0;
}; };
} // end namespace irr
} // end namespace io } // end namespace io

View file

@ -7,12 +7,6 @@
#include "IReferenceCounted.h" #include "IReferenceCounted.h"
#include "IFileArchive.h" #include "IFileArchive.h"
namespace irr
{
namespace video
{
class IVideoDriver;
} // end namespace video
namespace io namespace io
{ {
@ -154,4 +148,3 @@ public:
}; };
} // end namespace io } // end namespace io
} // end namespace irr

View file

@ -8,18 +8,9 @@
#include "EPrimitiveTypes.h" #include "EPrimitiveTypes.h"
#include "path.h" #include "path.h"
namespace irr
{
namespace io
{
class IReadFile;
} // end namespace io
namespace video namespace video
{ {
class IVideoDriver;
class IShaderConstantSetCallBack; class IShaderConstantSetCallBack;
//! Interface making it possible to create and use programs running on the GPU. //! Interface making it possible to create and use programs running on the GPU.
@ -141,4 +132,3 @@ public:
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -7,9 +7,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
#include "SColor.h" #include "SColor.h"
namespace irr
{
namespace video namespace video
{ {
class ITexture; class ITexture;
@ -254,4 +251,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -44,4 +42,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -69,4 +67,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
#include "SColor.h" #include "SColor.h"
namespace irr
{
namespace gui namespace gui
{ {
class IGUIFont; class IGUIFont;
@ -141,11 +139,10 @@ public:
//! Set the blinktime for the cursor. 2x blinktime is one full cycle. //! Set the blinktime for the cursor. 2x blinktime is one full cycle.
//** \param timeMs Blinktime in milliseconds. When set to 0 the cursor is constantly on without blinking */ //** \param timeMs Blinktime in milliseconds. When set to 0 the cursor is constantly on without blinking */
virtual void setCursorBlinkTime(irr::u32 timeMs) = 0; virtual void setCursorBlinkTime(u32 timeMs) = 0;
//! Get the cursor blinktime //! Get the cursor blinktime
virtual irr::u32 getCursorBlinkTime() const = 0; virtual u32 getCursorBlinkTime() const = 0;
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -14,8 +14,6 @@
#include <list> #include <list>
#include <vector> #include <vector>
namespace irr
{
namespace gui namespace gui
{ {
class IGUIEnvironment; class IGUIEnvironment;
@ -926,4 +924,3 @@ protected:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -11,15 +11,11 @@
#include "IEventReceiver.h" #include "IEventReceiver.h"
#include "path.h" #include "path.h"
namespace irr
{
class IOSOperator; class IOSOperator;
class IEventReceiver; class IEventReceiver;
namespace io namespace io
{ {
class IReadFile;
class IWriteFile;
class IFileSystem; class IFileSystem;
} // end namespace io } // end namespace io
namespace video namespace video
@ -46,7 +42,6 @@ class IGUITabControl;
class IGUITab; class IGUITab;
class IGUIComboBox; class IGUIComboBox;
class IGUIButton; class IGUIButton;
class IGUIWindow;
//! GUI Environment. Used as factory and manager of all other GUI elements. //! GUI Environment. Used as factory and manager of all other GUI elements.
/** \par This element can create the following events of type EGUI_EVENT_TYPE (which are passed on to focused sub-elements): /** \par This element can create the following events of type EGUI_EVENT_TYPE (which are passed on to focused sub-elements):
@ -403,4 +398,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
#include "path.h" #include "path.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -41,4 +39,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -9,8 +9,6 @@
#include "rect.h" #include "rect.h"
#include "irrString.h" #include "irrString.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -93,4 +91,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "IGUIFont.h" #include "IGUIFont.h"
namespace irr
{
namespace gui namespace gui
{ {
class IGUISpriteBank; class IGUISpriteBank;
@ -27,4 +25,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
#include "SColor.h" #include "SColor.h"
namespace irr
{
namespace video namespace video
{ {
class ITexture; class ITexture;
@ -80,4 +78,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "rect.h" #include "rect.h"
#include "irrTypes.h" #include "irrTypes.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -37,4 +35,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
#include "SColor.h" #include "SColor.h"
namespace irr
{
namespace gui namespace gui
{ {
class IGUISpriteBank; class IGUISpriteBank;
@ -133,4 +131,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
namespace irr
{
namespace gui namespace gui
{ {
@ -56,4 +54,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -9,8 +9,6 @@
#include "SColor.h" #include "SColor.h"
#include "rect.h" #include "rect.h"
namespace irr
{
namespace gui namespace gui
{ {
class IGUIFont; class IGUIFont;
@ -537,4 +535,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -9,9 +9,6 @@
#include "SColor.h" #include "SColor.h"
#include "rect.h" #include "rect.h"
namespace irr
{
namespace video namespace video
{ {
class ITexture; class ITexture;
@ -135,4 +132,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
#include "SColor.h" #include "SColor.h"
namespace irr
{
namespace gui namespace gui
{ {
class IGUIFont; class IGUIFont;
@ -130,4 +128,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
#include "SColor.h" #include "SColor.h"
namespace irr
{
namespace gui namespace gui
{ {
class IGUITab; class IGUITab;
@ -145,4 +143,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -6,8 +6,6 @@
#include "IGUIElement.h" #include "IGUIElement.h"
namespace irr
{
namespace video namespace video
{ {
class ITexture; class ITexture;
@ -31,4 +29,3 @@ public:
}; };
} // end namespace gui } // end namespace gui
} // end namespace irr

View file

@ -10,8 +10,6 @@
#include "SColor.h" #include "SColor.h"
#include <cstring> #include <cstring>
namespace irr
{
namespace video namespace video
{ {
@ -208,14 +206,6 @@ public:
//! copies this surface into another //! copies this surface into another
virtual void copyTo(IImage *target, const core::position2d<s32> &pos, const core::rect<s32> &sourceRect, const core::rect<s32> *clipRect = 0) = 0; virtual void copyTo(IImage *target, const core::position2d<s32> &pos, const core::rect<s32> &sourceRect, const core::rect<s32> *clipRect = 0) = 0;
//! copies this surface into another, using the alpha mask and cliprect and a color to add with
/** \param combineAlpha - When true then combine alpha channels. When false replace target image alpha with source image alpha.
*/
virtual void copyToWithAlpha(IImage *target, const core::position2d<s32> &pos,
const core::rect<s32> &sourceRect, const SColor &color,
const core::rect<s32> *clipRect = 0,
bool combineAlpha = false) = 0;
//! copies this surface into another, scaling it to fit, applying a box filter //! copies this surface into another, scaling it to fit, applying a box filter
virtual void copyToScalingBoxFilter(IImage *target, s32 bias = 0, bool blend = false) = 0; virtual void copyToScalingBoxFilter(IImage *target, s32 bias = 0, bool blend = false) = 0;
@ -332,4 +322,3 @@ protected:
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -8,8 +8,6 @@
#include "IImage.h" #include "IImage.h"
#include "path.h" #include "path.h"
namespace irr
{
namespace io namespace io
{ {
class IReadFile; class IReadFile;
@ -44,4 +42,3 @@ public:
}; };
} // end namespace video } // end namespace video
} // end namespace irr

View file

@ -7,8 +7,6 @@
#include "IReferenceCounted.h" #include "IReferenceCounted.h"
#include "path.h" #include "path.h"
namespace irr
{
namespace io namespace io
{ {
class IWriteFile; class IWriteFile;
@ -36,4 +34,3 @@ public:
}; };
} // namespace video } // namespace video
} // namespace irr

Some files were not shown because too many files have changed in this diff Show more