mirror of
https://github.com/minetest/minetest.git
synced 2025-03-06 20:48:40 +01:00
Compare commits
82 commits
5.11.0-rc1
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
7892541383 | ||
|
358658fa34 | ||
|
68602b2eaf | ||
|
e84ac56e35 | ||
|
47c000a293 | ||
|
304ce4cd54 | ||
|
d54646d342 | ||
|
7abaa8d4cd | ||
|
2796283550 | ||
|
7602308835 | ||
|
bc43019467 | ||
|
8449f5f6db | ||
|
0eb047ca33 | ||
|
98048cb06d | ||
|
6e995972bb | ||
|
08fad862aa | ||
|
c3477a4d08 | ||
|
062207e696 | ||
|
24c1230c7b | ||
|
eb79a76742 | ||
|
c0328e5363 | ||
|
8d822d8231 | ||
|
a11b25f3f5 | ||
|
90121dc66f | ||
|
d74af2f1a7 | ||
|
b6c71b2379 | ||
|
c261c26456 | ||
|
5abf220979 | ||
|
1ceeea34f4 | ||
|
3ae1fd459a | ||
|
0e86366324 | ||
|
58ad604a4b | ||
|
415e96184d | ||
|
8654e16725 | ||
|
eb8b449817 | ||
|
22c81e5292 | ||
|
42a35cec83 | ||
|
fc8c6742c4 | ||
|
ee9258cefd | ||
|
5e89371ecd | ||
|
abcd2e0b81 | ||
|
d12ce68e64 | ||
|
83fd837d75 | ||
|
7d3f0628c4 | ||
|
27bbe3a873 | ||
|
5a8720a484 | ||
|
e51221d247 | ||
|
0890125962 | ||
|
0667cbf5a2 | ||
|
ba62808fe8 | ||
|
50819ace8f | ||
|
ef0219c2ed | ||
|
f4bdf72aa4 | ||
|
cc352f3b66 | ||
|
215b000793 | ||
|
e8728acc5c | ||
|
166e02955e | ||
|
138111a542 | ||
|
191cb117f9 | ||
|
a57677120a | ||
|
75dcd94b90 | ||
|
d027fc9a88 | ||
|
a11d526110 | ||
|
eb797c502a | ||
|
567b9a997a | ||
|
319e270664 | ||
|
d015944f6c | ||
|
b7f01b0cc7 | ||
|
54bf5d62f2 | ||
|
849a583f66 | ||
|
0cb7735125 | ||
|
028949beca | ||
|
6bdeb10c16 | ||
|
44cbae8fad | ||
|
f7b2d4760f | ||
|
1ec19c2ad2 | ||
|
9bfd39f036 | ||
|
cfff6c4fd7 | ||
|
147dd3d372 | ||
|
cda3dc08ca | ||
|
78b4f929ce | ||
|
2c50066c16 |
202 changed files with 3119 additions and 15521 deletions
|
@ -1,4 +1,4 @@
|
||||||
Checks: '-*,modernize-use-emplace,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,performance-*'
|
Checks: '-*,modernize-use-emplace,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,performance-*,-performance-avoid-endl,performance-inefficient-string-concatenation'
|
||||||
WarningsAsErrors: '-*,modernize-use-emplace,performance-type-promotion-in-math-fn,performance-faster-string-find,performance-implicit-cast-in-loop'
|
WarningsAsErrors: '-*,modernize-use-emplace,performance-type-promotion-in-math-fn,performance-faster-string-find,performance-implicit-cast-in-loop'
|
||||||
CheckOptions:
|
CheckOptions:
|
||||||
- key: performance-unnecessary-value-param.AllowedTypes
|
- key: performance-unnecessary-value-param.AllowedTypes
|
||||||
|
|
2
.github/workflows/windows.yml
vendored
2
.github/workflows/windows.yml
vendored
|
@ -73,7 +73,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
VCPKG_VERSION: 01f602195983451bc83e72f4214af2cbc495aa94
|
VCPKG_VERSION: 01f602195983451bc83e72f4214af2cbc495aa94
|
||||||
# 2024.05.24
|
# 2024.05.24
|
||||||
vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp opengl-registry
|
vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp sdl2
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
|
|
@ -11,7 +11,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 11)
|
set(VERSION_MINOR 12)
|
||||||
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")
|
||||||
|
|
||||||
|
|
16
README.md
16
README.md
|
@ -1,13 +1,15 @@
|
||||||
Luanti (formerly Minetest)
|
<div align="center">
|
||||||
==========================
|
<img src="textures/base/pack/logo.png" width="32%">
|
||||||
|
<h1>Luanti (formerly Minetest)</h1>
|
||||||

|
<img src="https://github.com/luanti-org/luanti/workflows/build/badge.svg" alt="Build Status">
|
||||||
[](https://hosted.weblate.org/engage/minetest/?utm_source=widget)
|
<a href="https://hosted.weblate.org/engage/minetest/?utm_source=widget"><img src="https://hosted.weblate.org/widgets/minetest/-/svg-badge.svg" alt="Translation status"></a>
|
||||||
[](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html)
|
<a href="https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html"><img src="https://img.shields.io/badge/license-LGPLv2.1%2B-blue.svg" alt="License"></a>
|
||||||
|
</div>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
Luanti is a free open-source voxel game engine with easy modding and game creation.
|
Luanti is a free open-source voxel game engine with easy modding and game creation.
|
||||||
|
|
||||||
Copyright (C) 2010-2024 Perttu Ahola <celeron55@gmail.com>
|
Copyright (C) 2010-2025 Perttu Ahola <celeron55@gmail.com>
|
||||||
and contributors (see source file comments and the version control log)
|
and contributors (see source file comments and the version control log)
|
||||||
|
|
||||||
Table of Contents
|
Table of Contents
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
diff --git a/android/app/src/main/java/org/libsdl/app/SDLActivity.java b/android/app/src/main/java/org/libsdl/app/SDLActivity.java
|
diff --git a/android/app/src/main/java/org/libsdl/app/SDLActivity.java b/android/app/src/main/java/org/libsdl/app/SDLActivity.java
|
||||||
index fd5a056e3..83e3cf657 100644
|
|
||||||
--- a/android/app/src/main/java/org/libsdl/app/SDLActivity.java
|
--- a/android/app/src/main/java/org/libsdl/app/SDLActivity.java
|
||||||
+++ b/android/app/src/main/java/org/libsdl/app/SDLActivity.java
|
+++ b/android/app/src/main/java/org/libsdl/app/SDLActivity.java
|
||||||
@@ -1345,7 +1345,12 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
@@ -1345,7 +1345,12 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||||
|
@ -9,7 +8,7 @@ index fd5a056e3..83e3cf657 100644
|
||||||
- if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
|
- if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
|
||||||
+ if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE ||
|
+ if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE ||
|
||||||
+ /*
|
+ /*
|
||||||
+ * CUSTOM ADDITION FOR MINETEST
|
+ * CUSTOM ADDITION FOR LUANTI
|
||||||
+ * should be upstreamed
|
+ * should be upstreamed
|
||||||
+ */
|
+ */
|
||||||
+ (source & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE) {
|
+ (source & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE) {
|
||||||
|
|
|
@ -60,8 +60,8 @@ import java.util.Locale;
|
||||||
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
|
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
|
||||||
private static final String TAG = "SDL";
|
private static final String TAG = "SDL";
|
||||||
private static final int SDL_MAJOR_VERSION = 2;
|
private static final int SDL_MAJOR_VERSION = 2;
|
||||||
private static final int SDL_MINOR_VERSION = 30;
|
private static final int SDL_MINOR_VERSION = 32;
|
||||||
private static final int SDL_MICRO_VERSION = 8;
|
private static final int SDL_MICRO_VERSION = 0;
|
||||||
/*
|
/*
|
||||||
// Display InputType.SOURCE/CLASS of events and devices
|
// Display InputType.SOURCE/CLASS of events and devices
|
||||||
//
|
//
|
||||||
|
@ -790,6 +790,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
SDLActivity.mFullscreenModeActive = false;
|
SDLActivity.mFullscreenModeActive = false;
|
||||||
}
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
|
||||||
|
window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "error handling message, getContext() returned no Activity");
|
Log.e(TAG, "error handling message, getContext() returned no Activity");
|
||||||
|
@ -1347,7 +1350,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||||
|
|
||||||
if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE ||
|
if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE ||
|
||||||
/*
|
/*
|
||||||
* CUSTOM ADDITION FOR MINETEST
|
* CUSTOM ADDITION FOR LUANTI
|
||||||
* should be upstreamed
|
* should be upstreamed
|
||||||
*/
|
*/
|
||||||
(source & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE) {
|
(source & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE) {
|
||||||
|
|
11
android/app/src/main/res/values-fr/strings.xml
Normal file
11
android/app/src/main/res/values-fr/strings.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="label">Luanti</string>
|
||||||
|
<string name="loading">Chargement…</string>
|
||||||
|
<string name="notification_channel_name">Notification générale</string>
|
||||||
|
<string name="notification_channel_description">Notifications de Luanti</string>
|
||||||
|
<string name="unzip_notification_title">Chargement de Luanti</string>
|
||||||
|
<string name="unzip_notification_description">Moins d\'une minute…</string>
|
||||||
|
<string name="ime_dialog_done">Terminé</string>
|
||||||
|
<string name="no_web_browser">Aucun navigateur web trouvé</string>
|
||||||
|
</resources>
|
11
android/app/src/main/res/values-gl/strings.xml
Normal file
11
android/app/src/main/res/values-gl/strings.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="label">Luanti</string>
|
||||||
|
<string name="loading">Cargando…</string>
|
||||||
|
<string name="notification_channel_name">Notificación xeral</string>
|
||||||
|
<string name="notification_channel_description">Notificacións de Luanti</string>
|
||||||
|
<string name="unzip_notification_title">Cargando Luanti</string>
|
||||||
|
<string name="unzip_notification_description">Menos de 1 minuto…</string>
|
||||||
|
<string name="ime_dialog_done">Feito</string>
|
||||||
|
<string name="no_web_browser">Non se atopou ningún navegador web</string>
|
||||||
|
</resources>
|
|
@ -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", 11) // Version Minor
|
project.ext.set("versionMinor", 12) // 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
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ local facedir_to_dir_map = {
|
||||||
1, 4, 3, 2,
|
1, 4, 3, 2,
|
||||||
}
|
}
|
||||||
function core.facedir_to_dir(facedir)
|
function core.facedir_to_dir(facedir)
|
||||||
return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
|
return vector.copy(facedir_to_dir[facedir_to_dir_map[facedir % 32]])
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.dir_to_fourdir(dir)
|
function core.dir_to_fourdir(dir)
|
||||||
|
@ -110,7 +110,7 @@ function core.dir_to_fourdir(dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.fourdir_to_dir(fourdir)
|
function core.fourdir_to_dir(fourdir)
|
||||||
return facedir_to_dir[facedir_to_dir_map[fourdir % 4]]
|
return vector.copy(facedir_to_dir[facedir_to_dir_map[fourdir % 4]])
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.dir_to_wallmounted(dir)
|
function core.dir_to_wallmounted(dir)
|
||||||
|
@ -147,7 +147,7 @@ local wallmounted_to_dir = {
|
||||||
vector.new( 0, -1, 0),
|
vector.new( 0, -1, 0),
|
||||||
}
|
}
|
||||||
function core.wallmounted_to_dir(wallmounted)
|
function core.wallmounted_to_dir(wallmounted)
|
||||||
return wallmounted_to_dir[wallmounted % 8]
|
return vector.copy(wallmounted_to_dir[wallmounted % 8])
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.dir_to_yaw(dir)
|
function core.dir_to_yaw(dir)
|
||||||
|
|
|
@ -159,7 +159,6 @@ local function load()
|
||||||
{ heading = fgettext_ne("Movement") },
|
{ heading = fgettext_ne("Movement") },
|
||||||
"arm_inertia",
|
"arm_inertia",
|
||||||
"view_bobbing_amount",
|
"view_bobbing_amount",
|
||||||
"fall_bobbing_amount",
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -517,7 +516,7 @@ local function get_formspec(dialogdata)
|
||||||
|
|
||||||
("button[0,%f;%f,0.8;back;%s]"):format(
|
("button[0,%f;%f,0.8;back;%s]"):format(
|
||||||
tabsize.height + 0.2, back_w,
|
tabsize.height + 0.2, back_w,
|
||||||
fgettext(INIT == "pause_menu" and "Exit" or "Back")),
|
INIT == "pause_menu" and fgettext("Exit") or fgettext("Back")),
|
||||||
|
|
||||||
("box[%f,%f;%f,0.8;#0000008C]"):format(
|
("box[%f,%f;%f,0.8;#0000008C]"):format(
|
||||||
back_w + 0.2, tabsize.height + 0.2, checkbox_w),
|
back_w + 0.2, tabsize.height + 0.2, checkbox_w),
|
||||||
|
|
|
@ -61,7 +61,7 @@ local function create_minetest_conf_example(settings)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if entry.type == "key" then
|
if entry.type == "key" then
|
||||||
local line = "See https://github.com/minetest/irrlicht/blob/master/include/Keycodes.h"
|
local line = "See https://github.com/luanti-org/luanti/blob/master/irr/include/Keycodes.h"
|
||||||
insert(result, "# " .. line .. "\n")
|
insert(result, "# " .. line .. "\n")
|
||||||
end
|
end
|
||||||
insert(result, "# type: " .. entry.type)
|
insert(result, "# type: " .. entry.type)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
local builtin_shared = ...
|
local builtin_shared = ...
|
||||||
local SCALE = 0.667
|
|
||||||
|
|
||||||
local facedir_to_euler = {
|
local facedir_to_euler = {
|
||||||
{y = 0, x = 0, z = 0},
|
{y = 0, x = 0, z = 0},
|
||||||
|
@ -36,9 +35,7 @@ local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
|
||||||
|
|
||||||
core.register_entity(":__builtin:falling_node", {
|
core.register_entity(":__builtin:falling_node", {
|
||||||
initial_properties = {
|
initial_properties = {
|
||||||
visual = "item",
|
visual = "node",
|
||||||
visual_size = vector.new(SCALE, SCALE, SCALE),
|
|
||||||
textures = {},
|
|
||||||
physical = true,
|
physical = true,
|
||||||
is_visible = false,
|
is_visible = false,
|
||||||
collide_with_objects = true,
|
collide_with_objects = true,
|
||||||
|
@ -80,41 +77,15 @@ core.register_entity(":__builtin:falling_node", {
|
||||||
-- Save liquidtype for falling water
|
-- Save liquidtype for falling water
|
||||||
self.liquidtype = def.liquidtype
|
self.liquidtype = def.liquidtype
|
||||||
|
|
||||||
-- Set entity visuals
|
-- Set up entity visuals
|
||||||
if def.drawtype == "torchlike" or def.drawtype == "signlike" then
|
-- For compatibility with older clients we continue to use "item" visual
|
||||||
local textures
|
-- for simple situations.
|
||||||
if def.tiles and def.tiles[1] then
|
local drawtypes = {normal=true, glasslike=true, allfaces=true, nodebox=true}
|
||||||
local tile = def.tiles[1]
|
local p2types = {none=true, facedir=true, ["4dir"]=true}
|
||||||
if type(tile) == "table" then
|
if drawtypes[def.drawtype] and p2types[def.paramtype2] and def.use_texture_alpha ~= "blend" then
|
||||||
tile = tile.name
|
|
||||||
end
|
|
||||||
if def.drawtype == "torchlike" then
|
|
||||||
textures = { "("..tile..")^[transformFX", tile }
|
|
||||||
else
|
|
||||||
textures = { tile, "("..tile..")^[transformFX" }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local vsize
|
|
||||||
if def.visual_scale then
|
|
||||||
local s = def.visual_scale
|
|
||||||
vsize = vector.new(s, s, s)
|
|
||||||
end
|
|
||||||
self.object:set_properties({
|
|
||||||
is_visible = true,
|
|
||||||
visual = "upright_sprite",
|
|
||||||
visual_size = vsize,
|
|
||||||
textures = textures,
|
|
||||||
glow = def.light_source,
|
|
||||||
})
|
|
||||||
elseif def.drawtype ~= "airlike" then
|
|
||||||
local itemstring = node.name
|
|
||||||
if core.is_colored_paramtype(def.paramtype2) then
|
|
||||||
itemstring = core.itemstring_with_palette(itemstring, node.param2)
|
|
||||||
end
|
|
||||||
-- FIXME: solution needed for paramtype2 == "leveled"
|
|
||||||
-- Calculate size of falling node
|
-- Calculate size of falling node
|
||||||
local s = {}
|
local s = vector.zero()
|
||||||
s.x = (def.visual_scale or 1) * SCALE
|
s.x = (def.visual_scale or 1) * 0.667
|
||||||
s.y = s.x
|
s.y = s.x
|
||||||
s.z = s.x
|
s.z = s.x
|
||||||
-- Compensate for wield_scale
|
-- Compensate for wield_scale
|
||||||
|
@ -125,10 +96,31 @@ core.register_entity(":__builtin:falling_node", {
|
||||||
end
|
end
|
||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
is_visible = true,
|
is_visible = true,
|
||||||
wield_item = itemstring,
|
visual = "item",
|
||||||
|
wield_item = node.name,
|
||||||
visual_size = s,
|
visual_size = s,
|
||||||
glow = def.light_source,
|
glow = def.light_source,
|
||||||
})
|
})
|
||||||
|
-- Rotate as needed
|
||||||
|
if def.paramtype2 == "facedir" then
|
||||||
|
local fdir = node.param2 % 32 % 24
|
||||||
|
local euler = facedir_to_euler[fdir + 1]
|
||||||
|
if euler then
|
||||||
|
self.object:set_rotation(euler)
|
||||||
|
end
|
||||||
|
elseif def.paramtype2 == "4dir" then
|
||||||
|
local fdir = node.param2 % 4
|
||||||
|
local euler = facedir_to_euler[fdir + 1]
|
||||||
|
if euler then
|
||||||
|
self.object:set_rotation(euler)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif def.drawtype ~= "airlike" then
|
||||||
|
self.object:set_properties({
|
||||||
|
is_visible = true,
|
||||||
|
node = node,
|
||||||
|
glow = def.light_source,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set collision box (certain nodeboxes only for now)
|
-- Set collision box (certain nodeboxes only for now)
|
||||||
|
@ -148,111 +140,6 @@ core.register_entity(":__builtin:falling_node", {
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Rotate entity
|
|
||||||
if def.drawtype == "torchlike" then
|
|
||||||
if (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted")
|
|
||||||
and node.param2 % 8 == 7 then
|
|
||||||
self.object:set_yaw(-math.pi*0.25)
|
|
||||||
else
|
|
||||||
self.object:set_yaw(math.pi*0.25)
|
|
||||||
end
|
|
||||||
elseif ((node.param2 ~= 0 or def.drawtype == "nodebox" or def.drawtype == "mesh")
|
|
||||||
and (def.wield_image == "" or def.wield_image == nil))
|
|
||||||
or def.drawtype == "signlike"
|
|
||||||
or def.drawtype == "mesh"
|
|
||||||
or def.drawtype == "normal"
|
|
||||||
or def.drawtype == "nodebox" then
|
|
||||||
if (def.paramtype2 == "facedir" or def.paramtype2 == "colorfacedir") then
|
|
||||||
local fdir = node.param2 % 32 % 24
|
|
||||||
-- Get rotation from a precalculated lookup table
|
|
||||||
local euler = facedir_to_euler[fdir + 1]
|
|
||||||
if euler then
|
|
||||||
self.object:set_rotation(euler)
|
|
||||||
end
|
|
||||||
elseif (def.paramtype2 == "4dir" or def.paramtype2 == "color4dir") then
|
|
||||||
local fdir = node.param2 % 4
|
|
||||||
-- Get rotation from a precalculated lookup table
|
|
||||||
local euler = facedir_to_euler[fdir + 1]
|
|
||||||
if euler then
|
|
||||||
self.object:set_rotation(euler)
|
|
||||||
end
|
|
||||||
elseif (def.drawtype ~= "plantlike" and def.drawtype ~= "plantlike_rooted" and
|
|
||||||
(def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted" or def.drawtype == "signlike")) then
|
|
||||||
local rot = node.param2 % 8
|
|
||||||
if (def.drawtype == "signlike" and def.paramtype2 ~= "wallmounted" and def.paramtype2 ~= "colorwallmounted") then
|
|
||||||
-- Change rotation to "floor" by default for non-wallmounted paramtype2
|
|
||||||
rot = 1
|
|
||||||
end
|
|
||||||
local pitch, yaw, roll = 0, 0, 0
|
|
||||||
if def.drawtype == "nodebox" or def.drawtype == "mesh" then
|
|
||||||
if rot == 0 then
|
|
||||||
pitch, yaw = math.pi/2, 0
|
|
||||||
elseif rot == 1 then
|
|
||||||
pitch, yaw = -math.pi/2, math.pi
|
|
||||||
elseif rot == 2 then
|
|
||||||
pitch, yaw = 0, math.pi/2
|
|
||||||
elseif rot == 3 then
|
|
||||||
pitch, yaw = 0, -math.pi/2
|
|
||||||
elseif rot == 4 then
|
|
||||||
pitch, yaw = 0, math.pi
|
|
||||||
elseif rot == 6 then
|
|
||||||
pitch, yaw = math.pi/2, 0
|
|
||||||
elseif rot == 7 then
|
|
||||||
pitch, yaw = -math.pi/2, math.pi
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if rot == 1 then
|
|
||||||
pitch, yaw = math.pi, math.pi
|
|
||||||
elseif rot == 2 then
|
|
||||||
pitch, yaw = math.pi/2, math.pi/2
|
|
||||||
elseif rot == 3 then
|
|
||||||
pitch, yaw = math.pi/2, -math.pi/2
|
|
||||||
elseif rot == 4 then
|
|
||||||
pitch, yaw = math.pi/2, math.pi
|
|
||||||
elseif rot == 5 then
|
|
||||||
pitch, yaw = math.pi/2, 0
|
|
||||||
elseif rot == 6 then
|
|
||||||
pitch, yaw = math.pi, -math.pi/2
|
|
||||||
elseif rot == 7 then
|
|
||||||
pitch, yaw = 0, -math.pi/2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if def.drawtype == "signlike" then
|
|
||||||
pitch = pitch - math.pi/2
|
|
||||||
if rot == 0 then
|
|
||||||
yaw = yaw + math.pi/2
|
|
||||||
elseif rot == 1 then
|
|
||||||
yaw = yaw - math.pi/2
|
|
||||||
elseif rot == 6 then
|
|
||||||
yaw = yaw - math.pi/2
|
|
||||||
pitch = pitch + math.pi
|
|
||||||
elseif rot == 7 then
|
|
||||||
yaw = yaw + math.pi/2
|
|
||||||
pitch = pitch + math.pi
|
|
||||||
end
|
|
||||||
elseif def.drawtype == "mesh" or def.drawtype == "normal" or def.drawtype == "nodebox" then
|
|
||||||
if rot == 0 or rot == 1 then
|
|
||||||
roll = roll + math.pi
|
|
||||||
elseif rot == 6 or rot == 7 then
|
|
||||||
if def.drawtype ~= "normal" then
|
|
||||||
roll = roll - math.pi/2
|
|
||||||
end
|
|
||||||
else
|
|
||||||
yaw = yaw + math.pi
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.object:set_rotation({x=pitch, y=yaw, z=roll})
|
|
||||||
elseif (def.drawtype == "mesh" and def.paramtype2 == "degrotate") then
|
|
||||||
local p2 = (node.param2 - (def.place_param2 or 0)) % 240
|
|
||||||
local yaw = (p2 / 240) * (math.pi * 2)
|
|
||||||
self.object:set_yaw(yaw)
|
|
||||||
elseif (def.drawtype == "mesh" and def.paramtype2 == "colordegrotate") then
|
|
||||||
local p2 = (node.param2 % 32 - (def.place_param2 or 0) % 32) % 24
|
|
||||||
local yaw = (p2 / 24) * (math.pi * 2)
|
|
||||||
self.object:set_yaw(yaw)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
get_staticdata = function(self)
|
get_staticdata = function(self)
|
||||||
|
|
|
@ -45,6 +45,7 @@ core.features = {
|
||||||
abm_without_neighbors = true,
|
abm_without_neighbors = true,
|
||||||
biome_weights = true,
|
biome_weights = true,
|
||||||
particle_blend_clip = true,
|
particle_blend_clip = true,
|
||||||
|
remove_item_match_meta = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
"AFCMS",
|
"AFCMS",
|
||||||
"siliconsniffer",
|
"siliconsniffer",
|
||||||
"Wuzzy",
|
"Wuzzy",
|
||||||
"Zemtzov7",
|
"Zemtzov7"
|
||||||
],
|
],
|
||||||
"previous_contributors": [
|
"previous_contributors": [
|
||||||
"Ælla Chiana Moskopp (erle) <erle@dieweltistgarnichtso.net> [Logo]",
|
"Ælla Chiana Moskopp (erle) <erle@dieweltistgarnichtso.net> [Logo]",
|
||||||
|
|
|
@ -21,7 +21,7 @@ local function clients_list_formspec(dialogdata)
|
||||||
"size[6,9.5]",
|
"size[6,9.5]",
|
||||||
TOUCH_GUI and "padding[0.01,0.01]" or "",
|
TOUCH_GUI and "padding[0.01,0.01]" or "",
|
||||||
"hypertext[0,0;6,1.5;;<global margin=5 halign=center valign=middle>",
|
"hypertext[0,0;6,1.5;;<global margin=5 halign=center valign=middle>",
|
||||||
fgettext("This is the list of clients connected to\n$1",
|
fgettext("Players connected to\n$1",
|
||||||
"<b>" .. core.hypertext_escape(servername) .. "</b>") .. "]",
|
"<b>" .. core.hypertext_escape(servername) .. "</b>") .. "]",
|
||||||
"textlist[0.5,1.5;5,6.8;;" .. fmt_formspec_list(clients_list) .. "]",
|
"textlist[0.5,1.5;5,6.8;;" .. fmt_formspec_list(clients_list) .. "]",
|
||||||
"button[1.5,8.5;3,0.8;quit;OK]"
|
"button[1.5,8.5;3,0.8;quit;OK]"
|
||||||
|
|
|
@ -299,7 +299,7 @@ local function handle_buttons(this, fields)
|
||||||
worldfile:set("load_mod_" .. mod.name, mod.virtual_path)
|
worldfile:set("load_mod_" .. mod.name, mod.virtual_path)
|
||||||
was_set[mod.name] = true
|
was_set[mod.name] = true
|
||||||
elseif not was_set[mod.name] then
|
elseif not was_set[mod.name] then
|
||||||
worldfile:set("load_mod_" .. mod.name, "false")
|
worldfile:remove("load_mod_" .. mod.name)
|
||||||
end
|
end
|
||||||
elseif mod.enabled then
|
elseif mod.enabled then
|
||||||
gamedata.errormessage = fgettext_ne("Failed to enable mo" ..
|
gamedata.errormessage = fgettext_ne("Failed to enable mo" ..
|
||||||
|
|
|
@ -190,10 +190,10 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
local max_clients = 5
|
local max_clients = 5
|
||||||
if #clients_list > max_clients then
|
if #clients_list > max_clients then
|
||||||
retval = retval .. "tooltip[btn_view_clients;" ..
|
retval = retval .. "tooltip[btn_view_clients;" ..
|
||||||
fgettext("Clients:\n$1", table.concat(clients_list, "\n", 1, max_clients)) .. "\n..." .. "]"
|
fgettext("Players:\n$1", table.concat(clients_list, "\n", 1, max_clients)) .. "\n..." .. "]"
|
||||||
else
|
else
|
||||||
retval = retval .. "tooltip[btn_view_clients;" ..
|
retval = retval .. "tooltip[btn_view_clients;" ..
|
||||||
fgettext("Clients:\n$1", table.concat(clients_list, "\n")) .. "]"
|
fgettext("Players:\n$1", table.concat(clients_list, "\n")) .. "]"
|
||||||
end
|
end
|
||||||
retval = retval .. "style[btn_view_clients;padding=6]"
|
retval = retval .. "style[btn_view_clients;padding=6]"
|
||||||
retval = retval .. "image_button[4.5,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir ..
|
retval = retval .. "image_button[4.5,1.3;0.5,0.5;" .. core.formspec_escape(defaulttexturedir ..
|
||||||
|
@ -391,12 +391,15 @@ local function matches_query(server, query)
|
||||||
return name_matches and 50 or description_matches and 0
|
return name_matches and 50 or description_matches and 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local function search_server_list(input)
|
local function search_server_list(input, tabdata)
|
||||||
menudata.search_result = nil
|
menudata.search_result = nil
|
||||||
if #serverlistmgr.servers < 2 then
|
if #serverlistmgr.servers < 2 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
tabdata.pre_search_selection = tabdata.pre_search_selection or find_selected_server()
|
||||||
|
|
||||||
-- setup the search query
|
-- setup the search query
|
||||||
local query = parse_search_input(input)
|
local query = parse_search_input(input)
|
||||||
if not query then
|
if not query then
|
||||||
|
@ -419,11 +422,23 @@ local function search_server_list(input)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local current_server = find_selected_server()
|
||||||
|
|
||||||
table.sort(search_result, function(a, b)
|
table.sort(search_result, function(a, b)
|
||||||
return a.points > b.points
|
return a.points > b.points
|
||||||
end)
|
end)
|
||||||
menudata.search_result = search_result
|
menudata.search_result = search_result
|
||||||
|
|
||||||
|
-- Keep current selection if it's in search results
|
||||||
|
if current_server then
|
||||||
|
for _, server in ipairs(search_result) do
|
||||||
|
if server.address == current_server.address and
|
||||||
|
server.port == current_server.port then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Find first compatible server (favorite or public)
|
-- Find first compatible server (favorite or public)
|
||||||
for _, server in ipairs(search_result) do
|
for _, server in ipairs(search_result) do
|
||||||
if is_server_protocol_compat(server.proto_min, server.proto_max) then
|
if is_server_protocol_compat(server.proto_min, server.proto_max) then
|
||||||
|
@ -434,6 +449,7 @@ local function search_server_list(input)
|
||||||
-- If no compatible server found, clear selection
|
-- If no compatible server found, clear selection
|
||||||
set_selected_server(nil)
|
set_selected_server(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function main_button_handler(tabview, fields, name, tabdata)
|
local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
if fields.te_name then
|
if fields.te_name then
|
||||||
gamedata.playername = fields.te_name
|
gamedata.playername = fields.te_name
|
||||||
|
@ -471,6 +487,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
end
|
end
|
||||||
if event.type == "CHG" then
|
if event.type == "CHG" then
|
||||||
set_selected_server(server)
|
set_selected_server(server)
|
||||||
|
tabdata.pre_search_selection = nil
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -484,11 +501,9 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
if fields.btn_delete_favorite then
|
if fields.btn_delete_favorite then
|
||||||
local idx = core.get_table_index("servers")
|
local idx = core.get_table_index("servers")
|
||||||
if not idx then return end
|
if not idx then return end
|
||||||
local server = tabdata.lookup[idx]
|
|
||||||
if not server then return end
|
|
||||||
|
|
||||||
serverlistmgr.delete_favorite(server)
|
serverlistmgr.delete_favorite(tabdata.lookup[idx])
|
||||||
set_selected_server(server)
|
set_selected_server(tabdata.lookup[idx+1])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -516,13 +531,16 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
if fields.btn_mp_clear then
|
if fields.btn_mp_clear then
|
||||||
tabdata.search_for = ""
|
tabdata.search_for = ""
|
||||||
menudata.search_result = nil
|
menudata.search_result = nil
|
||||||
set_selected_server(nil)
|
if tabdata.pre_search_selection then
|
||||||
|
set_selected_server(tabdata.pre_search_selection)
|
||||||
|
tabdata.pre_search_selection = nil
|
||||||
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.btn_mp_search or fields.key_enter_field == "te_search" then
|
if fields.btn_mp_search or fields.key_enter_field == "te_search" then
|
||||||
tabdata.search_for = fields.te_search
|
tabdata.search_for = fields.te_search
|
||||||
search_server_list(fields.te_search)
|
search_server_list(fields.te_search, tabdata)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -256,8 +256,8 @@ fps_max (Maximum FPS) int 60 1 4294967295
|
||||||
# Vertical screen synchronization. Your system may still force VSync on even if this is disabled.
|
# Vertical screen synchronization. Your system may still force VSync on even if this is disabled.
|
||||||
vsync (VSync) bool false
|
vsync (VSync) bool false
|
||||||
|
|
||||||
# Maximum FPS when the window is not focused, or when the game is paused.
|
# Maximum FPS when the window is not focused.
|
||||||
fps_max_unfocused (FPS when unfocused or paused) int 20 1 4294967295
|
fps_max_unfocused (FPS when unfocused) int 10 1 4294967295
|
||||||
|
|
||||||
# View distance in nodes.
|
# View distance in nodes.
|
||||||
viewing_range (Viewing range) int 190 20 4000
|
viewing_range (Viewing range) int 190 20 4000
|
||||||
|
@ -295,10 +295,6 @@ arm_inertia (Arm inertia) bool true
|
||||||
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
|
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
|
||||||
view_bobbing_amount (View bobbing factor) float 1.0 0.0 7.9
|
view_bobbing_amount (View bobbing factor) float 1.0 0.0 7.9
|
||||||
|
|
||||||
# Multiplier for fall bobbing.
|
|
||||||
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
|
|
||||||
fall_bobbing_amount (Fall bobbing factor) float 0.03 0.0 100.0
|
|
||||||
|
|
||||||
[**Camera]
|
[**Camera]
|
||||||
|
|
||||||
# Field of view in degrees.
|
# Field of view in degrees.
|
||||||
|
@ -717,9 +713,6 @@ console_color (Console color) string (0,0,0)
|
||||||
# In-game chat console background alpha (opaqueness, between 0 and 255).
|
# In-game chat console background alpha (opaqueness, between 0 and 255).
|
||||||
console_alpha (Console alpha) int 200 0 255
|
console_alpha (Console alpha) int 200 0 255
|
||||||
|
|
||||||
# Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output.
|
|
||||||
clickable_chat_weblinks (Chat weblinks) bool true
|
|
||||||
|
|
||||||
# Optional override for chat weblink color.
|
# Optional override for chat weblink color.
|
||||||
chat_weblink_color (Weblink color) string #8888FF
|
chat_weblink_color (Weblink color) string #8888FF
|
||||||
|
|
||||||
|
@ -835,11 +828,12 @@ protocol_version_min (Protocol version minimum) int 1 1 65535
|
||||||
# Files that are not present will be fetched the usual way.
|
# Files that are not present will be fetched the usual way.
|
||||||
remote_media (Remote media) string
|
remote_media (Remote media) string
|
||||||
|
|
||||||
# Enable/disable running an IPv6 server.
|
# Enable IPv6 support for server.
|
||||||
|
# Note that clients will be able to connect with both IPv4 and IPv6.
|
||||||
# Ignored if bind_address is set.
|
# Ignored if bind_address is set.
|
||||||
#
|
#
|
||||||
# Requires: enable_ipv6
|
# Requires: enable_ipv6
|
||||||
ipv6_server (IPv6 server) bool false
|
ipv6_server (IPv6 server) bool true
|
||||||
|
|
||||||
[*Server Security]
|
[*Server Security]
|
||||||
|
|
||||||
|
@ -1797,14 +1791,6 @@ profiler_print_interval (Engine profiling data print interval) int 0 0
|
||||||
|
|
||||||
[*Advanced]
|
[*Advanced]
|
||||||
|
|
||||||
# Enable IPv6 support (for both client and server).
|
|
||||||
# Required for IPv6 connections to work at all.
|
|
||||||
enable_ipv6 (IPv6) bool true
|
|
||||||
|
|
||||||
# If enabled, invalid world data won't cause the server to shut down.
|
|
||||||
# Only enable this if you know what you are doing.
|
|
||||||
ignore_world_load_errors (Ignore world errors) bool false
|
|
||||||
|
|
||||||
[**Graphics]
|
[**Graphics]
|
||||||
|
|
||||||
# Enables debug and error-checking in the OpenGL driver.
|
# Enables debug and error-checking in the OpenGL driver.
|
||||||
|
@ -1990,6 +1976,10 @@ lighting_boost_spread (Light curve boost spread) float 0.2 0.0 0.4
|
||||||
|
|
||||||
[**Networking]
|
[**Networking]
|
||||||
|
|
||||||
|
# Enable IPv6 support (for both client and server).
|
||||||
|
# Required for IPv6 connections to work at all.
|
||||||
|
enable_ipv6 (IPv6) bool true
|
||||||
|
|
||||||
# Prometheus listener address.
|
# Prometheus listener address.
|
||||||
# If Luanti is compiled with ENABLE_PROMETHEUS option enabled,
|
# If Luanti is compiled with ENABLE_PROMETHEUS option enabled,
|
||||||
# enable metrics listener for Prometheus on that address.
|
# enable metrics listener for Prometheus on that address.
|
||||||
|
@ -2004,7 +1994,9 @@ max_out_chat_queue_size (Maximum size of the outgoing chat queue) int 20 -1 3276
|
||||||
client_unload_unused_data_timeout (Mapblock unload timeout) float 600.0 0.0
|
client_unload_unused_data_timeout (Mapblock unload timeout) float 600.0 0.0
|
||||||
|
|
||||||
# Maximum number of mapblocks for client to be kept in memory.
|
# Maximum number of mapblocks for client to be kept in memory.
|
||||||
# Set to -1 for unlimited amount.
|
# Note that there is an internal dynamic minimum number of blocks that
|
||||||
|
# won't be deleted, depending on the current view range.
|
||||||
|
# Set to -1 for no limit.
|
||||||
client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647
|
client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647
|
||||||
|
|
||||||
# Maximum number of blocks that are simultaneously sent per client.
|
# Maximum number of blocks that are simultaneously sent per client.
|
||||||
|
@ -2192,6 +2184,13 @@ curl_file_download_timeout (cURL file download timeout) int 300000 5000 21474836
|
||||||
|
|
||||||
[**Miscellaneous]
|
[**Miscellaneous]
|
||||||
|
|
||||||
|
# Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output.
|
||||||
|
clickable_chat_weblinks (Chat weblinks) bool true
|
||||||
|
|
||||||
|
# If enabled, invalid world data won't cause the server to shut down.
|
||||||
|
# Only enable this if you know what you are doing.
|
||||||
|
ignore_world_load_errors (Ignore world errors) bool false
|
||||||
|
|
||||||
# Adjust the detected display density, used for scaling UI elements.
|
# Adjust the detected display density, used for scaling UI elements.
|
||||||
display_density_factor (Display Density Scaling Factor) float 1 0.5 5.0
|
display_density_factor (Display Density Scaling Factor) float 1 0.5 5.0
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Luanti Lua Client Modding API Reference 5.11.0
|
Luanti Lua Client Modding API Reference 5.12.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`),
|
||||||
|
|
|
@ -22,27 +22,27 @@
|
||||||
|
|
||||||
For Debian/Ubuntu users:
|
For Debian/Ubuntu users:
|
||||||
|
|
||||||
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxi-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext
|
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext libsdl2-dev
|
||||||
|
|
||||||
For Fedora users:
|
For Fedora users:
|
||||||
|
|
||||||
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libXi-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext
|
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext SDL2-devel
|
||||||
|
|
||||||
For openSUSE users:
|
For openSUSE users:
|
||||||
|
|
||||||
sudo zypper install gcc gcc-c++ cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libXi-devel libvorbis-devel freetype2-devel
|
sudo zypper install gcc gcc-c++ cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libvorbis-devel freetype2-devel SDL2-devel
|
||||||
|
|
||||||
For Arch users:
|
For Arch users:
|
||||||
|
|
||||||
sudo pacman -S --needed base-devel libcurl-gnutls cmake libxi libpng libjpeg-turbo sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext
|
sudo pacman -S --needed base-devel libcurl-gnutls cmake libpng libjpeg-turbo sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext sdl2
|
||||||
|
|
||||||
For Alpine users:
|
For Alpine users:
|
||||||
|
|
||||||
sudo apk add build-base cmake libpng-dev jpeg-dev libxi-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext
|
sudo apk add build-base cmake libpng-dev jpeg-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext sdl2-dev
|
||||||
|
|
||||||
For Void users:
|
For Void users:
|
||||||
|
|
||||||
sudo xbps-install cmake libpng-devel jpeg-devel libXi-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel zstd libzstd-devel gettext
|
sudo xbps-install cmake libpng-devel jpeg-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel zstd libzstd-devel gettext SDL2-devel
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
It is highly recommended to use vcpkg as package manager.
|
It is highly recommended to use vcpkg as package manager.
|
||||||
|
|
||||||
After you successfully built vcpkg you can easily install the required libraries:
|
After you successfully built vcpkg you can easily install the required libraries:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext[tools] opengl-registry --triplet x64-windows
|
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext[tools] sdl2 --triplet x64-windows
|
||||||
```
|
```
|
||||||
|
|
||||||
- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
|
- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
|
||||||
|
|
|
@ -1522,7 +1522,7 @@ There are a bunch of different looking node types.
|
||||||
* `allfaces`
|
* `allfaces`
|
||||||
* Often used for partially-transparent nodes.
|
* Often used for partially-transparent nodes.
|
||||||
* External sides of textures, and unlike other drawtypes, the external sides
|
* External sides of textures, and unlike other drawtypes, the external sides
|
||||||
of other blocks, are visible from the inside.
|
of other nodes, are visible from the inside.
|
||||||
* `allfaces_optional`
|
* `allfaces_optional`
|
||||||
* Often used for leaves nodes.
|
* Often used for leaves nodes.
|
||||||
* This switches between `normal`, `glasslike` and `allfaces` according to
|
* This switches between `normal`, `glasslike` and `allfaces` according to
|
||||||
|
@ -5689,6 +5689,8 @@ Utilities
|
||||||
biome_weights = true,
|
biome_weights = true,
|
||||||
-- Particles can specify a "clip" blend mode (5.11.0)
|
-- Particles can specify a "clip" blend mode (5.11.0)
|
||||||
particle_blend_clip = true,
|
particle_blend_clip = true,
|
||||||
|
-- The `match_meta` optional parameter is available for `InvRef:remove_item()` (5.12.0)
|
||||||
|
remove_item_match_meta = true,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -7454,7 +7456,8 @@ Misc.
|
||||||
* This function can be overridden by mods to change the leave message.
|
* This function can be overridden by mods to change the leave message.
|
||||||
* `core.hash_node_position(pos)`: returns a 48-bit integer
|
* `core.hash_node_position(pos)`: returns a 48-bit integer
|
||||||
* `pos`: table {x=number, y=number, z=number},
|
* `pos`: table {x=number, y=number, z=number},
|
||||||
* Gives a unique hash number for a node position (16+16+16=48bit)
|
* Gives a unique numeric encoding for a node position (16+16+16=48bit)
|
||||||
|
* Despite the name, this is not a hash function (so it doesn't mix or produce collisions).
|
||||||
* `core.get_position_from_hash(hash)`: returns a position
|
* `core.get_position_from_hash(hash)`: returns a position
|
||||||
* Inverse transform of `core.hash_node_position`
|
* Inverse transform of `core.hash_node_position`
|
||||||
* `core.get_item_group(name, group)`: returns a rating
|
* `core.get_item_group(name, group)`: returns a rating
|
||||||
|
@ -7872,13 +7875,15 @@ An `InvRef` is a reference to an inventory.
|
||||||
can be fully added to the list
|
can be fully added to the list
|
||||||
* `contains_item(listname, stack, [match_meta])`: returns `true` if
|
* `contains_item(listname, stack, [match_meta])`: returns `true` if
|
||||||
the stack of items can be fully taken from the list.
|
the stack of items can be fully taken from the list.
|
||||||
If `match_meta` is false, only the items' names are compared
|
* If `match_meta` is `true`, item metadata is also considered when comparing
|
||||||
(default: `false`).
|
items. Otherwise, only the items names are compared. Default: `false`
|
||||||
* `remove_item(listname, stack)`: take as many items as specified from the
|
* The method ignores wear.
|
||||||
list, returns the items that were actually removed (as an `ItemStack`)
|
* `remove_item(listname, stack, [match_meta])`: take as many items as specified from the
|
||||||
-- note that any item metadata is ignored, so attempting to remove a specific
|
list, returns the items that were actually removed (as an `ItemStack`).
|
||||||
unique item this way will likely remove the wrong one -- to do that use
|
* If `match_meta` is `true` (available since feature `remove_item_match_meta`),
|
||||||
`set_stack` with an empty `ItemStack`.
|
item metadata is also considered when comparing items. Otherwise, only the
|
||||||
|
items names are compared. Default: `false`
|
||||||
|
* The method ignores wear.
|
||||||
* `get_location()`: returns a location compatible to
|
* `get_location()`: returns a location compatible to
|
||||||
`core.get_inventory(location)`.
|
`core.get_inventory(location)`.
|
||||||
* returns `{type="undefined"}` in case location is not known
|
* returns `{type="undefined"}` in case location is not known
|
||||||
|
@ -8827,6 +8832,14 @@ child will follow movement and rotation of that bone.
|
||||||
Same limits as for `thirdperson_back` apply.
|
Same limits as for `thirdperson_back` apply.
|
||||||
Defaults to `thirdperson_back` if unspecified.
|
Defaults to `thirdperson_back` if unspecified.
|
||||||
* `get_eye_offset()`: Returns camera offset vectors as set via `set_eye_offset`.
|
* `get_eye_offset()`: Returns camera offset vectors as set via `set_eye_offset`.
|
||||||
|
* `set_camera(params)`: Sets camera parameters.
|
||||||
|
* `mode`: Defines the camera mode used
|
||||||
|
- `any`: free choice between all modes (default)
|
||||||
|
- `first`: first-person camera
|
||||||
|
- `third`: third-person camera
|
||||||
|
- `third_front`: third-person camera, looking opposite of movement direction
|
||||||
|
* Supported by client since 5.12.0.
|
||||||
|
* `get_camera()`: Returns the camera parameters as a table as above.
|
||||||
* `send_mapblock(blockpos)`:
|
* `send_mapblock(blockpos)`:
|
||||||
* Sends an already loaded mapblock to the player.
|
* Sends an already loaded mapblock to the player.
|
||||||
* Returns `false` if nothing was sent (note that this can also mean that
|
* Returns `false` if nothing was sent (note that this can also mean that
|
||||||
|
@ -9221,7 +9234,7 @@ Player properties need to be saved manually.
|
||||||
-- Clients older than 5.9.0 interpret `pointable = "blocking"` as `pointable = true`.
|
-- Clients older than 5.9.0 interpret `pointable = "blocking"` as `pointable = true`.
|
||||||
-- Can be overridden by the `pointabilities` of the held item.
|
-- Can be overridden by the `pointabilities` of the held item.
|
||||||
|
|
||||||
visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item",
|
visual = "",
|
||||||
-- "cube" is a node-sized cube.
|
-- "cube" is a node-sized cube.
|
||||||
-- "sprite" is a flat texture always facing the player.
|
-- "sprite" is a flat texture always facing the player.
|
||||||
-- "upright_sprite" is a vertical flat texture.
|
-- "upright_sprite" is a vertical flat texture.
|
||||||
|
@ -9243,6 +9256,8 @@ Player properties need to be saved manually.
|
||||||
-- Wielditems are scaled a bit. If you want a wielditem to appear
|
-- Wielditems are scaled a bit. If you want a wielditem to appear
|
||||||
-- to be as large as a node, use `0.667` in `visual_size`
|
-- to be as large as a node, use `0.667` in `visual_size`
|
||||||
-- "item" is similar to "wielditem" but ignores the 'wield_image' parameter.
|
-- "item" is similar to "wielditem" but ignores the 'wield_image' parameter.
|
||||||
|
-- "node" looks exactly like a node in-world (supported since 5.12.0)
|
||||||
|
-- Note that visual effects like waving or liquid reflections will not work.
|
||||||
|
|
||||||
visual_size = {x = 1, y = 1, z = 1},
|
visual_size = {x = 1, y = 1, z = 1},
|
||||||
-- Multipliers for the visual size. If `z` is not specified, `x` will be used
|
-- Multipliers for the visual size. If `z` is not specified, `x` will be used
|
||||||
|
@ -9252,7 +9267,7 @@ Player properties need to be saved manually.
|
||||||
-- File name of mesh when using "mesh" visual
|
-- File name of mesh when using "mesh" visual
|
||||||
|
|
||||||
textures = {},
|
textures = {},
|
||||||
-- Number of required textures depends on visual.
|
-- Number of required textures depends on visual:
|
||||||
-- "cube" uses 6 textures just like a node, but all 6 must be defined.
|
-- "cube" uses 6 textures just like a node, but all 6 must be defined.
|
||||||
-- "sprite" uses 1 texture.
|
-- "sprite" uses 1 texture.
|
||||||
-- "upright_sprite" uses 2 textures: {front, back}.
|
-- "upright_sprite" uses 2 textures: {front, back}.
|
||||||
|
@ -9262,11 +9277,14 @@ Player properties need to be saved manually.
|
||||||
colors = {},
|
colors = {},
|
||||||
-- Currently unused.
|
-- Currently unused.
|
||||||
|
|
||||||
|
node = {name = "ignore", param1=0, param2=0},
|
||||||
|
-- Node to show when using the "node" visual
|
||||||
|
|
||||||
use_texture_alpha = false,
|
use_texture_alpha = false,
|
||||||
-- Use texture's alpha channel.
|
-- Use texture's alpha channel for transparency blending.
|
||||||
-- Excludes "upright_sprite" and "wielditem".
|
|
||||||
-- Note: currently causes visual issues when viewed through other
|
-- Note: currently causes visual issues when viewed through other
|
||||||
-- semi-transparent materials such as water.
|
-- semi-transparent materials such as water.
|
||||||
|
-- Note: ignored for "item", "wielditem" and "node" visual.
|
||||||
|
|
||||||
spritediv = {x = 1, y = 1},
|
spritediv = {x = 1, y = 1},
|
||||||
-- Used with spritesheet textures for animation and/or frame selection
|
-- Used with spritesheet textures for animation and/or frame selection
|
||||||
|
@ -9283,7 +9301,7 @@ Player properties need to be saved manually.
|
||||||
-- If false, object is invisible and can't be pointed.
|
-- If false, object is invisible and can't be pointed.
|
||||||
|
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
-- If true, is able to make footstep sounds of nodes
|
-- If true, object is able to make footstep sounds of nodes
|
||||||
-- (see node sound definition for details).
|
-- (see node sound definition for details).
|
||||||
|
|
||||||
automatic_rotate = 0,
|
automatic_rotate = 0,
|
||||||
|
@ -9306,6 +9324,7 @@ Player properties need to be saved manually.
|
||||||
|
|
||||||
backface_culling = true,
|
backface_culling = true,
|
||||||
-- Set to false to disable backface_culling for model
|
-- Set to false to disable backface_culling for model
|
||||||
|
-- Note: only used by "mesh" and "cube" visual
|
||||||
|
|
||||||
glow = 0,
|
glow = 0,
|
||||||
-- Add this much extra lighting when calculating texture color.
|
-- Add this much extra lighting when calculating texture color.
|
||||||
|
@ -9341,6 +9360,7 @@ Player properties need to be saved manually.
|
||||||
|
|
||||||
shaded = true,
|
shaded = true,
|
||||||
-- Setting this to 'false' disables diffuse lighting of entity
|
-- Setting this to 'false' disables diffuse lighting of entity
|
||||||
|
-- Note: ignored for "item", "wielditem" and "node" visual
|
||||||
|
|
||||||
show_on_minimap = false,
|
show_on_minimap = false,
|
||||||
-- Defaults to true for players, false for other entities.
|
-- Defaults to true for players, false for other entities.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Luanti Lua Mainmenu API Reference 5.11.0
|
Luanti Lua Mainmenu API Reference 5.12.0
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
|
|
|
@ -281,15 +281,27 @@ storing coordinates separately), but the format has been kept unchanged for
|
||||||
that part.
|
that part.
|
||||||
|
|
||||||
## `map.sqlite`
|
## `map.sqlite`
|
||||||
`map.sqlite` is a `SQLite3` database, containing a single table, called
|
`map.sqlite` is an `SQLite3` database, containing a single table, called
|
||||||
`blocks`. It looks like this:
|
`blocks`. It looks like this:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE `blocks` (
|
||||||
|
`x` INTEGER, `y` INTEGER, `z` INTEGER,
|
||||||
|
`data` BLOB NOT NULL,
|
||||||
|
PRIMARY KEY (`x`, `z`, `y`)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Before 5.12.0 it looked like this:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE TABLE `blocks` (`pos` INT NOT NULL PRIMARY KEY, `data` BLOB);
|
CREATE TABLE `blocks` (`pos` INT NOT NULL PRIMARY KEY, `data` BLOB);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Position Hashing
|
## Position Hashing
|
||||||
|
|
||||||
|
Applies to the pre-5.12.0 schema:
|
||||||
|
|
||||||
`pos` (a node position hash) is created from the three coordinates of a
|
`pos` (a node position hash) is created from the three coordinates of a
|
||||||
`MapBlock` using this algorithm, defined here in Python:
|
`MapBlock` using this algorithm, defined here in Python:
|
||||||
|
|
||||||
|
@ -335,8 +347,8 @@ See below for description.
|
||||||
> * NOTE: Byte order is MSB first (big-endian).
|
> * NOTE: Byte order is MSB first (big-endian).
|
||||||
> * NOTE: Zlib data is in such a format that Python's `zlib` at least can
|
> * NOTE: Zlib data is in such a format that Python's `zlib` at least can
|
||||||
> directly decompress.
|
> directly decompress.
|
||||||
> * NOTE: Since version 29 zstd is used instead of zlib. In addition, the entire
|
> * NOTE: Since version 29 zstd is used instead of zlib. In addition, the
|
||||||
> block is first serialized and then compressed (except the version byte).
|
> **entire block** is first serialized and then compressed (except version byte).
|
||||||
|
|
||||||
`u8` version
|
`u8` version
|
||||||
* map format version number, see serialization.h for the latest number
|
* map format version number, see serialization.h for the latest number
|
||||||
|
|
|
@ -22,11 +22,15 @@ core.register_node("basenodes:desert_stone", {
|
||||||
|
|
||||||
core.register_node("basenodes:dirt_with_grass", {
|
core.register_node("basenodes:dirt_with_grass", {
|
||||||
description = "Dirt with Grass",
|
description = "Dirt with Grass",
|
||||||
tiles ={"default_grass.png",
|
-- Using overlays here has no real merit here but we do it anyway so
|
||||||
|
-- overlay-related bugs become more apparent in devtest.
|
||||||
|
tiles = {"default_dirt.png"},
|
||||||
|
overlay_tiles = {
|
||||||
|
"default_grass.png",
|
||||||
-- a little dot on the bottom to distinguish it from dirt
|
-- a little dot on the bottom to distinguish it from dirt
|
||||||
"default_dirt.png^basenodes_dirt_with_grass_bottom.png",
|
"basenodes_dirt_with_grass_bottom.png",
|
||||||
{name = "default_dirt.png^default_grass_side.png",
|
{name = "default_grass_side.png", tileable_vertical = false},
|
||||||
tileable_vertical = false}},
|
},
|
||||||
groups = {crumbly=3, soil=1},
|
groups = {crumbly=3, soil=1},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,15 @@ core.register_entity("testentities:mesh_unshaded", {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
core.register_entity("testentities:node", {
|
||||||
|
initial_properties = {
|
||||||
|
visual = "node",
|
||||||
|
node = { name = "stairs:stair_stone" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
-- More complex meshes
|
||||||
|
|
||||||
core.register_entity("testentities:sam", {
|
core.register_entity("testentities:sam", {
|
||||||
initial_properties = {
|
initial_properties = {
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
local function get_stack_with_meta(count)
|
||||||
local item_with_meta = ItemStack({name = "air", meta = {test = "abc"}})
|
return ItemStack({name = "air", count = count, meta = {test = "abc"}})
|
||||||
|
end
|
||||||
|
|
||||||
local test_list = {
|
local test_list = {
|
||||||
ItemStack("air"),
|
ItemStack("air"),
|
||||||
ItemStack(""),
|
ItemStack(""),
|
||||||
ItemStack(item_with_meta),
|
ItemStack(get_stack_with_meta(1)),
|
||||||
}
|
}
|
||||||
|
|
||||||
local function compare_lists(a, b)
|
local function compare_lists(a, b)
|
||||||
|
@ -34,12 +35,12 @@ local function test_inventory()
|
||||||
assert(not inv:set_width("test", -1))
|
assert(not inv:set_width("test", -1))
|
||||||
|
|
||||||
inv:set_stack("test", 1, "air")
|
inv:set_stack("test", 1, "air")
|
||||||
inv:set_stack("test", 3, item_with_meta)
|
inv:set_stack("test", 3, get_stack_with_meta(1))
|
||||||
assert(not inv:is_empty("test"))
|
assert(not inv:is_empty("test"))
|
||||||
assert(compare_lists(inv:get_list("test"), test_list))
|
assert(compare_lists(inv:get_list("test"), test_list))
|
||||||
|
|
||||||
assert(inv:add_item("test", "air") == ItemStack())
|
assert(inv:add_item("test", "air") == ItemStack())
|
||||||
assert(inv:add_item("test", item_with_meta) == ItemStack())
|
assert(inv:add_item("test", get_stack_with_meta(1)) == ItemStack())
|
||||||
assert(inv:get_stack("test", 1) == ItemStack("air 2"))
|
assert(inv:get_stack("test", 1) == ItemStack("air 2"))
|
||||||
|
|
||||||
assert(inv:room_for_item("test", "air 99"))
|
assert(inv:room_for_item("test", "air 99"))
|
||||||
|
@ -48,16 +49,28 @@ local function test_inventory()
|
||||||
inv:set_stack("test", 2, "")
|
inv:set_stack("test", 2, "")
|
||||||
|
|
||||||
assert(inv:contains_item("test", "air"))
|
assert(inv:contains_item("test", "air"))
|
||||||
|
assert(inv:contains_item("test", "air 4"))
|
||||||
|
assert(not inv:contains_item("test", "air 5"))
|
||||||
assert(not inv:contains_item("test", "air 99"))
|
assert(not inv:contains_item("test", "air 99"))
|
||||||
assert(inv:contains_item("test", item_with_meta, true))
|
assert(inv:contains_item("test", "air 2", true))
|
||||||
|
assert(not inv:contains_item("test", "air 3", true))
|
||||||
|
assert(inv:contains_item("test", get_stack_with_meta(2), true))
|
||||||
|
assert(not inv:contains_item("test", get_stack_with_meta(3), true))
|
||||||
|
|
||||||
-- Items should be removed in reverse and combine with first stack removed
|
-- Items should be removed in reverse and combine with first stack removed
|
||||||
assert(inv:remove_item("test", "air") == item_with_meta)
|
assert(inv:remove_item("test", "air") == get_stack_with_meta(1))
|
||||||
item_with_meta:set_count(2)
|
assert(inv:remove_item("test", "air 2") == get_stack_with_meta(2))
|
||||||
assert(inv:remove_item("test", "air 2") == item_with_meta)
|
|
||||||
assert(inv:remove_item("test", "air") == ItemStack("air"))
|
assert(inv:remove_item("test", "air") == ItemStack("air"))
|
||||||
assert(inv:is_empty("test"))
|
assert(inv:is_empty("test"))
|
||||||
|
|
||||||
|
inv:set_stack("test", 1, "air 3")
|
||||||
|
inv:set_stack("test", 3, get_stack_with_meta(2))
|
||||||
|
assert(inv:remove_item("test", "air 4", true) == ItemStack("air 3"))
|
||||||
|
inv:set_stack("test", 1, "air 3")
|
||||||
|
assert(inv:remove_item("test", get_stack_with_meta(3), true) == get_stack_with_meta(2))
|
||||||
|
assert(inv:remove_item("test", "air 3", true) == ItemStack("air 3"))
|
||||||
|
assert(inv:is_empty("test"))
|
||||||
|
|
||||||
-- Failure of set_list(s) should not change inventory
|
-- Failure of set_list(s) should not change inventory
|
||||||
local before = inv:get_list("test")
|
local before = inv:get_list("test")
|
||||||
pcall(inv.set_lists, inv, {test = true})
|
pcall(inv.set_lists, inv, {test = true})
|
||||||
|
|
|
@ -189,6 +189,29 @@ local function test_write_json()
|
||||||
end
|
end
|
||||||
unittests.register("test_write_json", test_write_json)
|
unittests.register("test_write_json", test_write_json)
|
||||||
|
|
||||||
|
local function lint_json_files()
|
||||||
|
-- Check that files we ship with Luanti are valid JSON
|
||||||
|
local stack = {core.get_builtin_path()}
|
||||||
|
local checked = 0
|
||||||
|
while #stack > 0 do
|
||||||
|
local path = table.remove(stack)
|
||||||
|
for _, name in ipairs(core.get_dir_list(path, true)) do
|
||||||
|
stack[#stack+1] = path .. "/" .. name
|
||||||
|
end
|
||||||
|
for _, name in ipairs(core.get_dir_list(path, false)) do
|
||||||
|
if name:match("%.json$") then
|
||||||
|
local f = io.open(path .. "/" .. name, "rb")
|
||||||
|
print(path .. "/" .. name)
|
||||||
|
assert(core.parse_json(f:read("*all"), -1) ~= nil)
|
||||||
|
f:close()
|
||||||
|
checked = checked + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert(checked > 0, "no files found?!")
|
||||||
|
end
|
||||||
|
unittests.register("lint_json_files", lint_json_files)
|
||||||
|
|
||||||
local function test_game_info()
|
local function test_game_info()
|
||||||
local info = core.get_game_info()
|
local info = core.get_game_info()
|
||||||
local game_conf = Settings(info.path .. "/game.conf")
|
local game_conf = Settings(info.path .. "/game.conf")
|
||||||
|
|
|
@ -21,7 +21,7 @@ Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the
|
||||||
* `ENABLE_OPENGL` - Enable OpenGL driver
|
* `ENABLE_OPENGL` - Enable OpenGL driver
|
||||||
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
|
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
|
||||||
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
|
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
|
||||||
* `USE_SDL2` (default: ON for Android, OFF for other platforms) - Use SDL2 instead of older native device code
|
* `USE_SDL2` (default: platform-dependent, usually `ON`) - Use SDL2 instead of older native device code
|
||||||
|
|
||||||
However, IrrlichtMt cannot be built or installed separately.
|
However, IrrlichtMt cannot be built or installed separately.
|
||||||
|
|
||||||
|
|
|
@ -34,16 +34,16 @@ public:
|
||||||
/** \return Pointer to mesh which is displayed by this node. */
|
/** \return Pointer to mesh which is displayed by this node. */
|
||||||
virtual IMesh *getMesh(void) = 0;
|
virtual IMesh *getMesh(void) = 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 directly.
|
||||||
/** In this way it is possible to change the materials of a mesh
|
/** In this way it is possible to change the materials of a mesh
|
||||||
causing all mesh scene nodes referencing this mesh to change, too.
|
causing all mesh scene nodes referencing this mesh to change, too.
|
||||||
\param readonly Flag if the materials shall be read-only. */
|
\param shared Flag if the materials shall be shared. */
|
||||||
virtual void setReadOnlyMaterials(bool readonly) = 0;
|
virtual void setSharedMaterials(bool shared) = 0;
|
||||||
|
|
||||||
//! Check if the scene node should not copy the materials of the mesh but use them in a read only style
|
//! Check if the scene node does not copy the materials of the mesh but uses them directly.
|
||||||
/** This flag can be set by setReadOnlyMaterials().
|
/** This flag can be set by setSharedMaterials().
|
||||||
\return Whether the materials are read-only. */
|
\return Whether the materials are shared. */
|
||||||
virtual bool isReadOnlyMaterials() const = 0;
|
virtual bool isSharedMaterials() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -310,7 +310,11 @@ public:
|
||||||
\return The material at that index. */
|
\return The material at that index. */
|
||||||
virtual video::SMaterial &getMaterial(u32 num)
|
virtual video::SMaterial &getMaterial(u32 num)
|
||||||
{
|
{
|
||||||
return video::IdentityMaterial;
|
// We return a default material since a reference can't be null,
|
||||||
|
// but note that writing to this is a mistake either by a child class
|
||||||
|
// or the caller, because getMaterialCount() is zero.
|
||||||
|
// Doing so will helpfully cause a segfault.
|
||||||
|
return const_cast<video::SMaterial&>(video::IdentityMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get amount of materials used by this scene node.
|
//! Get amount of materials used by this scene node.
|
||||||
|
|
|
@ -198,9 +198,6 @@ public:
|
||||||
or similar. */
|
or similar. */
|
||||||
virtual bool supportsTouchEvents() const { return false; }
|
virtual bool supportsTouchEvents() const { return false; }
|
||||||
|
|
||||||
//! Checks whether windowing uses the Wayland protocol.
|
|
||||||
virtual bool isUsingWayland() const { return false; }
|
|
||||||
|
|
||||||
//! Get the current color format of the window
|
//! Get the current color format of the window
|
||||||
/** \return Color format of the window. */
|
/** \return Color format of the window. */
|
||||||
virtual video::ECOLOR_FORMAT getColorFormat() const = 0;
|
virtual video::ECOLOR_FORMAT getColorFormat() const = 0;
|
||||||
|
|
|
@ -472,7 +472,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
//! global const identity Material
|
//! global const identity Material
|
||||||
IRRLICHT_API extern SMaterial IdentityMaterial;
|
IRRLICHT_API extern const SMaterial IdentityMaterial;
|
||||||
|
|
||||||
} // end namespace video
|
} // end namespace video
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
|
|
@ -18,47 +18,38 @@ namespace core
|
||||||
|
|
||||||
//! Rounding error constant often used when comparing f32 values.
|
//! Rounding error constant often used when comparing f32 values.
|
||||||
|
|
||||||
const f32 ROUNDING_ERROR_f32 = 0.000001f;
|
constexpr f32 ROUNDING_ERROR_f32 = 0.000001f;
|
||||||
const f64 ROUNDING_ERROR_f64 = 0.00000001;
|
constexpr f64 ROUNDING_ERROR_f64 = 0.00000001;
|
||||||
|
|
||||||
#ifdef PI // make sure we don't collide with a define
|
#ifdef PI // make sure we don't collide with a define
|
||||||
#undef PI
|
#undef PI
|
||||||
#endif
|
#endif
|
||||||
//! Constant for PI.
|
//! Constant for PI.
|
||||||
const f32 PI = 3.14159265359f;
|
constexpr f32 PI = M_PI;
|
||||||
|
|
||||||
//! Constant for reciprocal of PI.
|
|
||||||
const f32 RECIPROCAL_PI = 1.0f / PI;
|
|
||||||
|
|
||||||
//! Constant for half of PI.
|
|
||||||
const f32 HALF_PI = PI / 2.0f;
|
|
||||||
|
|
||||||
#ifdef PI64 // make sure we don't collide with a define
|
#ifdef PI64 // make sure we don't collide with a define
|
||||||
#undef PI64
|
#undef PI64
|
||||||
#endif
|
#endif
|
||||||
//! Constant for 64bit PI.
|
//! Constant for 64bit PI.
|
||||||
const f64 PI64 = 3.1415926535897932384626433832795028841971693993751;
|
constexpr f64 PI64 = M_PI;
|
||||||
|
|
||||||
//! Constant for 64bit reciprocal of PI.
|
|
||||||
const f64 RECIPROCAL_PI64 = 1.0 / PI64;
|
|
||||||
|
|
||||||
//! 32bit Constant for converting from degrees to radians
|
//! 32bit Constant for converting from degrees to radians
|
||||||
const f32 DEGTORAD = PI / 180.0f;
|
constexpr f32 DEGTORAD = PI / 180.0f;
|
||||||
|
|
||||||
//! 32bit constant for converting from radians to degrees (formally known as GRAD_PI)
|
//! 32bit constant for converting from radians to degrees (formally known as GRAD_PI)
|
||||||
const f32 RADTODEG = 180.0f / PI;
|
constexpr f32 RADTODEG = 180.0f / PI;
|
||||||
|
|
||||||
//! 64bit constant for converting from degrees to radians (formally known as GRAD_PI2)
|
//! 64bit constant for converting from degrees to radians (formally known as GRAD_PI2)
|
||||||
const f64 DEGTORAD64 = PI64 / 180.0;
|
constexpr f64 DEGTORAD64 = PI64 / 180.0;
|
||||||
|
|
||||||
//! 64bit constant for converting from radians to degrees
|
//! 64bit constant for converting from radians to degrees
|
||||||
const f64 RADTODEG64 = 180.0 / PI64;
|
constexpr f64 RADTODEG64 = 180.0 / PI64;
|
||||||
|
|
||||||
//! Utility function to convert a radian value to degrees
|
//! Utility function to convert a radian value to degrees
|
||||||
/** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X
|
/** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X
|
||||||
\param radians The radians value to convert to degrees.
|
\param radians The radians value to convert to degrees.
|
||||||
*/
|
*/
|
||||||
inline f32 radToDeg(f32 radians)
|
inline constexpr f32 radToDeg(f32 radians)
|
||||||
{
|
{
|
||||||
return RADTODEG * radians;
|
return RADTODEG * radians;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +58,7 @@ inline f32 radToDeg(f32 radians)
|
||||||
/** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X
|
/** Provided as it can be clearer to write radToDeg(X) than RADTODEG * X
|
||||||
\param radians The radians value to convert to degrees.
|
\param radians The radians value to convert to degrees.
|
||||||
*/
|
*/
|
||||||
inline f64 radToDeg(f64 radians)
|
inline constexpr f64 radToDeg(f64 radians)
|
||||||
{
|
{
|
||||||
return RADTODEG64 * radians;
|
return RADTODEG64 * radians;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +67,7 @@ inline f64 radToDeg(f64 radians)
|
||||||
/** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X
|
/** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X
|
||||||
\param degrees The degrees value to convert to radians.
|
\param degrees The degrees value to convert to radians.
|
||||||
*/
|
*/
|
||||||
inline f32 degToRad(f32 degrees)
|
inline constexpr f32 degToRad(f32 degrees)
|
||||||
{
|
{
|
||||||
return DEGTORAD * degrees;
|
return DEGTORAD * degrees;
|
||||||
}
|
}
|
||||||
|
@ -85,44 +76,44 @@ inline f32 degToRad(f32 degrees)
|
||||||
/** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X
|
/** Provided as it can be clearer to write degToRad(X) than DEGTORAD * X
|
||||||
\param degrees The degrees value to convert to radians.
|
\param degrees The degrees value to convert to radians.
|
||||||
*/
|
*/
|
||||||
inline f64 degToRad(f64 degrees)
|
inline constexpr f64 degToRad(f64 degrees)
|
||||||
{
|
{
|
||||||
return DEGTORAD64 * degrees;
|
return DEGTORAD64 * degrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns minimum of two values. Own implementation to get rid of the STL (VS6 problems)
|
//! returns minimum of two values.
|
||||||
template <class T>
|
template <class T>
|
||||||
inline const T &min_(const T &a, const T &b)
|
inline const T &min_(const T &a, const T &b)
|
||||||
{
|
{
|
||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns minimum of three values. Own implementation to get rid of the STL (VS6 problems)
|
//! returns minimum of three values.
|
||||||
template <class T>
|
template <class T>
|
||||||
inline const T &min_(const T &a, const T &b, const T &c)
|
inline const T &min_(const T &a, const T &b, const T &c)
|
||||||
{
|
{
|
||||||
return a < b ? min_(a, c) : min_(b, c);
|
return a < b ? min_(a, c) : min_(b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns maximum of two values. Own implementation to get rid of the STL (VS6 problems)
|
//! returns maximum of two values.
|
||||||
template <class T>
|
template <class T>
|
||||||
inline const T &max_(const T &a, const T &b)
|
inline const T &max_(const T &a, const T &b)
|
||||||
{
|
{
|
||||||
return a < b ? b : a;
|
return a < b ? b : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns maximum of three values. Own implementation to get rid of the STL (VS6 problems)
|
//! returns maximum of three values.
|
||||||
template <class T>
|
template <class T>
|
||||||
inline const T &max_(const T &a, const T &b, const T &c)
|
inline const T &max_(const T &a, const T &b, const T &c)
|
||||||
{
|
{
|
||||||
return a < b ? max_(b, c) : max_(a, c);
|
return a < b ? max_(b, c) : max_(a, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns abs of two values. Own implementation to get rid of STL (VS6 problems)
|
//! returns abs of two values.
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T abs_(const T &a)
|
inline T abs_(const T &a)
|
||||||
{
|
{
|
||||||
return a < (T)0 ? -a : a;
|
return std::abs(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns linear interpolation of a and b with ratio t
|
//! returns linear interpolation of a and b with ratio t
|
||||||
|
@ -140,19 +131,6 @@ inline const T clamp(const T &value, const T &low, const T &high)
|
||||||
return min_(max_(value, low), high);
|
return min_(max_(value, low), high);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! swaps the content of the passed parameters
|
|
||||||
// Note: We use the same trick as boost and use two template arguments to
|
|
||||||
// avoid ambiguity when swapping objects of an Irrlicht type that has not
|
|
||||||
// it's own swap overload. Otherwise we get conflicts with some compilers
|
|
||||||
// in combination with stl.
|
|
||||||
template <class T1, class T2>
|
|
||||||
inline void swap(T1 &a, T2 &b)
|
|
||||||
{
|
|
||||||
T1 c(a);
|
|
||||||
a = b;
|
|
||||||
b = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T roundingError();
|
inline T roundingError();
|
||||||
|
|
||||||
|
|
|
@ -162,21 +162,12 @@ public:
|
||||||
//! Returns true if the matrix is the identity matrix
|
//! Returns true if the matrix is the identity matrix
|
||||||
inline bool isIdentity() const;
|
inline bool isIdentity() const;
|
||||||
|
|
||||||
//! Returns true if the matrix is orthogonal
|
|
||||||
inline bool isOrthogonal() const;
|
|
||||||
|
|
||||||
//! Returns true if the matrix is the identity matrix
|
|
||||||
bool isIdentity_integer_base() const;
|
|
||||||
|
|
||||||
//! Set the translation of the current matrix. Will erase any previous values.
|
//! Set the translation of the current matrix. Will erase any previous values.
|
||||||
CMatrix4<T> &setTranslation(const vector3d<T> &translation);
|
CMatrix4<T> &setTranslation(const vector3d<T> &translation);
|
||||||
|
|
||||||
//! Gets the current translation
|
//! Gets the current translation
|
||||||
vector3d<T> getTranslation() const;
|
vector3d<T> getTranslation() const;
|
||||||
|
|
||||||
//! Set the inverse translation of the current matrix. Will erase any previous values.
|
|
||||||
CMatrix4<T> &setInverseTranslation(const vector3d<T> &translation);
|
|
||||||
|
|
||||||
//! Make a rotation matrix from Euler angles. The 4th row and column are unmodified.
|
//! Make a rotation matrix from Euler angles. The 4th row and column are unmodified.
|
||||||
//! NOTE: Rotation order is ZYX. This means that vectors are
|
//! NOTE: Rotation order is ZYX. This means that vectors are
|
||||||
//! first rotated around the X, then the Y, and finally the Z axis.
|
//! first rotated around the X, then the Y, and finally the Z axis.
|
||||||
|
@ -188,9 +179,7 @@ public:
|
||||||
CMatrix4<T> &setRotationDegrees(const vector3d<T> &rotation);
|
CMatrix4<T> &setRotationDegrees(const vector3d<T> &rotation);
|
||||||
|
|
||||||
//! Get the rotation, as set by setRotation() when you already know the scale used to create the matrix
|
//! Get the rotation, as set by setRotation() when you already know the scale used to create the matrix
|
||||||
/** NOTE: The scale needs to be the correct one used to create this matrix.
|
/**
|
||||||
You can _not_ use the result of getScale(), but have to save your scale
|
|
||||||
variable in another place (like ISceneNode does).
|
|
||||||
NOTE: No scale value can be 0 or the result is undefined.
|
NOTE: No scale value can be 0 or the result is undefined.
|
||||||
NOTE: It does not necessarily return the *same* Euler angles as those set by setRotationDegrees(),
|
NOTE: It does not necessarily return the *same* Euler angles as those set by setRotationDegrees(),
|
||||||
but the rotation will be equivalent, i.e. will have the same result when used to rotate a vector or node.
|
but the rotation will be equivalent, i.e. will have the same result when used to rotate a vector or node.
|
||||||
|
@ -198,24 +187,18 @@ public:
|
||||||
WARNING: There have been troubles with this function over the years and we may still have missed some corner cases.
|
WARNING: There have been troubles with this function over the years and we may still have missed some corner cases.
|
||||||
It's generally safer to keep the rotation and scale you used to create the matrix around and work with those.
|
It's generally safer to keep the rotation and scale you used to create the matrix around and work with those.
|
||||||
*/
|
*/
|
||||||
core::vector3d<T> getRotationDegrees(const vector3d<T> &scale) const;
|
vector3d<T> getRotationRadians(const vector3d<T> &scale) const;
|
||||||
|
|
||||||
//! Returns the rotation, as set by setRotation().
|
//! Returns the rotation, as set by setRotation().
|
||||||
/** NOTE: You will have the same end-rotation as used in setRotation, but it might not use the same axis values.
|
/** NOTE: You will have the same end-rotation as used in setRotation, but it might not use the same axis values.
|
||||||
NOTE: This only works correct if no other matrix operations have been done on the inner 3x3 matrix besides
|
NOTE: This only works correctly for TRS matrix products where S is a positive, component-wise scaling (see setScale).
|
||||||
setting rotation (so no scale/shear). Thought it (probably) works as long as scale doesn't flip handedness.
|
|
||||||
NOTE: It does not necessarily return the *same* Euler angles as those set by setRotationDegrees(),
|
NOTE: It does not necessarily return the *same* Euler angles as those set by setRotationDegrees(),
|
||||||
but the rotation will be equivalent, i.e. will have the same result when used to rotate a vector or node.
|
but the rotation will be equivalent, i.e. will have the same result when used to rotate a vector or node.
|
||||||
*/
|
*/
|
||||||
core::vector3d<T> getRotationDegrees() const;
|
vector3d<T> getRotationRadians() const;
|
||||||
|
|
||||||
//! Make an inverted rotation matrix from Euler angles.
|
//! Same as getRotationRadians, but returns degrees.
|
||||||
/** The 4th row and column are unmodified. */
|
vector3d<T> getRotationDegrees() const;
|
||||||
inline CMatrix4<T> &setInverseRotationRadians(const vector3d<T> &rotation);
|
|
||||||
|
|
||||||
//! Make an inverted rotation matrix from Euler angles.
|
|
||||||
/** The 4th row and column are unmodified. */
|
|
||||||
inline CMatrix4<T> &setInverseRotationDegrees(const vector3d<T> &rotation);
|
|
||||||
|
|
||||||
//! Make a rotation matrix from angle and axis, assuming left handed rotation.
|
//! Make a rotation matrix from angle and axis, assuming left handed rotation.
|
||||||
/** The 4th row and column are unmodified. */
|
/** The 4th row and column are unmodified. */
|
||||||
|
@ -225,10 +208,10 @@ public:
|
||||||
CMatrix4<T> &setScale(const vector3d<T> &scale);
|
CMatrix4<T> &setScale(const vector3d<T> &scale);
|
||||||
|
|
||||||
//! Set Scale
|
//! Set Scale
|
||||||
CMatrix4<T> &setScale(const T scale) { return setScale(core::vector3d<T>(scale, scale, scale)); }
|
CMatrix4<T> &setScale(const T scale) { return setScale(vector3d<T>(scale, scale, scale)); }
|
||||||
|
|
||||||
//! Get Scale
|
//! Get Scale
|
||||||
core::vector3d<T> getScale() const;
|
vector3d<T> getScale() const;
|
||||||
|
|
||||||
//! Translate a vector by the inverse of the translation part of this matrix.
|
//! Translate a vector by the inverse of the translation part of this matrix.
|
||||||
void inverseTranslateVect(vector3df &vect) const;
|
void inverseTranslateVect(vector3df &vect) const;
|
||||||
|
@ -259,7 +242,7 @@ public:
|
||||||
//! An alternate transform vector method, writing into an array of 4 floats
|
//! An alternate transform vector method, writing into an array of 4 floats
|
||||||
/** This operation is performed as if the vector was 4d with the 4th component =1.
|
/** This operation is performed as if the vector was 4d with the 4th component =1.
|
||||||
NOTE: out[3] will be written to (4th vector component)*/
|
NOTE: out[3] will be written to (4th vector component)*/
|
||||||
void transformVect(T *out, const core::vector3df &in) const;
|
void transformVect(T *out, const vector3df &in) const;
|
||||||
|
|
||||||
//! An alternate transform vector method, reading from and writing to an array of 3 floats
|
//! An alternate transform vector method, reading from and writing to an array of 3 floats
|
||||||
/** This operation is performed as if the vector was 4d with the 4th component =1
|
/** This operation is performed as if the vector was 4d with the 4th component =1
|
||||||
|
@ -274,13 +257,13 @@ public:
|
||||||
void translateVect(vector3df &vect) const;
|
void translateVect(vector3df &vect) const;
|
||||||
|
|
||||||
//! Transforms a plane by this matrix
|
//! Transforms a plane by this matrix
|
||||||
void transformPlane(core::plane3d<f32> &plane) const;
|
void transformPlane(plane3d<f32> &plane) const;
|
||||||
|
|
||||||
//! Transforms a plane by this matrix
|
//! Transforms a plane by this matrix
|
||||||
void transformPlane(const core::plane3d<f32> &in, core::plane3d<f32> &out) const;
|
void transformPlane(const plane3d<f32> &in, plane3d<f32> &out) const;
|
||||||
|
|
||||||
//! Transforms a axis aligned bounding box
|
//! Transforms a axis aligned bounding box
|
||||||
void transformBoxEx(core::aabbox3d<f32> &box) const;
|
void transformBoxEx(aabbox3d<f32> &box) const;
|
||||||
|
|
||||||
//! Multiplies this matrix by a 1x4 matrix
|
//! Multiplies this matrix by a 1x4 matrix
|
||||||
void multiplyWith1x4Matrix(T *matrix) const;
|
void multiplyWith1x4Matrix(T *matrix) const;
|
||||||
|
@ -338,16 +321,16 @@ public:
|
||||||
\param plane: plane into which the geometry if flattened into
|
\param plane: plane into which the geometry if flattened into
|
||||||
\param point: value between 0 and 1, describing the light source.
|
\param point: value between 0 and 1, describing the light source.
|
||||||
If this is 1, it is a point light, if it is 0, it is a directional light. */
|
If this is 1, it is a point light, if it is 0, it is a directional light. */
|
||||||
CMatrix4<T> &buildShadowMatrix(const core::vector3df &light, core::plane3df plane, f32 point = 1.0f);
|
CMatrix4<T> &buildShadowMatrix(const vector3df &light, plane3df plane, f32 point = 1.0f);
|
||||||
|
|
||||||
//! Builds a matrix which transforms a normalized Device Coordinate to Device Coordinates.
|
//! Builds a matrix which transforms a normalized Device Coordinate to Device Coordinates.
|
||||||
/** Used to scale <-1,-1><1,1> to viewport, for example from <-1,-1> <1,1> to the viewport <0,0><0,640> */
|
/** Used to scale <-1,-1><1,1> to viewport, for example from <-1,-1> <1,1> to the viewport <0,0><0,640> */
|
||||||
CMatrix4<T> &buildNDCToDCMatrix(const core::rect<s32> &area, f32 zScale);
|
CMatrix4<T> &buildNDCToDCMatrix(const rect<s32> &area, f32 zScale);
|
||||||
|
|
||||||
//! Creates a new matrix as interpolated matrix from two other ones.
|
//! Creates a new matrix as interpolated matrix from two other ones.
|
||||||
/** \param b: other matrix to interpolate with
|
/** \param b: other matrix to interpolate with
|
||||||
\param time: Must be a value between 0 and 1. */
|
\param time: Must be a value between 0 and 1. */
|
||||||
CMatrix4<T> interpolate(const core::CMatrix4<T> &b, f32 time) const;
|
CMatrix4<T> interpolate(const CMatrix4<T> &b, f32 time) const;
|
||||||
|
|
||||||
//! Gets transposed matrix
|
//! Gets transposed matrix
|
||||||
CMatrix4<T> getTransposed() const;
|
CMatrix4<T> getTransposed() const;
|
||||||
|
@ -359,13 +342,13 @@ public:
|
||||||
/** \param from: vector to rotate from
|
/** \param from: vector to rotate from
|
||||||
\param to: vector to rotate to
|
\param to: vector to rotate to
|
||||||
*/
|
*/
|
||||||
CMatrix4<T> &buildRotateFromTo(const core::vector3df &from, const core::vector3df &to);
|
CMatrix4<T> &buildRotateFromTo(const vector3df &from, const vector3df &to);
|
||||||
|
|
||||||
//! Builds a combined matrix which translates to a center before rotation and translates from origin afterwards
|
//! Builds a combined matrix which translates to a center before rotation and translates from origin afterwards
|
||||||
/** \param center Position to rotate around
|
/** \param center Position to rotate around
|
||||||
\param translate Translation applied after the rotation
|
\param translate Translation applied after the rotation
|
||||||
*/
|
*/
|
||||||
void setRotationCenter(const core::vector3df ¢er, const core::vector3df &translate);
|
void setRotationCenter(const vector3df ¢er, const vector3df &translate);
|
||||||
|
|
||||||
//! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis
|
//! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis
|
||||||
/** \param camPos: viewer position in world coo
|
/** \param camPos: viewer position in world coo
|
||||||
|
@ -374,11 +357,11 @@ public:
|
||||||
\param axis: axis to rotate about
|
\param axis: axis to rotate about
|
||||||
\param from: source vector to rotate from
|
\param from: source vector to rotate from
|
||||||
*/
|
*/
|
||||||
void buildAxisAlignedBillboard(const core::vector3df &camPos,
|
void buildAxisAlignedBillboard(const vector3df &camPos,
|
||||||
const core::vector3df ¢er,
|
const vector3df ¢er,
|
||||||
const core::vector3df &translation,
|
const vector3df &translation,
|
||||||
const core::vector3df &axis,
|
const vector3df &axis,
|
||||||
const core::vector3df &from);
|
const vector3df &from);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
construct 2D Texture transformations
|
construct 2D Texture transformations
|
||||||
|
@ -386,9 +369,9 @@ public:
|
||||||
*/
|
*/
|
||||||
//! Set to a texture transformation matrix with the given parameters.
|
//! Set to a texture transformation matrix with the given parameters.
|
||||||
CMatrix4<T> &buildTextureTransform(f32 rotateRad,
|
CMatrix4<T> &buildTextureTransform(f32 rotateRad,
|
||||||
const core::vector2df &rotatecenter,
|
const vector2df &rotatecenter,
|
||||||
const core::vector2df &translate,
|
const vector2df &translate,
|
||||||
const core::vector2df &scale);
|
const vector2df &scale);
|
||||||
|
|
||||||
//! Set texture transformation rotation
|
//! Set texture transformation rotation
|
||||||
/** Rotate about z axis, recenter at (0.5,0.5).
|
/** Rotate about z axis, recenter at (0.5,0.5).
|
||||||
|
@ -439,9 +422,12 @@ public:
|
||||||
CMatrix4<T> &setM(const T *data);
|
CMatrix4<T> &setM(const T *data);
|
||||||
|
|
||||||
//! Compare two matrices using the equal method
|
//! Compare two matrices using the equal method
|
||||||
bool equals(const core::CMatrix4<T> &other, const T tolerance = (T)ROUNDING_ERROR_f64) const;
|
bool equals(const CMatrix4<T> &other, const T tolerance = (T)ROUNDING_ERROR_f64) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <bool degrees>
|
||||||
|
vector3d<T> getRotation(const vector3d<T> &scale) const;
|
||||||
|
|
||||||
//! Matrix data, stored in row-major order
|
//! Matrix data, stored in row-major order
|
||||||
T M[16];
|
T M[16];
|
||||||
};
|
};
|
||||||
|
@ -645,21 +631,8 @@ inline CMatrix4<T> &CMatrix4<T>::operator*=(const T &scalar)
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::operator*=(const CMatrix4<T> &other)
|
inline CMatrix4<T> &CMatrix4<T>::operator*=(const CMatrix4<T> &other)
|
||||||
{
|
{
|
||||||
#if defined(USE_MATRIX_TEST)
|
|
||||||
// do checks on your own in order to avoid copy creation
|
|
||||||
if (!other.isIdentity()) {
|
|
||||||
if (this->isIdentity()) {
|
|
||||||
return (*this = other);
|
|
||||||
} else {
|
|
||||||
CMatrix4<T> temp(*this);
|
|
||||||
return setbyproduct_nocheck(temp, other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
#else
|
|
||||||
CMatrix4<T> temp(*this);
|
CMatrix4<T> temp(*this);
|
||||||
return setbyproduct_nocheck(temp, other);
|
return setbyproduct_nocheck(temp, other);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! multiply by another matrix
|
//! multiply by another matrix
|
||||||
|
@ -699,30 +672,13 @@ inline CMatrix4<T> &CMatrix4<T>::setbyproduct_nocheck(const CMatrix4<T> &other_a
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::setbyproduct(const CMatrix4<T> &other_a, const CMatrix4<T> &other_b)
|
inline CMatrix4<T> &CMatrix4<T>::setbyproduct(const CMatrix4<T> &other_a, const CMatrix4<T> &other_b)
|
||||||
{
|
{
|
||||||
#if defined(USE_MATRIX_TEST)
|
|
||||||
if (other_a.isIdentity())
|
|
||||||
return (*this = other_b);
|
|
||||||
else if (other_b.isIdentity())
|
|
||||||
return (*this = other_a);
|
|
||||||
else
|
|
||||||
return setbyproduct_nocheck(other_a, other_b);
|
|
||||||
#else
|
|
||||||
return setbyproduct_nocheck(other_a, other_b);
|
return setbyproduct_nocheck(other_a, other_b);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! multiply by another matrix
|
//! multiply by another matrix
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> CMatrix4<T>::operator*(const CMatrix4<T> &m2) const
|
inline CMatrix4<T> CMatrix4<T>::operator*(const CMatrix4<T> &m2) const
|
||||||
{
|
{
|
||||||
#if defined(USE_MATRIX_TEST)
|
|
||||||
// Testing purpose..
|
|
||||||
if (this->isIdentity())
|
|
||||||
return m2;
|
|
||||||
if (m2.isIdentity())
|
|
||||||
return *this;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CMatrix4<T> m3(EM4CONST_NOTHING);
|
CMatrix4<T> m3(EM4CONST_NOTHING);
|
||||||
|
|
||||||
const T *m1 = M;
|
const T *m1 = M;
|
||||||
|
@ -764,15 +720,6 @@ inline CMatrix4<T> &CMatrix4<T>::setTranslation(const vector3d<T> &translation)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline CMatrix4<T> &CMatrix4<T>::setInverseTranslation(const vector3d<T> &translation)
|
|
||||||
{
|
|
||||||
M[12] = -translation.X;
|
|
||||||
M[13] = -translation.Y;
|
|
||||||
M[14] = -translation.Z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::setScale(const vector3d<T> &scale)
|
inline CMatrix4<T> &CMatrix4<T>::setScale(const vector3d<T> &scale)
|
||||||
{
|
{
|
||||||
|
@ -805,13 +752,7 @@ inline vector3d<T> CMatrix4<T>::getScale() const
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::setRotationDegrees(const vector3d<T> &rotation)
|
inline CMatrix4<T> &CMatrix4<T>::setRotationDegrees(const vector3d<T> &rotation)
|
||||||
{
|
{
|
||||||
return setRotationRadians(rotation * core::DEGTORAD);
|
return setRotationRadians(rotation * DEGTORAD);
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline CMatrix4<T> &CMatrix4<T>::setInverseRotationDegrees(const vector3d<T> &rotation)
|
|
||||||
{
|
|
||||||
return setInverseRotationRadians(rotation * core::DEGTORAD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -841,91 +782,60 @@ inline CMatrix4<T> &CMatrix4<T>::setRotationRadians(const vector3d<T> &rotation)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns a rotation which (mostly) works in combination with the given scale
|
|
||||||
/**
|
|
||||||
This code was originally written by by Chev (assuming no scaling back then,
|
|
||||||
we can be blamed for all problems added by regarding scale)
|
|
||||||
*/
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline core::vector3d<T> CMatrix4<T>::getRotationDegrees(const vector3d<T> &scale_) const
|
template <bool degrees>
|
||||||
|
inline vector3d<T> CMatrix4<T>::getRotation(const vector3d<T> &scale_) const
|
||||||
{
|
{
|
||||||
|
// Based on code by Chev
|
||||||
const CMatrix4<T> &mat = *this;
|
const CMatrix4<T> &mat = *this;
|
||||||
const core::vector3d<f64> scale(core::iszero(scale_.X) ? FLT_MAX : scale_.X, core::iszero(scale_.Y) ? FLT_MAX : scale_.Y, core::iszero(scale_.Z) ? FLT_MAX : scale_.Z);
|
const vector3d<f64> scale(iszero(scale_.X) ? FLT_MAX : scale_.X, iszero(scale_.Y) ? FLT_MAX : scale_.Y, iszero(scale_.Z) ? FLT_MAX : scale_.Z);
|
||||||
const core::vector3d<f64> invScale(core::reciprocal(scale.X), core::reciprocal(scale.Y), core::reciprocal(scale.Z));
|
const vector3d<f64> invScale(reciprocal(scale.X), reciprocal(scale.Y), reciprocal(scale.Z));
|
||||||
|
|
||||||
f64 Y = -asin(core::clamp(mat[2] * invScale.X, -1.0, 1.0));
|
f64 a = clamp(mat[2] * invScale.X, -1.0, 1.0);
|
||||||
const f64 C = cos(Y);
|
f64 Y = -asin(a);
|
||||||
Y *= RADTODEG64;
|
|
||||||
|
|
||||||
f64 rotx, roty, X, Z;
|
f64 rotx, roty, X, Z;
|
||||||
|
|
||||||
if (!core::iszero((T)C)) {
|
if (!core::equals(std::abs(a), 1.0)) {
|
||||||
const f64 invC = core::reciprocal(C);
|
// abs(a) = abs(sin(Y)) = 1 <=> cos(Y) = 0
|
||||||
rotx = mat[10] * invC * invScale.Z;
|
rotx = mat[10] * invScale.Z;
|
||||||
roty = mat[6] * invC * invScale.Y;
|
roty = mat[6] * invScale.Y;
|
||||||
X = atan2(roty, rotx) * RADTODEG64;
|
X = atan2(roty, rotx);
|
||||||
rotx = mat[0] * invC * invScale.X;
|
rotx = mat[0] * invScale.X;
|
||||||
roty = mat[1] * invC * invScale.X;
|
roty = mat[1] * invScale.X;
|
||||||
Z = atan2(roty, rotx) * RADTODEG64;
|
Z = atan2(roty, rotx);
|
||||||
} else {
|
} else {
|
||||||
X = 0.0;
|
X = 0.0;
|
||||||
rotx = mat[5] * invScale.Y;
|
rotx = mat[5];
|
||||||
roty = -mat[4] * invScale.Y;
|
roty = -mat[4];
|
||||||
Z = atan2(roty, rotx) * RADTODEG64;
|
Z = atan2(roty, rotx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix values that get below zero
|
if (degrees) {
|
||||||
if (X < 0.0)
|
X *= core::RADTODEG64;
|
||||||
X += 360.0;
|
Y *= core::RADTODEG64;
|
||||||
if (Y < 0.0)
|
Z *= core::RADTODEG64;
|
||||||
Y += 360.0;
|
}
|
||||||
if (Z < 0.0)
|
|
||||||
Z += 360.0;
|
|
||||||
|
|
||||||
return vector3d<T>((T)X, (T)Y, (T)Z);
|
return vector3d<T>((T)X, (T)Y, (T)Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns a rotation that is equivalent to that set by setRotationDegrees().
|
template <class T>
|
||||||
|
inline vector3d<T> CMatrix4<T>::getRotationRadians(const vector3d<T> &scale) const
|
||||||
|
{
|
||||||
|
return getRotation<false>(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline vector3d<T> CMatrix4<T>::getRotationRadians() const
|
||||||
|
{
|
||||||
|
return getRotationRadians(getScale());
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline vector3d<T> CMatrix4<T>::getRotationDegrees() const
|
inline vector3d<T> CMatrix4<T>::getRotationDegrees() const
|
||||||
{
|
{
|
||||||
// Note: Using getScale() here make it look like it could do matrix decomposition.
|
return getRotation<true>(getScale());
|
||||||
// It can't! It works (or should work) as long as rotation doesn't flip the handedness
|
|
||||||
// aka scale swapping 1 or 3 axes. (I think we could catch that as well by comparing
|
|
||||||
// crossproduct of first 2 axes to direction of third axis, but TODO)
|
|
||||||
// And maybe it should also offer the solution for the simple calculation
|
|
||||||
// without regarding scaling as Irrlicht did before 1.7
|
|
||||||
vector3d<T> scale(getScale());
|
|
||||||
|
|
||||||
return getRotationDegrees(scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Sets matrix to rotation matrix of inverse angles given as parameters
|
|
||||||
template <class T>
|
|
||||||
inline CMatrix4<T> &CMatrix4<T>::setInverseRotationRadians(const vector3d<T> &rotation)
|
|
||||||
{
|
|
||||||
f64 cPitch = cos(rotation.X);
|
|
||||||
f64 sPitch = sin(rotation.X);
|
|
||||||
f64 cYaw = cos(rotation.Y);
|
|
||||||
f64 sYaw = sin(rotation.Y);
|
|
||||||
f64 cRoll = cos(rotation.Z);
|
|
||||||
f64 sRoll = sin(rotation.Z);
|
|
||||||
|
|
||||||
M[0] = (T)(cYaw * cRoll);
|
|
||||||
M[4] = (T)(cYaw * sRoll);
|
|
||||||
M[8] = (T)(-sYaw);
|
|
||||||
|
|
||||||
f64 sPitch_sYaw = sPitch * sYaw;
|
|
||||||
f64 cPitch_sYaw = cPitch * sYaw;
|
|
||||||
|
|
||||||
M[1] = (T)(sPitch_sYaw * cRoll - cPitch * sRoll);
|
|
||||||
M[5] = (T)(sPitch_sYaw * sRoll + cPitch * cRoll);
|
|
||||||
M[9] = (T)(sPitch * cYaw);
|
|
||||||
|
|
||||||
M[2] = (T)(cPitch_sYaw * cRoll + sPitch * sRoll);
|
|
||||||
M[6] = (T)(cPitch_sYaw * sRoll - sPitch * cRoll);
|
|
||||||
M[10] = (T)(cPitch * cYaw);
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Sets matrix to rotation matrix defined by axis and angle, assuming LH rotation
|
//! Sets matrix to rotation matrix defined by axis and angle, assuming LH rotation
|
||||||
|
@ -959,8 +869,6 @@ inline CMatrix4<T> &CMatrix4<T>::setRotationAxisRadians(const T &angle, const ve
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
*/
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::makeIdentity()
|
inline CMatrix4<T> &CMatrix4<T>::makeIdentity()
|
||||||
{
|
{
|
||||||
|
@ -1002,77 +910,6 @@ inline bool CMatrix4<T>::isIdentity() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check orthogonality of matrix. */
|
|
||||||
template <class T>
|
|
||||||
inline bool CMatrix4<T>::isOrthogonal() const
|
|
||||||
{
|
|
||||||
T dp = M[0] * M[4] + M[1] * M[5] + M[2] * M[6] + M[3] * M[7];
|
|
||||||
if (!iszero(dp))
|
|
||||||
return false;
|
|
||||||
dp = M[0] * M[8] + M[1] * M[9] + M[2] * M[10] + M[3] * M[11];
|
|
||||||
if (!iszero(dp))
|
|
||||||
return false;
|
|
||||||
dp = M[0] * M[12] + M[1] * M[13] + M[2] * M[14] + M[3] * M[15];
|
|
||||||
if (!iszero(dp))
|
|
||||||
return false;
|
|
||||||
dp = M[4] * M[8] + M[5] * M[9] + M[6] * M[10] + M[7] * M[11];
|
|
||||||
if (!iszero(dp))
|
|
||||||
return false;
|
|
||||||
dp = M[4] * M[12] + M[5] * M[13] + M[6] * M[14] + M[7] * M[15];
|
|
||||||
if (!iszero(dp))
|
|
||||||
return false;
|
|
||||||
dp = M[8] * M[12] + M[9] * M[13] + M[10] * M[14] + M[11] * M[15];
|
|
||||||
return (iszero(dp));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
doesn't solve floating range problems..
|
|
||||||
but takes care on +/- 0 on translation because we are changing it..
|
|
||||||
reducing floating point branches
|
|
||||||
but it needs the floats in memory..
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
inline bool CMatrix4<T>::isIdentity_integer_base() const
|
|
||||||
{
|
|
||||||
if (IR(M[0]) != F32_VALUE_1)
|
|
||||||
return false;
|
|
||||||
if (IR(M[1]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[2]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[3]) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (IR(M[4]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[5]) != F32_VALUE_1)
|
|
||||||
return false;
|
|
||||||
if (IR(M[6]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[7]) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (IR(M[8]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[9]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[10]) != F32_VALUE_1)
|
|
||||||
return false;
|
|
||||||
if (IR(M[11]) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (IR(M[12]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[13]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[13]) != 0)
|
|
||||||
return false;
|
|
||||||
if (IR(M[15]) != F32_VALUE_1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline vector3d<T> CMatrix4<T>::rotateAndScaleVect(const vector3d<T> &v) const
|
inline vector3d<T> CMatrix4<T>::rotateAndScaleVect(const vector3d<T> &v) const
|
||||||
{
|
{
|
||||||
|
@ -1104,7 +941,7 @@ inline vector3d<T> CMatrix4<T>::transformVect(const vector3d<T> &v) const
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void CMatrix4<T>::transformVect(T *out, const core::vector3df &in) const
|
inline void CMatrix4<T>::transformVect(T *out, const vector3df &in) const
|
||||||
{
|
{
|
||||||
out[0] = in.X * M[0] + in.Y * M[4] + in.Z * M[8] + M[12];
|
out[0] = in.X * M[0] + in.Y * M[4] + in.Z * M[8] + M[12];
|
||||||
out[1] = in.X * M[1] + in.Y * M[5] + in.Z * M[9] + M[13];
|
out[1] = in.X * M[1] + in.Y * M[5] + in.Z * M[9] + M[13];
|
||||||
|
@ -1131,7 +968,7 @@ inline void CMatrix4<T>::transformVec4(T *out, const T *in) const
|
||||||
|
|
||||||
//! Transforms a plane by this matrix
|
//! Transforms a plane by this matrix
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void CMatrix4<T>::transformPlane(core::plane3d<f32> &plane) const
|
inline void CMatrix4<T>::transformPlane(plane3d<f32> &plane) const
|
||||||
{
|
{
|
||||||
vector3df member;
|
vector3df member;
|
||||||
// Transform the plane member point, i.e. rotate, translate and scale it.
|
// Transform the plane member point, i.e. rotate, translate and scale it.
|
||||||
|
@ -1145,7 +982,7 @@ inline void CMatrix4<T>::transformPlane(core::plane3d<f32> &plane) const
|
||||||
|
|
||||||
//! Transforms a plane by this matrix
|
//! Transforms a plane by this matrix
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void CMatrix4<T>::transformPlane(const core::plane3d<f32> &in, core::plane3d<f32> &out) const
|
inline void CMatrix4<T>::transformPlane(const plane3d<f32> &in, plane3d<f32> &out) const
|
||||||
{
|
{
|
||||||
out = in;
|
out = in;
|
||||||
transformPlane(out);
|
transformPlane(out);
|
||||||
|
@ -1153,13 +990,8 @@ inline void CMatrix4<T>::transformPlane(const core::plane3d<f32> &in, core::plan
|
||||||
|
|
||||||
//! Transforms a axis aligned bounding box more accurately than transformBox()
|
//! Transforms a axis aligned bounding box more accurately than transformBox()
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void CMatrix4<T>::transformBoxEx(core::aabbox3d<f32> &box) const
|
inline void CMatrix4<T>::transformBoxEx(aabbox3d<f32> &box) const
|
||||||
{
|
{
|
||||||
#if defined(USE_MATRIX_TEST)
|
|
||||||
if (isIdentity())
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const f32 Amin[3] = {box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z};
|
const f32 Amin[3] = {box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z};
|
||||||
const f32 Amax[3] = {box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z};
|
const f32 Amax[3] = {box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z};
|
||||||
|
|
||||||
|
@ -1242,12 +1074,6 @@ inline bool CMatrix4<T>::getInverse(CMatrix4<T> &out) const
|
||||||
/// The inverse is calculated using Cramers rule.
|
/// The inverse is calculated using Cramers rule.
|
||||||
/// If no inverse exists then 'false' is returned.
|
/// If no inverse exists then 'false' is returned.
|
||||||
|
|
||||||
#if defined(USE_MATRIX_TEST)
|
|
||||||
if (this->isIdentity()) {
|
|
||||||
out = *this;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
const CMatrix4<T> &m = *this;
|
const CMatrix4<T> &m = *this;
|
||||||
|
|
||||||
f32 d = (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -
|
f32 d = (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -
|
||||||
|
@ -1257,10 +1083,10 @@ inline bool CMatrix4<T>::getInverse(CMatrix4<T> &out) const
|
||||||
(m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +
|
(m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +
|
||||||
(m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);
|
(m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);
|
||||||
|
|
||||||
if (core::iszero(d, FLT_MIN))
|
if (iszero(d, FLT_MIN))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
d = core::reciprocal(d);
|
d = reciprocal(d);
|
||||||
|
|
||||||
out[0] = d * (m[5] * (m[10] * m[15] - m[11] * m[14]) +
|
out[0] = d * (m[5] * (m[10] * m[15] - m[11] * m[14]) +
|
||||||
m[6] * (m[11] * m[13] - m[9] * m[15]) +
|
m[6] * (m[11] * m[13] - m[9] * m[15]) +
|
||||||
|
@ -1642,7 +1468,7 @@ inline CMatrix4<T> &CMatrix4<T>::buildProjectionMatrixPerspectiveLH(
|
||||||
|
|
||||||
// Builds a matrix that flattens geometry into a plane.
|
// Builds a matrix that flattens geometry into a plane.
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::buildShadowMatrix(const core::vector3df &light, core::plane3df plane, f32 point)
|
inline CMatrix4<T> &CMatrix4<T>::buildShadowMatrix(const vector3df &light, plane3df plane, f32 point)
|
||||||
{
|
{
|
||||||
plane.Normal.normalize();
|
plane.Normal.normalize();
|
||||||
const f32 d = plane.Normal.dotProduct(light);
|
const f32 d = plane.Normal.dotProduct(light);
|
||||||
|
@ -1748,7 +1574,7 @@ inline CMatrix4<T> &CMatrix4<T>::buildCameraLookAtMatrixRH(
|
||||||
|
|
||||||
// creates a new matrix as interpolated matrix from this and the passed one.
|
// creates a new matrix as interpolated matrix from this and the passed one.
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> CMatrix4<T>::interpolate(const core::CMatrix4<T> &b, f32 time) const
|
inline CMatrix4<T> CMatrix4<T>::interpolate(const CMatrix4<T> &b, f32 time) const
|
||||||
{
|
{
|
||||||
CMatrix4<T> mat(EM4CONST_NOTHING);
|
CMatrix4<T> mat(EM4CONST_NOTHING);
|
||||||
|
|
||||||
|
@ -1797,7 +1623,7 @@ inline void CMatrix4<T>::getTransposed(CMatrix4<T> &o) const
|
||||||
|
|
||||||
// used to scale <-1,-1><1,1> to viewport
|
// used to scale <-1,-1><1,1> to viewport
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::buildNDCToDCMatrix(const core::rect<s32> &viewport, f32 zScale)
|
inline CMatrix4<T> &CMatrix4<T>::buildNDCToDCMatrix(const rect<s32> &viewport, f32 zScale)
|
||||||
{
|
{
|
||||||
const f32 scaleX = (viewport.getWidth() - 0.75f) * 0.5f;
|
const f32 scaleX = (viewport.getWidth() - 0.75f) * 0.5f;
|
||||||
const f32 scaleY = -(viewport.getHeight() - 0.75f) * 0.5f;
|
const f32 scaleY = -(viewport.getHeight() - 0.75f) * 0.5f;
|
||||||
|
@ -1808,7 +1634,7 @@ inline CMatrix4<T> &CMatrix4<T>::buildNDCToDCMatrix(const core::rect<s32> &viewp
|
||||||
makeIdentity();
|
makeIdentity();
|
||||||
M[12] = (T)dx;
|
M[12] = (T)dx;
|
||||||
M[13] = (T)dy;
|
M[13] = (T)dy;
|
||||||
return setScale(core::vector3d<T>((T)scaleX, (T)scaleY, (T)zScale));
|
return setScale(vector3d<T>((T)scaleX, (T)scaleY, (T)zScale));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Builds a matrix that rotates from one vector to another
|
//! Builds a matrix that rotates from one vector to another
|
||||||
|
@ -1818,25 +1644,25 @@ inline CMatrix4<T> &CMatrix4<T>::buildNDCToDCMatrix(const core::rect<s32> &viewp
|
||||||
http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm
|
http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::buildRotateFromTo(const core::vector3df &from, const core::vector3df &to)
|
inline CMatrix4<T> &CMatrix4<T>::buildRotateFromTo(const vector3df &from, const vector3df &to)
|
||||||
{
|
{
|
||||||
// unit vectors
|
// unit vectors
|
||||||
core::vector3df f(from);
|
vector3df f(from);
|
||||||
core::vector3df t(to);
|
vector3df t(to);
|
||||||
f.normalize();
|
f.normalize();
|
||||||
t.normalize();
|
t.normalize();
|
||||||
|
|
||||||
// axis multiplication by sin
|
// axis multiplication by sin
|
||||||
core::vector3df vs(t.crossProduct(f));
|
vector3df vs(t.crossProduct(f));
|
||||||
|
|
||||||
// axis of rotation
|
// axis of rotation
|
||||||
core::vector3df v(vs);
|
vector3df v(vs);
|
||||||
v.normalize();
|
v.normalize();
|
||||||
|
|
||||||
// cosine angle
|
// cosine angle
|
||||||
T ca = f.dotProduct(t);
|
T ca = f.dotProduct(t);
|
||||||
|
|
||||||
core::vector3df vt(v * (1 - ca));
|
vector3df vt(v * (1 - ca));
|
||||||
|
|
||||||
M[0] = vt.X * v.X + ca;
|
M[0] = vt.X * v.X + ca;
|
||||||
M[5] = vt.Y * v.Y + ca;
|
M[5] = vt.Y * v.Y + ca;
|
||||||
|
@ -1875,29 +1701,29 @@ inline CMatrix4<T> &CMatrix4<T>::buildRotateFromTo(const core::vector3df &from,
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void CMatrix4<T>::buildAxisAlignedBillboard(
|
inline void CMatrix4<T>::buildAxisAlignedBillboard(
|
||||||
const core::vector3df &camPos,
|
const vector3df &camPos,
|
||||||
const core::vector3df ¢er,
|
const vector3df ¢er,
|
||||||
const core::vector3df &translation,
|
const vector3df &translation,
|
||||||
const core::vector3df &axis,
|
const vector3df &axis,
|
||||||
const core::vector3df &from)
|
const vector3df &from)
|
||||||
{
|
{
|
||||||
// axis of rotation
|
// axis of rotation
|
||||||
core::vector3df up = axis;
|
vector3df up = axis;
|
||||||
up.normalize();
|
up.normalize();
|
||||||
const core::vector3df forward = (camPos - center).normalize();
|
const vector3df forward = (camPos - center).normalize();
|
||||||
const core::vector3df right = up.crossProduct(forward).normalize();
|
const vector3df right = up.crossProduct(forward).normalize();
|
||||||
|
|
||||||
// correct look vector
|
// correct look vector
|
||||||
const core::vector3df look = right.crossProduct(up);
|
const vector3df look = right.crossProduct(up);
|
||||||
|
|
||||||
// rotate from to
|
// rotate from to
|
||||||
// axis multiplication by sin
|
// axis multiplication by sin
|
||||||
const core::vector3df vs = look.crossProduct(from);
|
const vector3df vs = look.crossProduct(from);
|
||||||
|
|
||||||
// cosine angle
|
// cosine angle
|
||||||
const f32 ca = from.dotProduct(look);
|
const f32 ca = from.dotProduct(look);
|
||||||
|
|
||||||
core::vector3df vt(up * (1.f - ca));
|
vector3df vt(up * (1.f - ca));
|
||||||
|
|
||||||
M[0] = static_cast<T>(vt.X * up.X + ca);
|
M[0] = static_cast<T>(vt.X * up.X + ca);
|
||||||
M[5] = static_cast<T>(vt.Y * up.Y + ca);
|
M[5] = static_cast<T>(vt.Y * up.Y + ca);
|
||||||
|
@ -1924,7 +1750,7 @@ inline void CMatrix4<T>::buildAxisAlignedBillboard(
|
||||||
|
|
||||||
//! Builds a combined matrix which translate to a center before rotation and translate afterward
|
//! Builds a combined matrix which translate to a center before rotation and translate afterward
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void CMatrix4<T>::setRotationCenter(const core::vector3df ¢er, const core::vector3df &translation)
|
inline void CMatrix4<T>::setRotationCenter(const vector3df ¢er, const vector3df &translation)
|
||||||
{
|
{
|
||||||
M[12] = -M[0] * center.X - M[4] * center.Y - M[8] * center.Z + (center.X - translation.X);
|
M[12] = -M[0] * center.X - M[4] * center.Y - M[8] * center.Z + (center.X - translation.X);
|
||||||
M[13] = -M[1] * center.X - M[5] * center.Y - M[9] * center.Z + (center.Y - translation.Y);
|
M[13] = -M[1] * center.X - M[5] * center.Y - M[9] * center.Z + (center.Y - translation.Y);
|
||||||
|
@ -1945,9 +1771,9 @@ inline void CMatrix4<T>::setRotationCenter(const core::vector3df ¢er, const
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline CMatrix4<T> &CMatrix4<T>::buildTextureTransform(f32 rotateRad,
|
inline CMatrix4<T> &CMatrix4<T>::buildTextureTransform(f32 rotateRad,
|
||||||
const core::vector2df &rotatecenter,
|
const vector2df &rotatecenter,
|
||||||
const core::vector2df &translate,
|
const vector2df &translate,
|
||||||
const core::vector2df &scale)
|
const vector2df &scale)
|
||||||
{
|
{
|
||||||
const f32 c = cosf(rotateRad);
|
const f32 c = cosf(rotateRad);
|
||||||
const f32 s = sinf(rotateRad);
|
const f32 s = sinf(rotateRad);
|
||||||
|
@ -2052,7 +1878,7 @@ inline CMatrix4<T> &CMatrix4<T>::setM(const T *data)
|
||||||
|
|
||||||
//! Compare two matrices using the equal method
|
//! Compare two matrices using the equal method
|
||||||
template <class T>
|
template <class T>
|
||||||
inline bool CMatrix4<T>::equals(const core::CMatrix4<T> &other, const T tolerance) const
|
inline bool CMatrix4<T>::equals(const CMatrix4<T> &other, const T tolerance) const
|
||||||
{
|
{
|
||||||
for (s32 i = 0; i < 16; ++i)
|
for (s32 i = 0; i < 16; ++i)
|
||||||
if (!core::equals(M[i], other.M[i], tolerance))
|
if (!core::equals(M[i], other.M[i], tolerance))
|
||||||
|
|
|
@ -33,6 +33,12 @@ public:
|
||||||
explicit constexpr vector3d(T n) :
|
explicit constexpr vector3d(T n) :
|
||||||
X(n), Y(n), Z(n) {}
|
X(n), Y(n), Z(n) {}
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
constexpr static vector3d<T> from(const vector3d<U> &other)
|
||||||
|
{
|
||||||
|
return {static_cast<T>(other.X), static_cast<T>(other.Y), static_cast<T>(other.Z)};
|
||||||
|
}
|
||||||
|
|
||||||
// operators
|
// operators
|
||||||
|
|
||||||
vector3d<T> operator-() const { return vector3d<T>(-X, -Y, -Z); }
|
vector3d<T> operator-() const { return vector3d<T>(-X, -Y, -Z); }
|
||||||
|
|
|
@ -619,7 +619,7 @@ void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
|
||||||
|
|
||||||
// Code is slow, needs to be fixed up
|
// Code is slow, needs to be fixed up
|
||||||
|
|
||||||
const core::quaternion RotationStart(PretransitingSave[n].getRotationDegrees() * core::DEGTORAD);
|
const core::quaternion RotationStart(PretransitingSave[n].getRotationRadians());
|
||||||
const core::quaternion RotationEnd(JointChildSceneNodes[n]->getRotation() * core::DEGTORAD);
|
const core::quaternion RotationEnd(JointChildSceneNodes[n]->getRotation() * core::DEGTORAD);
|
||||||
|
|
||||||
core::quaternion QRotation;
|
core::quaternion QRotation;
|
||||||
|
|
|
@ -546,16 +546,6 @@ void SelfType::MeshExtractor::deferAddMesh(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base transformation between left & right handed coordinate systems.
|
|
||||||
// This just inverts the Z axis.
|
|
||||||
static const core::matrix4 leftToRight = core::matrix4(
|
|
||||||
1, 0, 0, 0,
|
|
||||||
0, 1, 0, 0,
|
|
||||||
0, 0, -1, 0,
|
|
||||||
0, 0, 0, 1
|
|
||||||
);
|
|
||||||
static const core::matrix4 rightToLeft = leftToRight;
|
|
||||||
|
|
||||||
static core::matrix4 loadTransform(const tiniergltf::Node::Matrix &m, SkinnedMesh::SJoint *joint)
|
static core::matrix4 loadTransform(const tiniergltf::Node::Matrix &m, SkinnedMesh::SJoint *joint)
|
||||||
{
|
{
|
||||||
// Note: Under the hood, this casts these doubles to floats.
|
// Note: Under the hood, this casts these doubles to floats.
|
||||||
|
@ -570,14 +560,7 @@ static core::matrix4 loadTransform(const tiniergltf::Node::Matrix &m, SkinnedMes
|
||||||
|
|
||||||
auto scale = mat.getScale();
|
auto scale = mat.getScale();
|
||||||
joint->Animatedscale = scale;
|
joint->Animatedscale = scale;
|
||||||
core::matrix4 inverseScale;
|
joint->Animatedrotation = mat.getRotationRadians(scale);
|
||||||
inverseScale.setScale(core::vector3df(
|
|
||||||
scale.X == 0 ? 0 : 1 / scale.X,
|
|
||||||
scale.Y == 0 ? 0 : 1 / scale.Y,
|
|
||||||
scale.Z == 0 ? 0 : 1 / scale.Z));
|
|
||||||
|
|
||||||
core::matrix4 axisNormalizedMat = inverseScale * mat;
|
|
||||||
joint->Animatedrotation = axisNormalizedMat.getRotationDegrees();
|
|
||||||
// Invert the rotation because it is applied using `getMatrix_transposed`,
|
// Invert the rotation because it is applied using `getMatrix_transposed`,
|
||||||
// which again inverts.
|
// which again inverts.
|
||||||
joint->Animatedrotation.makeInverse();
|
joint->Animatedrotation.makeInverse();
|
||||||
|
|
|
@ -308,8 +308,6 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters ¶m) :
|
||||||
if (SDL_Init(flags) < 0) {
|
if (SDL_Init(flags) < 0) {
|
||||||
os::Printer::log("Unable to initialize SDL", SDL_GetError(), ELL_ERROR);
|
os::Printer::log("Unable to initialize SDL", SDL_GetError(), ELL_ERROR);
|
||||||
Close = true;
|
Close = true;
|
||||||
} else {
|
|
||||||
os::Printer::log("SDL initialized", ELL_INFORMATION);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,21 +322,27 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters ¶m) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_VERSION(&Info.version);
|
core::stringc sdlver = "SDL ";
|
||||||
|
{
|
||||||
|
SDL_version v{};
|
||||||
|
SDL_GetVersion(&v);
|
||||||
|
sdlver += v.major;
|
||||||
|
sdlver += ".";
|
||||||
|
sdlver += v.minor;
|
||||||
|
sdlver += ".";
|
||||||
|
sdlver += v.patch;
|
||||||
|
// the SDL team seems to intentionally number sdl2-compat this way:
|
||||||
|
// <https://github.com/libsdl-org/sdl2-compat/tags>
|
||||||
|
if (v.patch >= 50)
|
||||||
|
sdlver += " (compat)";
|
||||||
|
|
||||||
#ifndef _IRR_EMSCRIPTEN_PLATFORM_
|
sdlver += " on ";
|
||||||
SDL_GetWindowWMInfo(Window, &Info);
|
sdlver += SDL_GetPlatform();
|
||||||
#endif //_IRR_EMSCRIPTEN_PLATFORM_
|
}
|
||||||
core::stringc sdlversion = "SDL Version ";
|
|
||||||
sdlversion += Info.version.major;
|
|
||||||
sdlversion += ".";
|
|
||||||
sdlversion += Info.version.minor;
|
|
||||||
sdlversion += ".";
|
|
||||||
sdlversion += Info.version.patch;
|
|
||||||
|
|
||||||
Operator = new COSOperator(sdlversion);
|
Operator = new COSOperator(sdlver);
|
||||||
if (SDLDeviceInstances == 1) {
|
if (SDLDeviceInstances == 1) {
|
||||||
os::Printer::log(sdlversion.c_str(), ELL_INFORMATION);
|
os::Printer::log(sdlver.c_str(), ELL_INFORMATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create cursor control
|
// create cursor control
|
||||||
|
@ -706,6 +710,10 @@ bool CIrrDeviceSDL::run()
|
||||||
irrevent.MouseInput.X = MouseX;
|
irrevent.MouseInput.X = MouseX;
|
||||||
irrevent.MouseInput.Y = MouseY;
|
irrevent.MouseInput.Y = MouseY;
|
||||||
|
|
||||||
|
// wheel y can be 0 if scrolling sideways
|
||||||
|
if (irrevent.MouseInput.Wheel == 0.0f)
|
||||||
|
break;
|
||||||
|
|
||||||
postEventFromUser(irrevent);
|
postEventFromUser(irrevent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1248,15 +1256,6 @@ bool CIrrDeviceSDL::supportsTouchEvents() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Checks whether windowing uses the Wayland protocol.
|
|
||||||
bool CIrrDeviceSDL::isUsingWayland() const
|
|
||||||
{
|
|
||||||
if (!Window)
|
|
||||||
return false;
|
|
||||||
auto *name = SDL_GetCurrentVideoDriver();
|
|
||||||
return name && !strcmp(name, "wayland");
|
|
||||||
}
|
|
||||||
|
|
||||||
//! returns if window is active. if not, nothing need to be drawn
|
//! returns if window is active. if not, nothing need to be drawn
|
||||||
bool CIrrDeviceSDL::isWindowActive() const
|
bool CIrrDeviceSDL::isWindowActive() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,9 +96,6 @@ public:
|
||||||
//! Checks if the Irrlicht device supports touch events.
|
//! Checks if the Irrlicht device supports touch events.
|
||||||
bool supportsTouchEvents() const override;
|
bool supportsTouchEvents() const override;
|
||||||
|
|
||||||
//! Checks whether windowing uses the Wayland protocol.
|
|
||||||
bool isUsingWayland() const override;
|
|
||||||
|
|
||||||
//! Get the position of this window on screen
|
//! Get the position of this window on screen
|
||||||
core::position2di getWindowPosition() override;
|
core::position2di getWindowPosition() override;
|
||||||
|
|
||||||
|
@ -340,7 +337,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
core::array<SKeyMap> KeyMap;
|
core::array<SKeyMap> KeyMap;
|
||||||
SDL_SysWMinfo Info;
|
|
||||||
|
|
||||||
s32 CurrentTouchCount;
|
s32 CurrentTouchCount;
|
||||||
bool IsInBackground;
|
bool IsInBackground;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# When enabling SDL2 by default on macOS, don't forget to change
|
# When enabling SDL2 by default on macOS, don't forget to change
|
||||||
# "NSHighResolutionCapable" to true in "Info.plist".
|
# "NSHighResolutionCapable" to true in "Info.plist".
|
||||||
if(ANDROID)
|
if(NOT APPLE)
|
||||||
set(DEFAULT_SDL2 ON)
|
set(DEFAULT_SDL2 ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -33,6 +33,15 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
|
||||||
elseif(MSVC)
|
elseif(MSVC)
|
||||||
string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " msvcrt.lib") # ???? fuck off
|
string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " msvcrt.lib") # ???? fuck off
|
||||||
|
|
||||||
|
add_compile_definitions(
|
||||||
|
# Suppress some useless warnings
|
||||||
|
_CRT_SECURE_NO_DEPRECATE
|
||||||
|
# Get M_PI to work
|
||||||
|
_USE_MATH_DEFINES
|
||||||
|
# Don't define min/max macros in minwindef.h
|
||||||
|
NOMINMAX
|
||||||
|
)
|
||||||
|
|
||||||
add_compile_options(/Zl)
|
add_compile_options(/Zl)
|
||||||
|
|
||||||
# Enable SSE for floating point math on 32-bit x86 by default
|
# Enable SSE for floating point math on 32-bit x86 by default
|
||||||
|
|
|
@ -21,7 +21,7 @@ CMeshSceneNode::CMeshSceneNode(IMesh *mesh, ISceneNode *parent, ISceneManager *m
|
||||||
const core::vector3df &scale) :
|
const core::vector3df &scale) :
|
||||||
IMeshSceneNode(parent, mgr, id, position, rotation, scale),
|
IMeshSceneNode(parent, mgr, id, position, rotation, scale),
|
||||||
Mesh(0),
|
Mesh(0),
|
||||||
PassCount(0), ReadOnlyMaterials(false)
|
PassCount(0), SharedMaterials(false)
|
||||||
{
|
{
|
||||||
setMesh(mesh);
|
setMesh(mesh);
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ void CMeshSceneNode::OnRegisterSceneNode()
|
||||||
int solidCount = 0;
|
int solidCount = 0;
|
||||||
|
|
||||||
// count transparent and solid materials in this scene node
|
// count transparent and solid materials in this scene node
|
||||||
const u32 numMaterials = ReadOnlyMaterials ? Mesh->getMeshBufferCount() : Materials.size();
|
const u32 numMaterials = SharedMaterials ? Mesh->getMeshBufferCount() : Materials.size();
|
||||||
for (u32 i = 0; i < numMaterials; ++i) {
|
for (u32 i = 0; i < numMaterials; ++i) {
|
||||||
const video::SMaterial &material = ReadOnlyMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
|
const auto &material = SharedMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
|
||||||
|
|
||||||
if (driver->needsTransparentRenderPass(material))
|
if (driver->needsTransparentRenderPass(material))
|
||||||
++transparentCount;
|
++transparentCount;
|
||||||
|
@ -93,7 +93,7 @@ void CMeshSceneNode::render()
|
||||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
||||||
scene::IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
scene::IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
||||||
if (mb) {
|
if (mb) {
|
||||||
const video::SMaterial &material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
const auto &material = SharedMaterials ? mb->getMaterial() : Materials[i];
|
||||||
|
|
||||||
const bool transparent = driver->needsTransparentRenderPass(material);
|
const bool transparent = driver->needsTransparentRenderPass(material);
|
||||||
|
|
||||||
|
@ -164,14 +164,10 @@ const core::aabbox3d<f32> &CMeshSceneNode::getBoundingBox() const
|
||||||
|
|
||||||
//! returns the material based on the zero based index i. To get the amount
|
//! returns the material based on the zero based index i. To get the amount
|
||||||
//! of materials used by this scene node, use getMaterialCount().
|
//! of materials used by this scene node, use getMaterialCount().
|
||||||
//! This function is needed for inserting the node into the scene hierarchy on a
|
|
||||||
//! optimal position for minimizing renderstate changes, but can also be used
|
|
||||||
//! to directly modify the material of a scene node.
|
|
||||||
video::SMaterial &CMeshSceneNode::getMaterial(u32 i)
|
video::SMaterial &CMeshSceneNode::getMaterial(u32 i)
|
||||||
{
|
{
|
||||||
if (Mesh && ReadOnlyMaterials && i < Mesh->getMeshBufferCount()) {
|
if (Mesh && SharedMaterials && i < Mesh->getMeshBufferCount()) {
|
||||||
ReadOnlyMaterial = Mesh->getMeshBuffer(i)->getMaterial();
|
return Mesh->getMeshBuffer(i)->getMaterial();
|
||||||
return ReadOnlyMaterial;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= Materials.size())
|
if (i >= Materials.size())
|
||||||
|
@ -183,7 +179,7 @@ video::SMaterial &CMeshSceneNode::getMaterial(u32 i)
|
||||||
//! returns amount of materials used by this scene node.
|
//! returns amount of materials used by this scene node.
|
||||||
u32 CMeshSceneNode::getMaterialCount() const
|
u32 CMeshSceneNode::getMaterialCount() const
|
||||||
{
|
{
|
||||||
if (Mesh && ReadOnlyMaterials)
|
if (Mesh && SharedMaterials)
|
||||||
return Mesh->getMeshBufferCount();
|
return Mesh->getMeshBufferCount();
|
||||||
|
|
||||||
return Materials.size();
|
return Materials.size();
|
||||||
|
@ -206,9 +202,10 @@ void CMeshSceneNode::copyMaterials()
|
||||||
{
|
{
|
||||||
Materials.clear();
|
Materials.clear();
|
||||||
|
|
||||||
if (Mesh) {
|
if (Mesh && !SharedMaterials) {
|
||||||
video::SMaterial mat;
|
video::SMaterial mat;
|
||||||
|
|
||||||
|
Materials.reserve(Mesh->getMeshBufferCount());
|
||||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
||||||
IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
||||||
if (mb)
|
if (mb)
|
||||||
|
@ -222,15 +219,18 @@ void CMeshSceneNode::copyMaterials()
|
||||||
//! 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 causing all mesh scene nodes
|
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
|
||||||
referencing this mesh to change too. */
|
referencing this mesh to change too. */
|
||||||
void CMeshSceneNode::setReadOnlyMaterials(bool readonly)
|
void CMeshSceneNode::setSharedMaterials(bool shared)
|
||||||
{
|
{
|
||||||
ReadOnlyMaterials = readonly;
|
if (SharedMaterials != shared) {
|
||||||
|
SharedMaterials = shared;
|
||||||
|
copyMaterials();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
||||||
bool CMeshSceneNode::isReadOnlyMaterials() const
|
bool CMeshSceneNode::isSharedMaterials() const
|
||||||
{
|
{
|
||||||
return ReadOnlyMaterials;
|
return SharedMaterials;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Creates a clone of this scene node and its children.
|
//! Creates a clone of this scene node and its children.
|
||||||
|
@ -245,7 +245,7 @@ ISceneNode *CMeshSceneNode::clone(ISceneNode *newParent, ISceneManager *newManag
|
||||||
newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale);
|
newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale);
|
||||||
|
|
||||||
nb->cloneMembers(this, newManager);
|
nb->cloneMembers(this, newManager);
|
||||||
nb->ReadOnlyMaterials = ReadOnlyMaterials;
|
nb->SharedMaterials = SharedMaterials;
|
||||||
nb->Materials = Materials;
|
nb->Materials = Materials;
|
||||||
|
|
||||||
if (newParent)
|
if (newParent)
|
||||||
|
|
|
@ -52,13 +52,16 @@ public:
|
||||||
//! Returns the current mesh
|
//! Returns the current mesh
|
||||||
IMesh *getMesh(void) override { return Mesh; }
|
IMesh *getMesh(void) override { return Mesh; }
|
||||||
|
|
||||||
//! 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 directly.
|
||||||
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
|
/** In this way it is possible to change the materials of a mesh
|
||||||
referencing this mesh to change too. */
|
causing all mesh scene nodes referencing this mesh to change, too.
|
||||||
void setReadOnlyMaterials(bool readonly) override;
|
\param shared Flag if the materials shall be shared. */
|
||||||
|
void setSharedMaterials(bool shared) override;
|
||||||
|
|
||||||
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
//! Check if the scene node does not copy the materials of the mesh but uses them directly.
|
||||||
bool isReadOnlyMaterials() const override;
|
/** This flag can be set by setSharedMaterials().
|
||||||
|
\return Whether the materials are shared. */
|
||||||
|
bool isSharedMaterials() const override;
|
||||||
|
|
||||||
//! Creates a clone of this scene node and its children.
|
//! Creates a clone of this scene node and its children.
|
||||||
ISceneNode *clone(ISceneNode *newParent = 0, ISceneManager *newManager = 0) override;
|
ISceneNode *clone(ISceneNode *newParent = 0, ISceneManager *newManager = 0) override;
|
||||||
|
@ -71,14 +74,13 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void copyMaterials();
|
void copyMaterials();
|
||||||
|
|
||||||
core::array<video::SMaterial> Materials;
|
std::vector<video::SMaterial> Materials;
|
||||||
core::aabbox3d<f32> Box{{0, 0, 0}};
|
core::aabbox3d<f32> Box{{0, 0, 0}};
|
||||||
video::SMaterial ReadOnlyMaterial;
|
|
||||||
|
|
||||||
IMesh *Mesh;
|
IMesh *Mesh;
|
||||||
|
|
||||||
s32 PassCount;
|
s32 PassCount;
|
||||||
bool ReadOnlyMaterials;
|
bool SharedMaterials;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -1455,9 +1455,9 @@ void CNullDriver::setMaterialRendererName(u32 idx, const char *name)
|
||||||
void CNullDriver::swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames)
|
void CNullDriver::swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames)
|
||||||
{
|
{
|
||||||
if (idx1 < MaterialRenderers.size() && idx2 < MaterialRenderers.size()) {
|
if (idx1 < MaterialRenderers.size() && idx2 < MaterialRenderers.size()) {
|
||||||
irr::core::swap(MaterialRenderers[idx1].Renderer, MaterialRenderers[idx2].Renderer);
|
std::swap(MaterialRenderers[idx1].Renderer, MaterialRenderers[idx2].Renderer);
|
||||||
if (swapNames)
|
if (swapNames)
|
||||||
irr::core::swap(MaterialRenderers[idx1].Name, MaterialRenderers[idx2].Name);
|
std::swap(MaterialRenderers[idx1].Name, MaterialRenderers[idx2].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1526,8 +1526,6 @@ bool CXMeshFileLoader::parseDataObjectAnimationKey(SkinnedMesh::SJoint *joint)
|
||||||
os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
|
os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// core::vector3df rotation = mat.getRotationDegrees();
|
|
||||||
|
|
||||||
AnimatedMesh->addRotationKey(joint, time, core::quaternion(mat.getTransposed()));
|
AnimatedMesh->addRotationKey(joint, time, core::quaternion(mat.getTransposed()));
|
||||||
AnimatedMesh->addPositionKey(joint, time, mat.getTranslation());
|
AnimatedMesh->addPositionKey(joint, time, mat.getTranslation());
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ const matrix4 IdentityMatrix(matrix4::EM4CONST_IDENTITY);
|
||||||
|
|
||||||
namespace video
|
namespace video
|
||||||
{
|
{
|
||||||
SMaterial IdentityMaterial;
|
const SMaterial IdentityMaterial;
|
||||||
|
|
||||||
extern "C" IRRLICHT_API bool IRRCALLCONV isDriverSupported(E_DRIVER_TYPE driver)
|
extern "C" IRRLICHT_API bool IRRCALLCONV isDriverSupported(E_DRIVER_TYPE driver)
|
||||||
{
|
{
|
||||||
|
|
|
@ -149,6 +149,6 @@
|
||||||
<update_contact>celeron55@gmail.com</update_contact>
|
<update_contact>celeron55@gmail.com</update_contact>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
<release date="2024-11-10" version="5.10.0"/>
|
<release date="2025-02-14" version="5.11.0"/>
|
||||||
</releases>
|
</releases>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -3,9 +3,9 @@ msgstr ""
|
||||||
"Project-Id-Version: minetest\n"
|
"Project-Id-Version: minetest\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
||||||
"PO-Revision-Date: 2025-01-27 06:02+0000\n"
|
"PO-Revision-Date: 2025-02-11 02:02+0000\n"
|
||||||
"Last-Translator: 109247019824 "
|
"Last-Translator: 109247019824 <109247019824@users.noreply.hosted.weblate.org>"
|
||||||
"<109247019824@users.noreply.hosted.weblate.org>\n"
|
"\n"
|
||||||
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/minetest/"
|
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/minetest/"
|
||||||
"minetest/bg/>\n"
|
"minetest/bg/>\n"
|
||||||
"Language: bg\n"
|
"Language: bg\n"
|
||||||
|
@ -264,13 +264,12 @@ msgid "Show technical names"
|
||||||
msgstr "Технически наименования"
|
msgstr "Технически наименования"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Touchscreen layout"
|
msgid "Touchscreen layout"
|
||||||
msgstr "Сензорен екран"
|
msgstr "Подредба на сензорния екран"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
msgid "pause_menu"
|
msgid "pause_menu"
|
||||||
msgstr ""
|
msgstr "pause_menu"
|
||||||
|
|
||||||
#: builtin/common/settings/settingtypes.lua
|
#: builtin/common/settings/settingtypes.lua
|
||||||
msgid "Client Mods"
|
msgid "Client Mods"
|
||||||
|
@ -612,6 +611,8 @@ msgid ""
|
||||||
"This is the list of clients connected to\n"
|
"This is the list of clients connected to\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Това е списък на клиентите свързани с\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua
|
#: builtin/mainmenu/dlg_config_world.lua
|
||||||
msgid "(Enabled, has error)"
|
msgid "(Enabled, has error)"
|
||||||
|
|
180
po/de/luanti.po
180
po/de/luanti.po
|
@ -3,7 +3,7 @@ msgstr ""
|
||||||
"Project-Id-Version: German (Minetest)\n"
|
"Project-Id-Version: German (Minetest)\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
||||||
"PO-Revision-Date: 2025-02-05 11:03+0000\n"
|
"PO-Revision-Date: 2025-02-11 02:02+0000\n"
|
||||||
"Last-Translator: Wuzzy <Wuzzy@disroot.org>\n"
|
"Last-Translator: Wuzzy <Wuzzy@disroot.org>\n"
|
||||||
"Language-Team: German <https://hosted.weblate.org/projects/minetest/minetest/"
|
"Language-Team: German <https://hosted.weblate.org/projects/minetest/minetest/"
|
||||||
"de/>\n"
|
"de/>\n"
|
||||||
|
@ -263,14 +263,12 @@ msgid "Show technical names"
|
||||||
msgstr "Technische Namen zeigen"
|
msgstr "Technische Namen zeigen"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Touchscreen layout"
|
msgid "Touchscreen layout"
|
||||||
msgstr "Touchscreen"
|
msgstr "Touchscreen-Layout"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "pause_menu"
|
msgid "pause_menu"
|
||||||
msgstr "Bildwiederholrate im Pausenmenü"
|
msgstr "pause_menu"
|
||||||
|
|
||||||
#: builtin/common/settings/settingtypes.lua
|
#: builtin/common/settings/settingtypes.lua
|
||||||
msgid "Client Mods"
|
msgid "Client Mods"
|
||||||
|
@ -436,7 +434,7 @@ msgstr "Mods"
|
||||||
#: builtin/mainmenu/content/dlg_contentdb.lua
|
#: builtin/mainmenu/content/dlg_contentdb.lua
|
||||||
#: builtin/mainmenu/content/dlg_package.lua
|
#: builtin/mainmenu/content/dlg_package.lua
|
||||||
msgid "No packages could be retrieved"
|
msgid "No packages could be retrieved"
|
||||||
msgstr "Es konnten keine Pakete abgerufen werden"
|
msgstr "Es konnten keine Pakete empfangen werden"
|
||||||
|
|
||||||
#: builtin/mainmenu/content/dlg_contentdb.lua
|
#: builtin/mainmenu/content/dlg_contentdb.lua
|
||||||
msgid "No updates"
|
msgid "No updates"
|
||||||
|
@ -610,6 +608,8 @@ msgid ""
|
||||||
"This is the list of clients connected to\n"
|
"This is the list of clients connected to\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Dies ist die Liste der Clients, die zu\n"
|
||||||
|
"$1 verbunden sind"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua
|
#: builtin/mainmenu/dlg_config_world.lua
|
||||||
msgid "(Enabled, has error)"
|
msgid "(Enabled, has error)"
|
||||||
|
@ -975,25 +975,24 @@ msgstr ""
|
||||||
"der jede Umbennenung hier überschreiben wird."
|
"der jede Umbennenung hier überschreiben wird."
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Expand all"
|
msgid "Expand all"
|
||||||
msgstr "Alle aktivieren"
|
msgstr "Alle ausklappen"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "Group by prefix"
|
msgid "Group by prefix"
|
||||||
msgstr ""
|
msgstr "Nach Präfix gruppieren"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses a game called $2 and the following mods:"
|
msgid "The $1 server uses a game called $2 and the following mods:"
|
||||||
msgstr ""
|
msgstr "Der Server $1 nutzt ein Spiel namens $2 und die folgenden Mods:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses the following mods:"
|
msgid "The $1 server uses the following mods:"
|
||||||
msgstr ""
|
msgstr "Der Server $1 nutzt folgende Mods:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_version_info.lua
|
#: builtin/mainmenu/dlg_version_info.lua
|
||||||
msgid "A new $1 version is available"
|
msgid "A new $1 version is available"
|
||||||
msgstr "Eine neue $1-Version ist verfügbar"
|
msgstr "Eine neue Version von $1 ist verfügbar"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_version_info.lua
|
#: builtin/mainmenu/dlg_version_info.lua
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -1203,20 +1202,20 @@ msgstr ""
|
||||||
"Sie müssen ein Spiel installieren, bevor Sie eine Welt erstellen können."
|
"Sie müssen ein Spiel installieren, bevor Sie eine Welt erstellen können."
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Add favorite"
|
msgid "Add favorite"
|
||||||
msgstr "Favorit entfernen"
|
msgstr "Favorit hinzufügen"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Adresse"
|
msgstr "Adresse"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Clients:\n"
|
"Clients:\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr "Client"
|
msgstr ""
|
||||||
|
"Clients:\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Creative mode"
|
msgid "Creative mode"
|
||||||
|
@ -1232,9 +1231,8 @@ msgid "Favorites"
|
||||||
msgstr "Favoriten"
|
msgstr "Favoriten"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Game: $1"
|
msgid "Game: $1"
|
||||||
msgstr "Spiel"
|
msgstr "Spiel: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Incompatible Servers"
|
msgid "Incompatible Servers"
|
||||||
|
@ -1249,14 +1247,12 @@ msgid "Login"
|
||||||
msgstr "Einloggen"
|
msgstr "Einloggen"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Number of mods: $1"
|
msgid "Number of mods: $1"
|
||||||
msgstr "Anzahl der Erzeugerthreads"
|
msgstr "Anzahl der Mods: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Open server website"
|
msgid "Open server website"
|
||||||
msgstr "Taktung dedizierter Server"
|
msgstr "Server-Webseite besuchen"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Ping"
|
msgid "Ping"
|
||||||
|
@ -1269,6 +1265,10 @@ msgid ""
|
||||||
"mod:<name>\n"
|
"mod:<name>\n"
|
||||||
"player:<name>"
|
"player:<name>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Mögliche Filter\n"
|
||||||
|
"game:<Name>\n"
|
||||||
|
"mod:<Name>\n"
|
||||||
|
"player:<Name>"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Public Servers"
|
msgid "Public Servers"
|
||||||
|
@ -1364,9 +1364,8 @@ msgid "Access denied. Reason: %s"
|
||||||
msgstr "Zugriff verweigert. Grund: %s"
|
msgstr "Zugriff verweigert. Grund: %s"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "All debug info hidden"
|
msgid "All debug info hidden"
|
||||||
msgstr "Debug-Infos angezeigt"
|
msgstr "Alle Debug-Infos verborgen"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Automatic forward disabled"
|
msgid "Automatic forward disabled"
|
||||||
|
@ -1390,7 +1389,7 @@ msgstr "Blockgrenzen für Blöcke in Nähe angezeigt"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Bounding boxes shown"
|
msgid "Bounding boxes shown"
|
||||||
msgstr ""
|
msgstr "Grenzboxen angezeigt"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Camera update disabled"
|
msgid "Camera update disabled"
|
||||||
|
@ -1632,9 +1631,8 @@ msgid "Volume changed to %d%%"
|
||||||
msgstr "Lautstärke auf %d%% gesetzt"
|
msgstr "Lautstärke auf %d%% gesetzt"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Wireframe not supported by video driver"
|
msgid "Wireframe not supported by video driver"
|
||||||
msgstr "Shader sind aktiviert, aber GLSL wird vom Treiber nicht unterstützt."
|
msgstr "Drahtmodell vom Treiber nicht unterstützt"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Wireframe shown"
|
msgid "Wireframe shown"
|
||||||
|
@ -2067,9 +2065,8 @@ msgid "Failed to compile the \"%s\" shader."
|
||||||
msgstr "Fehler beim Kompilieren des „%s“-Shaders."
|
msgstr "Fehler beim Kompilieren des „%s“-Shaders."
|
||||||
|
|
||||||
#: src/client/shader.cpp
|
#: src/client/shader.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "GLSL is not supported by the driver"
|
msgid "GLSL is not supported by the driver"
|
||||||
msgstr "Shader sind aktiviert, aber GLSL wird vom Treiber nicht unterstützt."
|
msgstr "GLSL wird vom Treiber nicht unterstützt"
|
||||||
|
|
||||||
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
||||||
#: src/content/mod_configuration.cpp
|
#: src/content/mod_configuration.cpp
|
||||||
|
@ -2306,35 +2303,32 @@ msgid "Sound Volume: %d%%"
|
||||||
msgstr "Tonlautstärke: %d%%"
|
msgstr "Tonlautstärke: %d%%"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Add button"
|
msgid "Add button"
|
||||||
msgstr "Mittlere Taste"
|
msgstr "Button hinzufügen"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Done"
|
msgid "Done"
|
||||||
msgstr "Fertig!"
|
msgstr "Fertig"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Entfernter Server"
|
msgstr "Entfernen"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr "Zurücksetzen"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Start dragging a button to add. Tap outside to cancel."
|
msgid "Start dragging a button to add. Tap outside to cancel."
|
||||||
msgstr ""
|
msgstr "Button ziehen zum Hinzufügen. Außerhalb antippen zum Abbrechen."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap a button to select it. Drag a button to move it."
|
msgid "Tap a button to select it. Drag a button to move it."
|
||||||
msgstr ""
|
msgstr "Button antippen zum Auswählen. Button ziehen zum Verschieben."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap outside to deselect."
|
msgid "Tap outside to deselect."
|
||||||
msgstr ""
|
msgstr "Außerhalb antippen zum Abwählen."
|
||||||
|
|
||||||
#: src/gui/touchscreenlayout.cpp
|
#: src/gui/touchscreenlayout.cpp
|
||||||
msgid "Joystick"
|
msgid "Joystick"
|
||||||
|
@ -2576,7 +2570,6 @@ msgid "3D noise that determines number of dungeons per mapchunk."
|
||||||
msgstr "3-D-Rauschen, welches die Anzahl der Verliese je Mapchunk festlegt."
|
msgstr "3-D-Rauschen, welches die Anzahl der Verliese je Mapchunk festlegt."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"3D support.\n"
|
"3D support.\n"
|
||||||
"Currently supported:\n"
|
"Currently supported:\n"
|
||||||
|
@ -2595,9 +2588,7 @@ msgstr ""
|
||||||
"zeilenbasierte Polarisation.\n"
|
"zeilenbasierte Polarisation.\n"
|
||||||
"- topbottom: Bildschirm horizontal teilen.\n"
|
"- topbottom: Bildschirm horizontal teilen.\n"
|
||||||
"- sidebyside: Bildschirm vertikal teilen.\n"
|
"- sidebyside: Bildschirm vertikal teilen.\n"
|
||||||
"- crossview: Schieläugiges 3-D\n"
|
"- crossview: Schieläugiges 3-D"
|
||||||
"Beachten Sie, dass der „interlaced“-Modus erfordert, dass Shader aktiviert "
|
|
||||||
"sind."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -2692,11 +2683,13 @@ msgid ""
|
||||||
"All mesh buffers with less than this number of vertices will be merged\n"
|
"All mesh buffers with less than this number of vertices will be merged\n"
|
||||||
"during map rendering. This improves rendering performance."
|
"during map rendering. This improves rendering performance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Alle Mesh-Puffer, die weniger als diese Anzahl Punkte haben, werden während\n"
|
||||||
|
"des Renderns der Karte zusammengeführt. Dies verbessert die Performanz\n"
|
||||||
|
"des Renderns."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Allow clouds to look 3D instead of flat."
|
msgid "Allow clouds to look 3D instead of flat."
|
||||||
msgstr "Wolken blockförmig statt flach aussehen lassen."
|
msgstr "Erlaubt, dass Wolken ein 3-D-Aussehen statt ein flaches Aussehen haben."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Allows liquids to be translucent."
|
msgid "Allows liquids to be translucent."
|
||||||
|
@ -3107,7 +3100,7 @@ msgstr "Wolken im Menü"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Color depth for post-processing texture"
|
msgid "Color depth for post-processing texture"
|
||||||
msgstr ""
|
msgstr "Farbtiefe für Nachbearbeitungstextur"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Colored fog"
|
msgid "Colored fog"
|
||||||
|
@ -3127,7 +3120,6 @@ msgstr ""
|
||||||
"für Details."
|
"für Details."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Comma-separated list of flags to hide in the content repository.\n"
|
"Comma-separated list of flags to hide in the content repository.\n"
|
||||||
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
||||||
|
@ -3145,7 +3137,7 @@ msgstr ""
|
||||||
"Sie können auch Inhaltseinstufungen festlegen.\n"
|
"Sie können auch Inhaltseinstufungen festlegen.\n"
|
||||||
"Diese Flags sind von Luanti-Versionen unabhängig,\n"
|
"Diese Flags sind von Luanti-Versionen unabhängig,\n"
|
||||||
"für eine vollständige Liste gehen Sie auf:\n"
|
"für eine vollständige Liste gehen Sie auf:\n"
|
||||||
"https://content.minetest.net/help/content_flags/"
|
"https://content.luanti.org/help/content_flags/"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -3316,6 +3308,11 @@ msgid ""
|
||||||
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
||||||
"require more than 8 bits to work."
|
"require more than 8 bits to work."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Die Farbtiefe der Textur, die für die Nachbearbeitungs-Pipeline benutzt "
|
||||||
|
"wird, festlegen.\n"
|
||||||
|
"Wird der Wert verringert, kann dies die Performanz verbessern, aber einige "
|
||||||
|
"Effekte (z.B. Debanding)\n"
|
||||||
|
"brauchen mehr als 8 Bit, um zu funktionieren."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dedicated server step"
|
msgid "Dedicated server step"
|
||||||
|
@ -3544,6 +3541,10 @@ msgid ""
|
||||||
"situations\n"
|
"situations\n"
|
||||||
"where transparency sorting would be very slow otherwise."
|
"where transparency sorting would be very slow otherwise."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Transparenzsortierte Dreiecke nach ihren Meshpuffern gruppiert zeichnen.\n"
|
||||||
|
"Dies macht die Transparenzsortierung zwischen Meshpuffern kaputt, aber "
|
||||||
|
"vermeidet\n"
|
||||||
|
"Situationen, wo die Transparenzsortierung sonst sehr langsam wäre."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dump the mapgen debug information."
|
msgid "Dump the mapgen debug information."
|
||||||
|
@ -3628,14 +3629,12 @@ msgstr ""
|
||||||
"Verhalten des menschlichen Auges simuliert."
|
"Verhalten des menschlichen Auges simuliert."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable colored shadows for transculent nodes.\n"
|
"Enable colored shadows for transculent nodes.\n"
|
||||||
"This is expensive."
|
"This is expensive."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Aktiviert gefärbte Schatten. \n"
|
"Aktiviert gefärbte Schatten für transluzente Blöcke.\n"
|
||||||
"Falls aktiv, werden transluzente Blöcke gefärbte Schatten werfen. Dies ist "
|
"Dies ist rechenintensiv."
|
||||||
"rechenintensiv."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable console window"
|
msgid "Enable console window"
|
||||||
|
@ -3721,14 +3720,12 @@ msgstr ""
|
||||||
"1.0 für den Standardwert, 2.0 für doppelte Geschwindigkeit."
|
"1.0 für den Standardwert, 2.0 für doppelte Geschwindigkeit."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable/disable running an IPv6 server.\n"
|
"Enable/disable running an IPv6 server.\n"
|
||||||
"Ignored if bind_address is set."
|
"Ignored if bind_address is set."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Server als IPv6 laufen lassen (oder nicht).\n"
|
"Server als IPv6 laufen lassen (oder nicht).\n"
|
||||||
"Wird ignoriert, falls bind_address gesetzt ist.\n"
|
"Wird ignoriert, falls bind_address gesetzt ist."
|
||||||
"Dafür muss außerdem enable_ipv6 aktiviert sein."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -4399,15 +4396,15 @@ msgstr ""
|
||||||
"ihr Passwort zu ein leeres Passwort ändern."
|
"ihr Passwort zu ein leeres Passwort ändern."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"If enabled, server account registration is separate from login in the UI.\n"
|
"If enabled, server account registration is separate from login in the UI.\n"
|
||||||
"If disabled, connecting to a server will automatically register a new "
|
"If disabled, connecting to a server will automatically register a new "
|
||||||
"account."
|
"account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Falls aktiviert, wird die Kontoregistrierung vom Einloggen in der "
|
"Falls aktiviert, wird die Serverkontoregistrierung in der Benutzeroberfläche "
|
||||||
"Benutzeroberfläche getrennt behandelt.\n"
|
"getrennt vom Einloggen behandelt.\n"
|
||||||
"Falls deaktiviert, werden neue Konten beim Einloggen automatisch registriert."
|
"Falls deaktiviert, werden neue Konten beim Verbindungsaufbau zu einem Server "
|
||||||
|
"automatisch registriert."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5313,7 +5310,7 @@ msgstr "Untergrenze der zufälligen Anzahl kleiner Höhlen je Mapchunk."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Minimum vertex count for mesh buffers"
|
msgid "Minimum vertex count for mesh buffers"
|
||||||
msgstr ""
|
msgstr "Minimale Punktanzahl für Meshpuffer"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Mipmapping"
|
msgid "Mipmapping"
|
||||||
|
@ -5409,16 +5406,15 @@ msgstr ""
|
||||||
"- Die optionalen Schwebeländer von v7 (standardmäßig deaktiviert)."
|
"- Die optionalen Schwebeländer von v7 (standardmäßig deaktiviert)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Name of the player.\n"
|
"Name of the player.\n"
|
||||||
"When running a server, a client connecting with this name is admin.\n"
|
"When running a server, a client connecting with this name is admin.\n"
|
||||||
"When starting from the main menu, this is overridden."
|
"When starting from the main menu, this is overridden."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Name des Spielers.\n"
|
"Name des Spielers.\n"
|
||||||
"Wenn ein Server gestartet wird, werden Clients mit diesem Namen zu "
|
"Wenn ein Server gestartet wird, wird ein Client mit diesem Namen zum "
|
||||||
"Administratoren.\n"
|
"Administrator.\n"
|
||||||
"Wird vom Hauptmenü aus gestartet, wird diese Einstellung überschrieben."
|
"Wenn vom Hauptmenü aus gestartet, wird diese Einstellung überschrieben."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5938,7 +5934,6 @@ msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
msgstr "Siehe https://www.sqlite.org/pragma.html#pragma_synchronous"
|
msgstr "Siehe https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select the antialiasing method to apply.\n"
|
"Select the antialiasing method to apply.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -5965,20 +5960,22 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"* None – Keine Kantenglättung (Standard)\n"
|
"* None – Keine Kantenglättung (Standard)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* FSAA – Von der Hardware bereitgestellte Vollbildkantenglättung (nicht\n"
|
"* FSAA – Von der Hardware bereitgestellte Vollbildkantenglättung\n"
|
||||||
"kompatibel mit Nachbearbeitung und Unterabtastung), auch bekannt\n"
|
"Auch bekannt als „Multi-Sample Antialiasing“ (MSAA)\n"
|
||||||
"als Multi-Sample Antialiasing (MSAA). Glättet Blockkanten aus, "
|
"Glättet Blockkanten, aber hat keine Auswirkung auf das Innere von Texturen.\n"
|
||||||
"beeinträchtigt\n"
|
|
||||||
"aber nicht die Innenseiten der Texturen.\n"
|
|
||||||
"Um diese Option zu ändern, ist ein Neustart erforderlich.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"* FXAA – Schnelle annähende Kantenglättung (benötigt Shader).\n"
|
"Wenn die Nachbearbeitung deaktiviert ist, benötigt das Ändern von FSAA\n"
|
||||||
|
"einen Neustart. Außerdem wird, wenn die Nachbearbeitung deaktiviert ist,\n"
|
||||||
|
"FSAA nicht zusammen mit einer Unterabtastung oder einer\n"
|
||||||
|
"Nicht-Standard-„3d_mode“-Einstellung funktionieren.\n"
|
||||||
|
"\n"
|
||||||
|
"* FXAA – Schnelle annähende Kantenglättung\n"
|
||||||
"Wendet einen Nachbearbeitungsfilter an, um kontrastreiche Kanten zu "
|
"Wendet einen Nachbearbeitungsfilter an, um kontrastreiche Kanten zu "
|
||||||
"erkennen\n"
|
"erkennen\n"
|
||||||
"und zu glätten. Bietet eine Balance zwischen Geschwindigkeit und "
|
"und zu glätten. Bietet eine Balance zwischen Geschwindigkeit und "
|
||||||
"Bildqualität.\n"
|
"Bildqualität.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* SSAA – Super-Sampling-Kantenglättung (benötigt Shader).\n"
|
"* SSAA – Super-Sampling-Kantenglättung\n"
|
||||||
"Rendert ein hochauflösendes Bild der Szene, dann skaliert es herunter, um\n"
|
"Rendert ein hochauflösendes Bild der Szene, dann skaliert es herunter, um\n"
|
||||||
"die Aliasing-Effekte zu reduzieren. Dies ist die langsamste und genaueste "
|
"die Aliasing-Effekte zu reduzieren. Dies ist die langsamste und genaueste "
|
||||||
"Methode."
|
"Methode."
|
||||||
|
@ -6419,7 +6416,6 @@ msgstr ""
|
||||||
"(oder alle) Gegenstände setzen kann."
|
"(oder alle) Gegenstände setzen kann."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Spread a complete update of the shadow map over a given number of frames.\n"
|
"Spread a complete update of the shadow map over a given number of frames.\n"
|
||||||
"Higher values might make shadows laggy, lower values\n"
|
"Higher values might make shadows laggy, lower values\n"
|
||||||
|
@ -6427,8 +6423,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Eine vollständige Aktualisierung der Schattenkarte über die angegebene\n"
|
"Eine vollständige Aktualisierung der Schattenkarte über die angegebene\n"
|
||||||
"Anzahl Frames verteilen. Höhere Werte können dazu führen, dass\n"
|
"Anzahl Frames verteilen. Höhere Werte können dazu führen, dass\n"
|
||||||
"Schatten langsamer reagieren, niedrigere Werte sind rechenintensiver.\n"
|
"Schatten langsamer reagieren, niedrigere Werte sind rechenintensiver."
|
||||||
"Minimalwert: 1; Maximalwert: 16"
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6876,9 +6871,8 @@ msgid "Transparency Sorting Distance"
|
||||||
msgstr "Transparenzsortierungsdistanz"
|
msgstr "Transparenzsortierungsdistanz"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Transparency Sorting Group by Buffers"
|
msgid "Transparency Sorting Group by Buffers"
|
||||||
msgstr "Transparenzsortierungsdistanz"
|
msgstr "Transparenzsortierung nach Puffer gruppieren"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Trees noise"
|
msgid "Trees noise"
|
||||||
|
@ -6942,7 +6936,6 @@ msgid "Undersampling"
|
||||||
msgstr "Unterabtastung"
|
msgstr "Unterabtastung"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
||||||
"to the game world only, keeping the GUI intact.\n"
|
"to the game world only, keeping the GUI intact.\n"
|
||||||
|
@ -6954,11 +6947,14 @@ msgid ""
|
||||||
"to a non-default value."
|
"to a non-default value."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Unterabtastung ist ähnlich der Verwendung einer niedrigeren "
|
"Unterabtastung ist ähnlich der Verwendung einer niedrigeren "
|
||||||
"Bildschirmauflösung, aber sie wird nur auf die Spielwelt angewandt, während "
|
"Bildschirmauflösung,\n"
|
||||||
"die GUI intakt bleibt.\n"
|
"aber sie wird nur auf die Spielwelt angewandt, während die GUI intakt bleibt."
|
||||||
|
"\n"
|
||||||
"Dies sollte einen beträchtlichen Performanzschub auf Kosten einer weniger "
|
"Dies sollte einen beträchtlichen Performanzschub auf Kosten einer weniger "
|
||||||
"detaillierten Grafik geben.\n"
|
"detaillierten Grafik geben.\n"
|
||||||
"Hohe Werte führen zu einer weniger detaillierten Grafik."
|
"Hohe Werte führen zu einer weniger detaillierten Grafik.\n"
|
||||||
|
"Anmerkung: Unterabtastung wird im Moment nicht unterstützt, falls die\n"
|
||||||
|
"„3d_mode“-Einstellung auf einen Nicht-Standardwert gesetzt ist."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Unlimited player transfer distance"
|
msgid "Unlimited player transfer distance"
|
||||||
|
@ -6985,13 +6981,14 @@ msgid "Use a cloud animation for the main menu background."
|
||||||
msgstr "Eine Wolkenanimation für den Hintergrund im Hauptmenü benutzen."
|
msgstr "Eine Wolkenanimation für den Hintergrund im Hauptmenü benutzen."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Use anisotropic filtering when looking at textures from an angle.\n"
|
"Use anisotropic filtering when looking at textures from an angle.\n"
|
||||||
"This provides a significant improvement when used together with mipmapping."
|
"This provides a significant improvement when used together with mipmapping."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Anisotrope Filterung verwenden, wenn auf Texturen aus einem gewissen Winkel "
|
"Anisotrope Filterung verwenden, wenn auf Texturen aus einem gewissen Winkel "
|
||||||
"heraus geschaut wird."
|
"heraus geschaut wird.\n"
|
||||||
|
"Dies bietet eine signifikante Verbesserung, wenn es gemeinsam mit Mipmapping "
|
||||||
|
"verwendet wird."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Use bilinear filtering when scaling textures."
|
msgid "Use bilinear filtering when scaling textures."
|
||||||
|
@ -7268,7 +7265,6 @@ msgstr ""
|
||||||
"die Inventarbilder von Blöcken)."
|
"die Inventarbilder von Blöcken)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
||||||
"can be blurred, so this option automatically upscales them to preserve\n"
|
"can be blurred, so this option automatically upscales them to preserve\n"
|
||||||
|
@ -7279,14 +7275,14 @@ msgid ""
|
||||||
"This is also used as the base node texture size for world-aligned\n"
|
"This is also used as the base node texture size for world-aligned\n"
|
||||||
"texture autoscaling."
|
"texture autoscaling."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Wenn bilineare, trilineare oder anisotrope Filter benutzt werden, können\n"
|
"Wenn bilineare/trilineare Filter benutzt werden, können\n"
|
||||||
"niedrigauflösende Texturen verschwommen sein, also werden sie automatisch\n"
|
"niedrigauflösende Texturen verschwommen sein, also werden sie automatisch\n"
|
||||||
"mit Pixelwiederholung vergrößert, um scharfe Pixel zu behalten. Dies setzt "
|
"mit Pixelwiederholung vergrößert, um scharfe Pixel zu behalten. Dies setzt "
|
||||||
"die\n"
|
"die\n"
|
||||||
"minimale Texturengröße für die vergrößerten Texturen; höhere Werte führen\n"
|
"minimale Texturengröße für die vergrößerten Texturen; höhere Werte führen\n"
|
||||||
"zu einem schärferen Aussehen, aber erfordern mehr Speicher. Zweierpotenzen\n"
|
"zu einem schärferen Aussehen, aber erfordern mehr Speicher.\n"
|
||||||
"werden empfohlen. Diese Einstellung trifft NUR dann in Kraft, falls\n"
|
"Diese Einstellung trifft NUR dann in Kraft, falls\n"
|
||||||
"der bilineare/trilineare/anisotrope Filter aktiviert ist.\n"
|
"einer der genannten Filter aktiviert ist.\n"
|
||||||
"Dies wird außerdem verwendet als die Basisblocktexturengröße für\n"
|
"Dies wird außerdem verwendet als die Basisblocktexturengröße für\n"
|
||||||
"welt-ausgerichtete automatische Texturenskalierung."
|
"welt-ausgerichtete automatische Texturenskalierung."
|
||||||
|
|
||||||
|
@ -7326,17 +7322,15 @@ msgid "Whether to fog out the end of the visible area."
|
||||||
msgstr "Ob das Ende des sichtbaren Gebietes im Nebel verschwinden soll."
|
msgstr "Ob das Ende des sichtbaren Gebietes im Nebel verschwinden soll."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
||||||
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
||||||
"pause menu."
|
"pause menu."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ob die Töne stummgeschaltet werden. Man kann die Töne jederzeit "
|
"Ob die Töne stummgeschaltet werden. Man kann die Töne jederzeit "
|
||||||
"stummschalten,\n"
|
"stummschalten.\n"
|
||||||
"außer, wenn das Tonsystem ausgeschaltet wurde (enable_sound=false).\n"
|
|
||||||
"Im Spiel können die Töne mit der Stummtaste oder mit Hilfe des\n"
|
"Im Spiel können die Töne mit der Stummtaste oder mit Hilfe des\n"
|
||||||
"Pausemenüs stummgeschaltet werden."
|
"Pausenmenüs stummgeschaltet werden."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
192
po/es/luanti.po
192
po/es/luanti.po
|
@ -3,7 +3,7 @@ msgstr ""
|
||||||
"Project-Id-Version: Spanish (Minetest)\n"
|
"Project-Id-Version: Spanish (Minetest)\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
||||||
"PO-Revision-Date: 2025-01-23 21:01+0000\n"
|
"PO-Revision-Date: 2025-02-14 12:19+0000\n"
|
||||||
"Last-Translator: Miguel <mp0187595@tutamail.com>\n"
|
"Last-Translator: Miguel <mp0187595@tutamail.com>\n"
|
||||||
"Language-Team: Spanish <https://hosted.weblate.org/projects/minetest/"
|
"Language-Team: Spanish <https://hosted.weblate.org/projects/minetest/"
|
||||||
"minetest/es/>\n"
|
"minetest/es/>\n"
|
||||||
|
@ -12,7 +12,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.10-dev\n"
|
"X-Generator: Weblate 5.10\n"
|
||||||
|
|
||||||
#: builtin/client/chatcommands.lua
|
#: builtin/client/chatcommands.lua
|
||||||
msgid "Clear the out chat queue"
|
msgid "Clear the out chat queue"
|
||||||
|
@ -263,14 +263,12 @@ msgid "Show technical names"
|
||||||
msgstr "Mostrar los nombres técnicos"
|
msgstr "Mostrar los nombres técnicos"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Touchscreen layout"
|
msgid "Touchscreen layout"
|
||||||
msgstr "Pantalla táctil"
|
msgstr "Diseño de pantalla táctil"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "pause_menu"
|
msgid "pause_menu"
|
||||||
msgstr "FPS (cuadros/s) en el menú de pausa"
|
msgstr "pause_menu"
|
||||||
|
|
||||||
#: builtin/common/settings/settingtypes.lua
|
#: builtin/common/settings/settingtypes.lua
|
||||||
msgid "Client Mods"
|
msgid "Client Mods"
|
||||||
|
@ -610,6 +608,8 @@ msgid ""
|
||||||
"This is the list of clients connected to\n"
|
"This is the list of clients connected to\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Esta es la lista de clientes conectados a\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua
|
#: builtin/mainmenu/dlg_config_world.lua
|
||||||
msgid "(Enabled, has error)"
|
msgid "(Enabled, has error)"
|
||||||
|
@ -974,21 +974,20 @@ msgstr ""
|
||||||
"cual sobreescribirá cualquier renombrado desde aquí."
|
"cual sobreescribirá cualquier renombrado desde aquí."
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Expand all"
|
msgid "Expand all"
|
||||||
msgstr "Activar todos"
|
msgstr "Expandir todo"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "Group by prefix"
|
msgid "Group by prefix"
|
||||||
msgstr ""
|
msgstr "Grupo por prefijo"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses a game called $2 and the following mods:"
|
msgid "The $1 server uses a game called $2 and the following mods:"
|
||||||
msgstr ""
|
msgstr "El servidor $1 utiliza un juego llamado $2 y los siguientes mods:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses the following mods:"
|
msgid "The $1 server uses the following mods:"
|
||||||
msgstr ""
|
msgstr "El servidor $1 usa los siguientes mods:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_version_info.lua
|
#: builtin/mainmenu/dlg_version_info.lua
|
||||||
msgid "A new $1 version is available"
|
msgid "A new $1 version is available"
|
||||||
|
@ -1201,20 +1200,20 @@ msgid "You need to install a game before you can create a world."
|
||||||
msgstr "Necesitas instalar un juego antes de poder crear un mundo."
|
msgstr "Necesitas instalar un juego antes de poder crear un mundo."
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Add favorite"
|
msgid "Add favorite"
|
||||||
msgstr "Eliminar el favorito"
|
msgstr "Añadir a favorito"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Dirección"
|
msgstr "Dirección"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Clients:\n"
|
"Clients:\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr "Cliente"
|
msgstr ""
|
||||||
|
"Clientes:\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Creative mode"
|
msgid "Creative mode"
|
||||||
|
@ -1230,9 +1229,8 @@ msgid "Favorites"
|
||||||
msgstr "Favoritos"
|
msgstr "Favoritos"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Game: $1"
|
msgid "Game: $1"
|
||||||
msgstr "Juego"
|
msgstr "Juego: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Incompatible Servers"
|
msgid "Incompatible Servers"
|
||||||
|
@ -1247,26 +1245,29 @@ msgid "Login"
|
||||||
msgstr "Iniciar sesión"
|
msgstr "Iniciar sesión"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Number of mods: $1"
|
msgid "Number of mods: $1"
|
||||||
msgstr "Número de hilos emergentes"
|
msgstr "Número de mods: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Open server website"
|
msgid "Open server website"
|
||||||
msgstr "Intervalo de servidor dedicado"
|
msgstr "Abrir sitio web del servidor"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Ping"
|
msgid "Ping"
|
||||||
msgstr "Ping"
|
msgstr "Ping"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
"Possible filters\n"
|
"Possible filters\n"
|
||||||
"game:<name>\n"
|
"game:<name>\n"
|
||||||
"mod:<name>\n"
|
"mod:<name>\n"
|
||||||
"player:<name>"
|
"player:<name>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Posibles filtros\n"
|
||||||
|
"game:<nombre>\n"
|
||||||
|
"mod:<nombre>\n"
|
||||||
|
"player:<nombre>"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Public Servers"
|
msgid "Public Servers"
|
||||||
|
@ -1274,7 +1275,7 @@ msgstr "Servidores Públicos"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Refresh"
|
msgid "Refresh"
|
||||||
msgstr "Actualizar"
|
msgstr "Refrescar"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Remove favorite"
|
msgid "Remove favorite"
|
||||||
|
@ -1364,9 +1365,8 @@ msgid "Access denied. Reason: %s"
|
||||||
msgstr "Acceso denegado. Razón: %s"
|
msgstr "Acceso denegado. Razón: %s"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "All debug info hidden"
|
msgid "All debug info hidden"
|
||||||
msgstr "Info de depuración mostrada"
|
msgstr "Toda la información de depuración oculta"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Automatic forward disabled"
|
msgid "Automatic forward disabled"
|
||||||
|
@ -1390,7 +1390,7 @@ msgstr "Límites de bloque mostrados para bloques cercanos"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Bounding boxes shown"
|
msgid "Bounding boxes shown"
|
||||||
msgstr ""
|
msgstr "Cajas delimitadoras mostradas"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Camera update disabled"
|
msgid "Camera update disabled"
|
||||||
|
@ -1633,9 +1633,8 @@ msgid "Volume changed to %d%%"
|
||||||
msgstr "Volumen cambiado a %d%%"
|
msgstr "Volumen cambiado a %d%%"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Wireframe not supported by video driver"
|
msgid "Wireframe not supported by video driver"
|
||||||
msgstr "Los shaders están activados pero el driver no soporta GLSL."
|
msgstr "El controlador de vídeo no admite la estructura alámbrica"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Wireframe shown"
|
msgid "Wireframe shown"
|
||||||
|
@ -2068,9 +2067,8 @@ msgid "Failed to compile the \"%s\" shader."
|
||||||
msgstr "Fallo al compilar el shader \"%s\"."
|
msgstr "Fallo al compilar el shader \"%s\"."
|
||||||
|
|
||||||
#: src/client/shader.cpp
|
#: src/client/shader.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "GLSL is not supported by the driver"
|
msgid "GLSL is not supported by the driver"
|
||||||
msgstr "Los shaders están activados pero el driver no soporta GLSL."
|
msgstr "El controlador no admite GLSL"
|
||||||
|
|
||||||
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
||||||
#: src/content/mod_configuration.cpp
|
#: src/content/mod_configuration.cpp
|
||||||
|
@ -2235,11 +2233,11 @@ msgstr "Alternar el registro del chat"
|
||||||
|
|
||||||
#: src/gui/guiKeyChangeMenu.cpp src/gui/touchscreenlayout.cpp
|
#: src/gui/guiKeyChangeMenu.cpp src/gui/touchscreenlayout.cpp
|
||||||
msgid "Toggle fast"
|
msgid "Toggle fast"
|
||||||
msgstr "Activar rápido"
|
msgstr "Alternar rápido"
|
||||||
|
|
||||||
#: src/gui/guiKeyChangeMenu.cpp src/gui/touchscreenlayout.cpp
|
#: src/gui/guiKeyChangeMenu.cpp src/gui/touchscreenlayout.cpp
|
||||||
msgid "Toggle fly"
|
msgid "Toggle fly"
|
||||||
msgstr "Activar volar"
|
msgstr "Alternar volar"
|
||||||
|
|
||||||
#: src/gui/guiKeyChangeMenu.cpp
|
#: src/gui/guiKeyChangeMenu.cpp
|
||||||
msgid "Toggle fog"
|
msgid "Toggle fog"
|
||||||
|
@ -2307,35 +2305,33 @@ msgid "Sound Volume: %d%%"
|
||||||
msgstr "Volumen del sonido: %d%%"
|
msgstr "Volumen del sonido: %d%%"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Add button"
|
msgid "Add button"
|
||||||
msgstr "Botón central"
|
msgstr "Agregar botón"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Done"
|
msgid "Done"
|
||||||
msgstr "¡Completado!"
|
msgstr "Hecho"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Servidor remoto"
|
msgstr "Eliminar"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr "Reiniciar"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Start dragging a button to add. Tap outside to cancel."
|
msgid "Start dragging a button to add. Tap outside to cancel."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Comienza arrastrando un botón para agregarlo. Toca afuera para cancelar."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap a button to select it. Drag a button to move it."
|
msgid "Tap a button to select it. Drag a button to move it."
|
||||||
msgstr ""
|
msgstr "Toca un botón para seleccionarlo. Arrastra un botón para moverlo."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap outside to deselect."
|
msgid "Tap outside to deselect."
|
||||||
msgstr ""
|
msgstr "Toca afuera para anular la selección."
|
||||||
|
|
||||||
#: src/gui/touchscreenlayout.cpp
|
#: src/gui/touchscreenlayout.cpp
|
||||||
msgid "Joystick"
|
msgid "Joystick"
|
||||||
|
@ -2575,7 +2571,6 @@ msgid "3D noise that determines number of dungeons per mapchunk."
|
||||||
msgstr "Ruido 3D que determina la cantidad de mazmorras por chunk."
|
msgstr "Ruido 3D que determina la cantidad de mazmorras por chunk."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"3D support.\n"
|
"3D support.\n"
|
||||||
"Currently supported:\n"
|
"Currently supported:\n"
|
||||||
|
@ -2588,14 +2583,13 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Soporte 3D.\n"
|
"Soporte 3D.\n"
|
||||||
"Soportado actualmente:\n"
|
"Soportado actualmente:\n"
|
||||||
"- Ninguno (none): sin salida 3D.\n"
|
"- Ninguno: sin salida 3D.\n"
|
||||||
"- Anaglifo (anaglyph): 3D en colores cían y magenta.\n"
|
"- Anaglifo: 3D en colores cían y magenta.\n"
|
||||||
"- Entrelazado (interlaced): soporte para pantallas con polarización "
|
"- Entrelazado: soporte para pantallas con polarización basada en filas "
|
||||||
"basada en filas impar/par.\n"
|
"impar/par.\n"
|
||||||
"- Arriba-abajo (topbottom): dividir pantalla arriba y abajo.\n"
|
"- Arriba-abajo: dividir pantalla arriba y abajo.\n"
|
||||||
"- Lado a lado (sidebyside): dividir pantalla lado a lado.\n"
|
"- Lado a lado: dividir pantalla lado a lado.\n"
|
||||||
"- Vista cruzada (crossview): visión 3D cruzada.\n"
|
"- Vista cruzada: visión 3D cruzada"
|
||||||
"Nota: el modo entrelazado requiere que los sombreadores estén activados."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -2687,11 +2681,14 @@ msgid ""
|
||||||
"All mesh buffers with less than this number of vertices will be merged\n"
|
"All mesh buffers with less than this number of vertices will be merged\n"
|
||||||
"during map rendering. This improves rendering performance."
|
"during map rendering. This improves rendering performance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Se fusionarán todos los buffers de malla con menos de este número de "
|
||||||
|
"vértices\n"
|
||||||
|
"Durante la representación del mapa. Esto mejora el rendimiento de "
|
||||||
|
"renderizado."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Allow clouds to look 3D instead of flat."
|
msgid "Allow clouds to look 3D instead of flat."
|
||||||
msgstr "Usar nubes 3D en lugar de planas."
|
msgstr "Permitir que las nubes se vean en 3D en lugar de planas."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Allows liquids to be translucent."
|
msgid "Allows liquids to be translucent."
|
||||||
|
@ -3105,7 +3102,7 @@ msgstr "Nubes en el menú"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Color depth for post-processing texture"
|
msgid "Color depth for post-processing texture"
|
||||||
msgstr ""
|
msgstr "Profundidad de color para la textura post-procesamiento"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Colored fog"
|
msgid "Colored fog"
|
||||||
|
@ -3125,7 +3122,6 @@ msgstr ""
|
||||||
"Útil para pruebas. Ver al_extensions.[h,cpp] para más detalles."
|
"Útil para pruebas. Ver al_extensions.[h,cpp] para más detalles."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Comma-separated list of flags to hide in the content repository.\n"
|
"Comma-separated list of flags to hide in the content repository.\n"
|
||||||
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
||||||
|
@ -3142,7 +3138,7 @@ msgstr ""
|
||||||
"según lo definido por la Free Software Foundation.\n"
|
"según lo definido por la Free Software Foundation.\n"
|
||||||
"También puedes especificar clasificaciones de contenido.\n"
|
"También puedes especificar clasificaciones de contenido.\n"
|
||||||
"Estas banderas son independientes de las versiones de Luanti,\n"
|
"Estas banderas son independientes de las versiones de Luanti,\n"
|
||||||
"así que consulta una lista completa en https://content.minetest.net/help/"
|
"así que consulta una lista completa en https://content.luanti.org/help/"
|
||||||
"content_flags/"
|
"content_flags/"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -3313,6 +3309,11 @@ msgid ""
|
||||||
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
||||||
"require more than 8 bits to work."
|
"require more than 8 bits to work."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Decide la profundidad de color de la textura utilizada para la canalización "
|
||||||
|
"post-procesamiento.\n"
|
||||||
|
"Reducir esto puede mejorar el rendimiento, pero algunos efectos (por "
|
||||||
|
"ejemplo, tramado)\n"
|
||||||
|
"requieren más de 8 bits para trabajar."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dedicated server step"
|
msgid "Dedicated server step"
|
||||||
|
@ -3537,6 +3538,11 @@ msgid ""
|
||||||
"situations\n"
|
"situations\n"
|
||||||
"where transparency sorting would be very slow otherwise."
|
"where transparency sorting would be very slow otherwise."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Dibuja los triángulos clasificados por transparencia agrupados por sus "
|
||||||
|
"buffers de malla.\n"
|
||||||
|
"Esto rompe la clasificación de transparencia entre los buffers de malla, "
|
||||||
|
"pero evita situaciones\n"
|
||||||
|
"donde la clasificación de transparencia sería muy lenta de lo contrario."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dump the mapgen debug information."
|
msgid "Dump the mapgen debug information."
|
||||||
|
@ -3621,14 +3627,12 @@ msgstr ""
|
||||||
"el comportamiento del ojo humano."
|
"el comportamiento del ojo humano."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable colored shadows for transculent nodes.\n"
|
"Enable colored shadows for transculent nodes.\n"
|
||||||
"This is expensive."
|
"This is expensive."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Habilitar las sombras coloreadas.\n"
|
"Habilita las sombras de colores para nodos translúcidos.\n"
|
||||||
"Si el valor es verdadero los nodos traslúcidos proyectarán sombras "
|
"Esto es costoso."
|
||||||
"coloreadas. Esta opción usa muchos recursos."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable console window"
|
msgid "Enable console window"
|
||||||
|
@ -3712,14 +3716,12 @@ msgstr ""
|
||||||
"Por ejemplo: 0 para balanceo sin vista; 1.0 para normal; 2.0 para doble."
|
"Por ejemplo: 0 para balanceo sin vista; 1.0 para normal; 2.0 para doble."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable/disable running an IPv6 server.\n"
|
"Enable/disable running an IPv6 server.\n"
|
||||||
"Ignored if bind_address is set."
|
"Ignored if bind_address is set."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Habilita/deshabilita la ejecución de un servidor IPv6.\n"
|
"Activa/desactiva la ejecución de un servidor IPv6.\n"
|
||||||
"Ignorado si se establece bind_address.\n"
|
"Se ignora si bind_address está establecido."
|
||||||
"Necesita habilitar enable_ipv6 para ser activado."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -3749,7 +3751,7 @@ msgstr "Activar el desplazamiento suave."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enables the post processing pipeline."
|
msgid "Enables the post processing pipeline."
|
||||||
msgstr "Habilita la canalización para el posprocesamiento."
|
msgstr "Habilita la canalización posterior al procesamiento."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -4384,7 +4386,6 @@ msgstr ""
|
||||||
"la suya por una contraseña vacía."
|
"la suya por una contraseña vacía."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"If enabled, server account registration is separate from login in the UI.\n"
|
"If enabled, server account registration is separate from login in the UI.\n"
|
||||||
"If disabled, connecting to a server will automatically register a new "
|
"If disabled, connecting to a server will automatically register a new "
|
||||||
|
@ -4392,8 +4393,8 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Si está activado, el registro de la cuenta es independiente del inicio de "
|
"Si está activado, el registro de la cuenta es independiente del inicio de "
|
||||||
"sesión en la interfaz de usuario.\n"
|
"sesión en la interfaz de usuario.\n"
|
||||||
"Si está deshabilitado, las cuentas nuevas se registrarán automáticamente al "
|
"Si está desactivado, la conexión a un servidor registrará automáticamente "
|
||||||
"iniciar sesión."
|
"una nueva cuenta."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5298,7 +5299,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Minimum vertex count for mesh buffers"
|
msgid "Minimum vertex count for mesh buffers"
|
||||||
msgstr ""
|
msgstr "Recuento mínimo de vértices para buffers de malla"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Mipmapping"
|
msgid "Mipmapping"
|
||||||
|
@ -5393,15 +5394,14 @@ msgstr ""
|
||||||
"- Las islas flotantes opcionales de v7 (desactivadas por defecto)."
|
"- Las islas flotantes opcionales de v7 (desactivadas por defecto)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Name of the player.\n"
|
"Name of the player.\n"
|
||||||
"When running a server, a client connecting with this name is admin.\n"
|
"When running a server, a client connecting with this name is admin.\n"
|
||||||
"When starting from the main menu, this is overridden."
|
"When starting from the main menu, this is overridden."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nombre del jugador.\n"
|
"Nombre del jugador.\n"
|
||||||
"Cuando se ejecuta un servidor, los clientes que se conecten con este nombre "
|
"Al ejecutar un servidor, el cliente que se conecta con este nombre es "
|
||||||
"son administradores.\n"
|
"administrador.\n"
|
||||||
"Al comenzar desde el menú principal, esto se anula."
|
"Al comenzar desde el menú principal, esto se anula."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -5927,7 +5927,6 @@ msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
msgstr "Ver https://www.sqlite.org/pragma.html#pragma_synchronous"
|
msgstr "Ver https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select the antialiasing method to apply.\n"
|
"Select the antialiasing method to apply.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -5950,26 +5949,28 @@ msgid ""
|
||||||
"Renders higher-resolution image of the scene, then scales down to reduce\n"
|
"Renders higher-resolution image of the scene, then scales down to reduce\n"
|
||||||
"the aliasing effects. This is the slowest and the most accurate method."
|
"the aliasing effects. This is the slowest and the most accurate method."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Seleccione el método de antialiasing a aplicar.\n"
|
"Seleccione el método de suavizado a aplicar.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* Ninguno - Sin antialiasing (por defecto)\n"
|
"* Ninguno - Sin suavizado (por defecto)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* FSAA - Antialiasing de pantalla completa por hardware\n"
|
"* FSAA - Suavizado de pantalla completa por hardware\n"
|
||||||
"(incompatible con Postprocesado y Submuestreo)\n"
|
"También conocido como suavizado multimuestra (MSAA)\n"
|
||||||
"También conocido como antialiasing multimuestra (MSAA)\n"
|
"Suaviza los bordes de los bloques pero no afecta al interior de las texturas."
|
||||||
"Suaviza los bordes de los bloques pero no afecta al interior de las "
|
|
||||||
"texturas.\n"
|
|
||||||
"Es necesario reiniciar para cambiar esta opción.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"* FXAA - Antialiasing rápido aproximado (requiere shaders)\n"
|
"\n"
|
||||||
"Aplica un filtro de postprocesado para detectar y suavizar los bordes de "
|
"Si el posprocesamiento está desactivado, cambiar FSAA requiere reiniciar.\n"
|
||||||
|
"Además, si se desactiva el posprocesamiento, FSAA no funcionará con\n"
|
||||||
|
"submuestreo o una configuración no predeterminada de \"3d_mode\".\n"
|
||||||
|
"\n"
|
||||||
|
"* FXAA - Suavizado aproximado rápido\n"
|
||||||
|
"Aplica un filtro de pos-procesamiento para detectar y suavizar los bordes de "
|
||||||
"alto contraste.\n"
|
"alto contraste.\n"
|
||||||
"Proporciona un equilibrio entre velocidad y calidad de imagen.\n"
|
"Proporciona un equilibrio entre velocidad y calidad de imagen.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* SSAA - Antialiasing de supermuestreo (requiere shaders)\n"
|
"* SSAA - Suavizado de supermuestreo\n"
|
||||||
"Renderiza una imagen de mayor resolución de la escena y, a continuación, "
|
"Renderiza una imagen de mayor resolución de la escena y, a continuación, "
|
||||||
"reduce la escala para reducir los efectos de aliasing.\n"
|
"reduce la escala para reducir\n"
|
||||||
"los efectos del aliasing. Es el método más lento y preciso."
|
"los efectos de distorsión. Es el método más lento y preciso."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Selection box border color (R,G,B)."
|
msgid "Selection box border color (R,G,B)."
|
||||||
|
@ -6410,7 +6411,6 @@ msgstr ""
|
||||||
"pila para ciertos ítems (o para todos)."
|
"pila para ciertos ítems (o para todos)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Spread a complete update of the shadow map over a given number of frames.\n"
|
"Spread a complete update of the shadow map over a given number of frames.\n"
|
||||||
"Higher values might make shadows laggy, lower values\n"
|
"Higher values might make shadows laggy, lower values\n"
|
||||||
|
@ -6420,8 +6420,7 @@ msgstr ""
|
||||||
"determinado de fotogramas.\n"
|
"determinado de fotogramas.\n"
|
||||||
"Los valores más altos pueden hacer que las sombras se retrasen, los valores "
|
"Los valores más altos pueden hacer que las sombras se retrasen, los valores "
|
||||||
"más bajos\n"
|
"más bajos\n"
|
||||||
"consumirán más recursos.\n"
|
"consumirán más recursos."
|
||||||
"Valor mínimo: 1; valor máximo: 16"
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6872,9 +6871,8 @@ msgid "Transparency Sorting Distance"
|
||||||
msgstr "Distancia de Clasificación de Transparencia"
|
msgstr "Distancia de Clasificación de Transparencia"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Transparency Sorting Group by Buffers"
|
msgid "Transparency Sorting Group by Buffers"
|
||||||
msgstr "Distancia de Clasificación de Transparencia"
|
msgstr "Grupo de Clasificación de Transparencia por búferes"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Trees noise"
|
msgid "Trees noise"
|
||||||
|
@ -6978,11 +6976,13 @@ msgid "Use a cloud animation for the main menu background."
|
||||||
msgstr "Usar nubes con animaciones para el fondo del menú principal."
|
msgstr "Usar nubes con animaciones para el fondo del menú principal."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Use anisotropic filtering when looking at textures from an angle.\n"
|
"Use anisotropic filtering when looking at textures from an angle.\n"
|
||||||
"This provides a significant improvement when used together with mipmapping."
|
"This provides a significant improvement when used together with mipmapping."
|
||||||
msgstr "Usar filtrado anisotrópico al mirar texturas desde un ángulo."
|
msgstr ""
|
||||||
|
"Usar filtrado anisotrópico al mirar texturas desde un ángulo.\n"
|
||||||
|
"Esto proporciona una mejora significativa cuando se utiliza junto con el "
|
||||||
|
"mapeo MIP."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Use bilinear filtering when scaling textures."
|
msgid "Use bilinear filtering when scaling textures."
|
||||||
|
@ -7319,18 +7319,16 @@ msgid "Whether to fog out the end of the visible area."
|
||||||
msgstr "Si se debe nublar el final del área visible."
|
msgstr "Si se debe nublar el final del área visible."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
||||||
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
||||||
"pause menu."
|
"pause menu."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Si deseas silenciar los sonidos. Puedes activar el sonido en cualquier "
|
"Si deseas silenciar los sonidos. Puedes activar el sonido en cualquier "
|
||||||
"momento,\n"
|
"momento.\n"
|
||||||
"a menos que el sistema de sonido esté desactivado (enable_sound=false).\n"
|
"En el juego, puedes alternar el estado de silencio con la tecla de silenciar "
|
||||||
"En el juego, puedes alternar el estado de silencio con la tecla de silencio "
|
"o usando el\n"
|
||||||
"o\n"
|
"menú de pausa."
|
||||||
"usando el menú de pausa."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
255
po/fr/luanti.po
255
po/fr/luanti.po
|
@ -3,7 +3,7 @@ msgstr ""
|
||||||
"Project-Id-Version: French (Minetest)\n"
|
"Project-Id-Version: French (Minetest)\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
||||||
"PO-Revision-Date: 2024-11-06 18:04+0000\n"
|
"PO-Revision-Date: 2025-02-12 12:18+0000\n"
|
||||||
"Last-Translator: waxtatect <piero@live.ie>\n"
|
"Last-Translator: waxtatect <piero@live.ie>\n"
|
||||||
"Language-Team: French <https://hosted.weblate.org/projects/minetest/minetest/"
|
"Language-Team: French <https://hosted.weblate.org/projects/minetest/minetest/"
|
||||||
"fr/>\n"
|
"fr/>\n"
|
||||||
|
@ -12,7 +12,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
"X-Generator: Weblate 5.8.2\n"
|
"X-Generator: Weblate 5.10-dev\n"
|
||||||
|
|
||||||
#: builtin/client/chatcommands.lua
|
#: builtin/client/chatcommands.lua
|
||||||
msgid "Clear the out chat queue"
|
msgid "Clear the out chat queue"
|
||||||
|
@ -263,14 +263,12 @@ msgid "Show technical names"
|
||||||
msgstr "Montrer les noms techniques"
|
msgstr "Montrer les noms techniques"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Touchscreen layout"
|
msgid "Touchscreen layout"
|
||||||
msgstr "Écran tactile"
|
msgstr "Disposition de l'écran tactile"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "pause_menu"
|
msgid "pause_menu"
|
||||||
msgstr "FPS maximum sur le menu pause"
|
msgstr "pause_menu"
|
||||||
|
|
||||||
#: builtin/common/settings/settingtypes.lua
|
#: builtin/common/settings/settingtypes.lua
|
||||||
msgid "Client Mods"
|
msgid "Client Mods"
|
||||||
|
@ -319,7 +317,7 @@ msgstr "Très basses"
|
||||||
|
|
||||||
#: builtin/fstk/ui.lua
|
#: builtin/fstk/ui.lua
|
||||||
msgid "<none available>"
|
msgid "<none available>"
|
||||||
msgstr "< aucun disponible >"
|
msgstr "<non disponible>"
|
||||||
|
|
||||||
#: builtin/fstk/ui.lua
|
#: builtin/fstk/ui.lua
|
||||||
msgid "An error occurred in a Lua script:"
|
msgid "An error occurred in a Lua script:"
|
||||||
|
@ -610,6 +608,8 @@ msgid ""
|
||||||
"This is the list of clients connected to\n"
|
"This is the list of clients connected to\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Voici la liste des clients connectés à\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua
|
#: builtin/mainmenu/dlg_config_world.lua
|
||||||
msgid "(Enabled, has error)"
|
msgid "(Enabled, has error)"
|
||||||
|
@ -977,21 +977,20 @@ msgstr ""
|
||||||
"remplace tout renommage effectué ici."
|
"remplace tout renommage effectué ici."
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Expand all"
|
msgid "Expand all"
|
||||||
msgstr "Tout activer"
|
msgstr "Tout développer"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "Group by prefix"
|
msgid "Group by prefix"
|
||||||
msgstr ""
|
msgstr "Grouper par préfixe"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses a game called $2 and the following mods:"
|
msgid "The $1 server uses a game called $2 and the following mods:"
|
||||||
msgstr ""
|
msgstr "Le serveur $1 utilise un jeu appelé $2 et les mods suivants :"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses the following mods:"
|
msgid "The $1 server uses the following mods:"
|
||||||
msgstr ""
|
msgstr "Le serveur $1 utilise les mods suivants :"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_version_info.lua
|
#: builtin/mainmenu/dlg_version_info.lua
|
||||||
msgid "A new $1 version is available"
|
msgid "A new $1 version is available"
|
||||||
|
@ -1205,20 +1204,20 @@ msgid "You need to install a game before you can create a world."
|
||||||
msgstr "Vous devez en installer un pour créer un nouveau monde."
|
msgstr "Vous devez en installer un pour créer un nouveau monde."
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Add favorite"
|
msgid "Add favorite"
|
||||||
msgstr "Supprimer le favori"
|
msgstr "Ajouter aux favoris"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Adresse"
|
msgstr "Adresse"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Clients:\n"
|
"Clients:\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr "Client"
|
msgstr ""
|
||||||
|
"Clients : \n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Creative mode"
|
msgid "Creative mode"
|
||||||
|
@ -1234,9 +1233,8 @@ msgid "Favorites"
|
||||||
msgstr "Favoris"
|
msgstr "Favoris"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Game: $1"
|
msgid "Game: $1"
|
||||||
msgstr "Jeu"
|
msgstr "Jeu : $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Incompatible Servers"
|
msgid "Incompatible Servers"
|
||||||
|
@ -1251,14 +1249,12 @@ msgid "Login"
|
||||||
msgstr "Connexion"
|
msgstr "Connexion"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Number of mods: $1"
|
msgid "Number of mods: $1"
|
||||||
msgstr "Nombre de fils émergents"
|
msgstr "Nombre de mods : $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Open server website"
|
msgid "Open server website"
|
||||||
msgstr "Intervalle de mise à jour des objets sur le serveur"
|
msgstr "Visiter le site web du serveur"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Ping"
|
msgid "Ping"
|
||||||
|
@ -1271,6 +1267,10 @@ msgid ""
|
||||||
"mod:<name>\n"
|
"mod:<name>\n"
|
||||||
"player:<name>"
|
"player:<name>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Filtres possibles :\n"
|
||||||
|
"game:<nom>\n"
|
||||||
|
"mod:<nom>\n"
|
||||||
|
"player:<nom>"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Public Servers"
|
msgid "Public Servers"
|
||||||
|
@ -1366,9 +1366,8 @@ msgid "Access denied. Reason: %s"
|
||||||
msgstr "Accès refusé. Raison : %s"
|
msgstr "Accès refusé. Raison : %s"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "All debug info hidden"
|
msgid "All debug info hidden"
|
||||||
msgstr "Informations de débogage affichées"
|
msgstr "Informations de débogage cachées"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Automatic forward disabled"
|
msgid "Automatic forward disabled"
|
||||||
|
@ -1392,7 +1391,7 @@ msgstr "Limites des blocs affichées pour les blocs voisins"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Bounding boxes shown"
|
msgid "Bounding boxes shown"
|
||||||
msgstr ""
|
msgstr "Limites des boîtes affichées"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Camera update disabled"
|
msgid "Camera update disabled"
|
||||||
|
@ -1635,10 +1634,8 @@ msgid "Volume changed to %d%%"
|
||||||
msgstr "Volume réglé sur %d %%"
|
msgstr "Volume réglé sur %d %%"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Wireframe not supported by video driver"
|
msgid "Wireframe not supported by video driver"
|
||||||
msgstr ""
|
msgstr "Fils de fer non pris en charge par le pilote vidéo"
|
||||||
"Les nuanceurs sont activés mais GLSL n'est pas pris en charge par le pilote."
|
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Wireframe shown"
|
msgid "Wireframe shown"
|
||||||
|
@ -2068,10 +2065,8 @@ msgid "Failed to compile the \"%s\" shader."
|
||||||
msgstr "Échec de la compilation du nuanceur « %s »."
|
msgstr "Échec de la compilation du nuanceur « %s »."
|
||||||
|
|
||||||
#: src/client/shader.cpp
|
#: src/client/shader.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "GLSL is not supported by the driver"
|
msgid "GLSL is not supported by the driver"
|
||||||
msgstr ""
|
msgstr "GLSL n'est pas pris en charge par le pilote vidéo"
|
||||||
"Les nuanceurs sont activés mais GLSL n'est pas pris en charge par le pilote."
|
|
||||||
|
|
||||||
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
||||||
#: src/content/mod_configuration.cpp
|
#: src/content/mod_configuration.cpp
|
||||||
|
@ -2091,7 +2086,7 @@ msgid ""
|
||||||
"Note: this may be caused by a dependency cycle, in which case try updating "
|
"Note: this may be caused by a dependency cycle, in which case try updating "
|
||||||
"the mods."
|
"the mods."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Note : ceci peut être dû à un cycle de dépendances, dans ce cas essayer de "
|
"Note : cela peut être dû à un cycle de dépendances, dans ce cas essayer de "
|
||||||
"mettre à jour les mods."
|
"mettre à jour les mods."
|
||||||
|
|
||||||
#: src/content/mod_configuration.cpp
|
#: src/content/mod_configuration.cpp
|
||||||
|
@ -2308,35 +2303,35 @@ msgid "Sound Volume: %d%%"
|
||||||
msgstr "Volume du son : %d %%"
|
msgstr "Volume du son : %d %%"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Add button"
|
msgid "Add button"
|
||||||
msgstr "Clic central"
|
msgstr "Ajouter un bouton"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Done"
|
msgid "Done"
|
||||||
msgstr "Terminé !"
|
msgstr "Terminé"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Serveur distant"
|
msgstr "Supprimer"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr "Réinitialiser"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Start dragging a button to add. Tap outside to cancel."
|
msgid "Start dragging a button to add. Tap outside to cancel."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Faire glisser un bouton pour ajouter. Appuyer à l'extérieur pour annuler."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap a button to select it. Drag a button to move it."
|
msgid "Tap a button to select it. Drag a button to move it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Appuyer sur un bouton pour le sélectionner. Faire glisser un bouton pour le "
|
||||||
|
"déplacer."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap outside to deselect."
|
msgid "Tap outside to deselect."
|
||||||
msgstr ""
|
msgstr "Appuyer à l'extérieur pour désélectionner."
|
||||||
|
|
||||||
#: src/gui/touchscreenlayout.cpp
|
#: src/gui/touchscreenlayout.cpp
|
||||||
msgid "Joystick"
|
msgid "Joystick"
|
||||||
|
@ -2524,7 +2519,7 @@ msgstr "Nuages 3D"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "3D mode"
|
msgid "3D mode"
|
||||||
msgstr "Mode écran 3D"
|
msgstr "Mode 3D"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "3D mode parallax strength"
|
msgid "3D mode parallax strength"
|
||||||
|
@ -2573,7 +2568,6 @@ msgid "3D noise that determines number of dungeons per mapchunk."
|
||||||
msgstr "Bruit 3D qui détermine le nombre de donjons par tranche de carte."
|
msgstr "Bruit 3D qui détermine le nombre de donjons par tranche de carte."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"3D support.\n"
|
"3D support.\n"
|
||||||
"Currently supported:\n"
|
"Currently supported:\n"
|
||||||
|
@ -2592,8 +2586,7 @@ msgstr ""
|
||||||
"lignes paires/impaires.\n"
|
"lignes paires/impaires.\n"
|
||||||
"– haut-bas : partage haut et bas de l'écran.\n"
|
"– haut-bas : partage haut et bas de l'écran.\n"
|
||||||
"– côte-à-côte : partage côte à côte de l'écran.\n"
|
"– côte-à-côte : partage côte à côte de l'écran.\n"
|
||||||
"– vision croisée : vision croisée 3D.\n"
|
"– vision croisée : vision croisée 3D."
|
||||||
"Noter que le mode entrelacé nécessite que les nuanceurs soient activés."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -2683,11 +2676,13 @@ msgid ""
|
||||||
"All mesh buffers with less than this number of vertices will be merged\n"
|
"All mesh buffers with less than this number of vertices will be merged\n"
|
||||||
"during map rendering. This improves rendering performance."
|
"during map rendering. This improves rendering performance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Tous les tampons de maillage ayant moins de ce nombre de sommets sont "
|
||||||
|
"fusionnés lors du rendu de la carte.\n"
|
||||||
|
"Cela améliore les performances de rendu."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Allow clouds to look 3D instead of flat."
|
msgid "Allow clouds to look 3D instead of flat."
|
||||||
msgstr "Activer les nuages 3D au lieu des nuages 2D (plats)."
|
msgstr "Permet aux nuages de paraître en 3D au lieu de plats."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Allows liquids to be translucent."
|
msgid "Allows liquids to be translucent."
|
||||||
|
@ -2705,7 +2700,7 @@ msgstr ""
|
||||||
"Des valeurs plus élevées rendent les niveaux de lumière moyens et inférieurs "
|
"Des valeurs plus élevées rendent les niveaux de lumière moyens et inférieurs "
|
||||||
"plus lumineux.\n"
|
"plus lumineux.\n"
|
||||||
"La valeur « 1,0 » laisse la courbe de lumière intacte.\n"
|
"La valeur « 1,0 » laisse la courbe de lumière intacte.\n"
|
||||||
"Ceci a un effet significatif seulement sur la lumière du jour et la lumière "
|
"Cela a un effet significatif seulement sur la lumière du jour et la lumière "
|
||||||
"artificielle, et a très peu d'effet sur la lumière naturelle nocturne."
|
"artificielle, et a très peu d'effet sur la lumière naturelle nocturne."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -2777,7 +2772,7 @@ msgstr ""
|
||||||
"effectue un tramage supplémentaire ou si les canaux de couleur ne sont pas "
|
"effectue un tramage supplémentaire ou si les canaux de couleur ne sont pas "
|
||||||
"quantifiés à 8 bits.\n"
|
"quantifiés à 8 bits.\n"
|
||||||
"Avec OpenGL ES, le tramage fonctionne seulement si les nuanceurs prennent en "
|
"Avec OpenGL ES, le tramage fonctionne seulement si les nuanceurs prennent en "
|
||||||
"charge une précision élevée en virgule flottante et ceci peut avoir un "
|
"charge une précision élevée en virgule flottante et cela peut avoir un "
|
||||||
"impact plus important sur les performances."
|
"impact plus important sur les performances."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -2836,8 +2831,8 @@ msgstr ""
|
||||||
"Des valeurs plus faibles peuvent augmenter la performance du serveur, mais "
|
"Des valeurs plus faibles peuvent augmenter la performance du serveur, mais "
|
||||||
"peut provoquer l'apparition de problèmes de rendu (certains blocs ne sont "
|
"peut provoquer l'apparition de problèmes de rendu (certains blocs ne sont "
|
||||||
"pas visibles).\n"
|
"pas visibles).\n"
|
||||||
"Ceci est particulièrement utile pour les très grandes distances de vue (plus "
|
"C'est particulièrement utile pour les très grandes distances de vue (plus de "
|
||||||
"de 500).\n"
|
"500).\n"
|
||||||
"Établie en blocs de carte (16 nœuds)."
|
"Établie en blocs de carte (16 nœuds)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -3099,7 +3094,7 @@ msgstr "Nuages dans le menu"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Color depth for post-processing texture"
|
msgid "Color depth for post-processing texture"
|
||||||
msgstr ""
|
msgstr "Profondeur de couleur pour la texture de post-traitement"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Colored fog"
|
msgid "Colored fog"
|
||||||
|
@ -3119,7 +3114,6 @@ msgstr ""
|
||||||
"Utile pour les tests. Voir « al_extensions.[h, cpp] » pour plus de détails."
|
"Utile pour les tests. Voir « al_extensions.[h, cpp] » pour plus de détails."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Comma-separated list of flags to hide in the content repository.\n"
|
"Comma-separated list of flags to hide in the content repository.\n"
|
||||||
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
||||||
|
@ -3272,7 +3266,7 @@ msgid ""
|
||||||
"This also applies to the object crosshair."
|
"This also applies to the object crosshair."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Opacité du réticule (entre 0 et 255).\n"
|
"Opacité du réticule (entre 0 et 255).\n"
|
||||||
"Ceci s'applique également au réticule de l'objet."
|
"Cela s'applique également au réticule de l'objet."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Crosshair color"
|
msgid "Crosshair color"
|
||||||
|
@ -3284,7 +3278,7 @@ msgid ""
|
||||||
"Also controls the object crosshair color"
|
"Also controls the object crosshair color"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Couleur du réticule (R,V,B).\n"
|
"Couleur du réticule (R,V,B).\n"
|
||||||
"Ceci s'applique également à la couleur du réticule de l'objet."
|
"Cela s'applique également à la couleur du réticule de l'objet."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Debug log file size threshold"
|
msgid "Debug log file size threshold"
|
||||||
|
@ -3305,6 +3299,10 @@ msgid ""
|
||||||
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
||||||
"require more than 8 bits to work."
|
"require more than 8 bits to work."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Détermine la profondeur de couleur de la texture utilisée pour les "
|
||||||
|
"opérations de post-traitement.\n"
|
||||||
|
"Réduire cette valeur peut améliorer les performances, mais certains effets ("
|
||||||
|
"ex. : le tramage) nécessitent plus de 8 bits pour fonctionner."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dedicated server step"
|
msgid "Dedicated server step"
|
||||||
|
@ -3345,8 +3343,8 @@ msgid ""
|
||||||
"but also uses more resources."
|
"but also uses more resources."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Définir la qualité du filtrage des ombres.\n"
|
"Définir la qualité du filtrage des ombres.\n"
|
||||||
"Ceci simule l'effet d'ombres douces en appliquant un disque PCF ou Poisson "
|
"Cela simule l'effet d'ombres douces en appliquant le PCF ou le disque de "
|
||||||
"mais utilise également plus de ressources."
|
"Poisson mais utilise également plus de ressources."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -3364,10 +3362,10 @@ msgstr ""
|
||||||
"Les anciens clients sont compatibles dans le sens où ils ne plantent pas "
|
"Les anciens clients sont compatibles dans le sens où ils ne plantent pas "
|
||||||
"lors de la connexion aux serveurs récents,\n"
|
"lors de la connexion aux serveurs récents,\n"
|
||||||
"mais ils peuvent ne pas prendre en charge certaines fonctionnalités.\n"
|
"mais ils peuvent ne pas prendre en charge certaines fonctionnalités.\n"
|
||||||
"Ceci permet un contrôle plus précis que "
|
"Cela permet un contrôle plus précis que « strict_protocol_version_checking »."
|
||||||
"« strict_protocol_version_checking ».\n"
|
"\n"
|
||||||
"Luanti applique toujours son propre minimum interne, activer "
|
"Luanti applique toujours son propre minimum interne, activer « "
|
||||||
"« strict_protocol_version_checking » le remplace."
|
"strict_protocol_version_checking » le remplace."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Defines areas where trees have apples."
|
msgid "Defines areas where trees have apples."
|
||||||
|
@ -3441,7 +3439,7 @@ msgid ""
|
||||||
"down the rate of mesh updates, thus reducing jitter on slower clients."
|
"down the rate of mesh updates, thus reducing jitter on slower clients."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Délai entre les mises à jour du maillage du client en ms.\n"
|
"Délai entre les mises à jour du maillage du client en ms.\n"
|
||||||
"Augmenter ceci ralentit le taux de mise à jour et réduit donc les "
|
"Augmenter cela ralentit le taux de mise à jour et réduit donc les "
|
||||||
"tremblements sur les clients lents."
|
"tremblements sur les clients lents."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -3528,6 +3526,10 @@ msgid ""
|
||||||
"situations\n"
|
"situations\n"
|
||||||
"where transparency sorting would be very slow otherwise."
|
"where transparency sorting would be very slow otherwise."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Dessine les triangles triés par transparence regroupés par leurs tampons de "
|
||||||
|
"maillage.\n"
|
||||||
|
"Cela empêche le tri par transparence entre les tampons de maillage, mais "
|
||||||
|
"évite les situations où le tri par transparence serait très lent autrement."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dump the mapgen debug information."
|
msgid "Dump the mapgen debug information."
|
||||||
|
@ -3589,7 +3591,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Activer le filtrage par disque de Poisson.\n"
|
"Activer le filtrage par disque de Poisson.\n"
|
||||||
"Si activé, utilise le disque de Poisson pour créer des « ombres douces ». "
|
"Si activé, utilise le disque de Poisson pour créer des « ombres douces ». "
|
||||||
"Sinon, utilise le filtrage PCF."
|
"Sinon, utilise le PCF."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable Post Processing"
|
msgid "Enable Post Processing"
|
||||||
|
@ -3597,7 +3599,7 @@ msgstr "Activer le post-traitement"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable Raytraced Culling"
|
msgid "Enable Raytraced Culling"
|
||||||
msgstr "Activer l'élimination des blocs invisibles par Ray Tracing"
|
msgstr "Activer l'élimination des blocs invisibles par lancer de rayons"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -3613,14 +3615,12 @@ msgstr ""
|
||||||
"simulant le comportement de l’œil humain."
|
"simulant le comportement de l’œil humain."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable colored shadows for transculent nodes.\n"
|
"Enable colored shadows for transculent nodes.\n"
|
||||||
"This is expensive."
|
"This is expensive."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Activer les ombres colorées.\n"
|
"Activer les ombres colorées pour les nœuds translucides.\n"
|
||||||
"Sur les nœuds vraiment transparents, projette des ombres colorées. Ceci est "
|
"Cela utilise beaucoup de ressources."
|
||||||
"coûteux."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable console window"
|
msgid "Enable console window"
|
||||||
|
@ -3707,14 +3707,12 @@ msgstr ""
|
||||||
"double."
|
"double."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable/disable running an IPv6 server.\n"
|
"Enable/disable running an IPv6 server.\n"
|
||||||
"Ignored if bind_address is set."
|
"Ignored if bind_address is set."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Activer/désactiver l'usage d'un serveur IPv6.\n"
|
"Activer/désactiver l'usage d'un serveur IPv6.\n"
|
||||||
"Ignoré si « bind_address » est activé.\n"
|
"Ignoré si « bind_address » est activé."
|
||||||
"A besoin de « enable_ipv6 » pour être activé."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -3978,7 +3976,7 @@ msgid ""
|
||||||
"be\n"
|
"be\n"
|
||||||
"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
|
"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Pour les polices de style pixel qui ne s'adaptent pas bien, ceci garantit "
|
"Pour les polices de style pixel qui ne s'adaptent pas bien, cela garantit "
|
||||||
"que les tailles de police utilisées avec cette police sont toujours "
|
"que les tailles de police utilisées avec cette police sont toujours "
|
||||||
"divisibles par cette valeur, en pixels.\n"
|
"divisibles par cette valeur, en pixels.\n"
|
||||||
"Par exemple une police de style pixel de 16 pixels de haut doit avoir cette "
|
"Par exemple une police de style pixel de 16 pixels de haut doit avoir cette "
|
||||||
|
@ -4057,7 +4055,7 @@ msgstr ""
|
||||||
"Distance maximale à laquelle les clients ont connaissance des objets, "
|
"Distance maximale à laquelle les clients ont connaissance des objets, "
|
||||||
"établie en blocs de carte (16 nœuds).\n"
|
"établie en blocs de carte (16 nœuds).\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Définir ceci plus grand que « active_block_range », ainsi le serveur "
|
"Définir cela plus grand que « active_block_range », ainsi le serveur "
|
||||||
"maintient les objets actifs jusqu’à cette distance dans la direction où un "
|
"maintient les objets actifs jusqu’à cette distance dans la direction où un "
|
||||||
"joueur regarde (cela peut éviter que des mobs disparaissent soudainement de "
|
"joueur regarde (cela peut éviter que des mobs disparaissent soudainement de "
|
||||||
"la vue)."
|
"la vue)."
|
||||||
|
@ -4288,7 +4286,7 @@ msgid ""
|
||||||
"Decrease this to increase liquid resistance to movement."
|
"Decrease this to increase liquid resistance to movement."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ralentissement lors du déplacement dans un liquide.\n"
|
"Ralentissement lors du déplacement dans un liquide.\n"
|
||||||
"Réduire ceci pour augmenter la résistance au mouvement."
|
"Réduire cette valeur pour augmenter la résistance au mouvement."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "How wide to make rivers."
|
msgid "How wide to make rivers."
|
||||||
|
@ -4376,16 +4374,15 @@ msgstr ""
|
||||||
"de le remplacer par un mot de passe vide."
|
"de le remplacer par un mot de passe vide."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"If enabled, server account registration is separate from login in the UI.\n"
|
"If enabled, server account registration is separate from login in the UI.\n"
|
||||||
"If disabled, connecting to a server will automatically register a new "
|
"If disabled, connecting to a server will automatically register a new "
|
||||||
"account."
|
"account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Si activé, l'enregistrement du compte est séparé de la connexion dans "
|
"Si activé, l'enregistrement du compte sur le serveur est séparé de la "
|
||||||
"l'interface utilisateur.\n"
|
"connexion dans l'interface utilisateur.\n"
|
||||||
"Si désactivé, les nouveaux comptes sont enregistrés automatiquement lors de "
|
"Si désactivé, la connexion à un serveur entraîne automatiquement "
|
||||||
"la connexion."
|
"l'enregistrement d'un nouveau compte."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -4396,7 +4393,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Si activé, le serveur effectue la détermination des blocs de carte "
|
"Si activé, le serveur effectue la détermination des blocs de carte "
|
||||||
"invisibles selon la position des yeux du joueur.\n"
|
"invisibles selon la position des yeux du joueur.\n"
|
||||||
"Ceci peut réduire le nombre de blocs envoyés au client de 50 à 80 %.\n"
|
"Cela peut réduire le nombre de blocs envoyés au client de 50 à 80 %.\n"
|
||||||
"Les clients ne reçoivent plus la plupart des blocs invisibles, de sorte que "
|
"Les clients ne reçoivent plus la plupart des blocs invisibles, de sorte que "
|
||||||
"l'utilité du mode sans collisions est réduite."
|
"l'utilité du mode sans collisions est réduite."
|
||||||
|
|
||||||
|
@ -4473,7 +4470,7 @@ msgid ""
|
||||||
"This is usually only needed by core/builtin contributors"
|
"This is usually only needed by core/builtin contributors"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Instrumenter « Intégré » (« builtin »).\n"
|
"Instrumenter « Intégré » (« builtin »).\n"
|
||||||
"Ceci est habituellement nécessaire seulement pour les développeurs "
|
"Cela est habituellement nécessaire seulement pour les développeurs "
|
||||||
"principaux."
|
"principaux."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -4752,7 +4749,7 @@ msgid ""
|
||||||
"- trace"
|
"- trace"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Niveau de journalisation à écrire dans « debug.txt » :\n"
|
"Niveau de journalisation à écrire dans « debug.txt » :\n"
|
||||||
"– < rien > (pas de journalisation)\n"
|
"– <vide> (pas de journalisation)\n"
|
||||||
"– aucun (messages sans niveau)\n"
|
"– aucun (messages sans niveau)\n"
|
||||||
"– erreur\n"
|
"– erreur\n"
|
||||||
"– avertissement\n"
|
"– avertissement\n"
|
||||||
|
@ -5282,7 +5279,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Minimum vertex count for mesh buffers"
|
msgid "Minimum vertex count for mesh buffers"
|
||||||
msgstr ""
|
msgstr "Nombre minimal de sommets pour les tampons de maillage"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Mipmapping"
|
msgid "Mipmapping"
|
||||||
|
@ -5378,15 +5375,14 @@ msgstr ""
|
||||||
"– les terrains flottants optionnels du générateur v7 (désactivé par défaut)."
|
"– les terrains flottants optionnels du générateur v7 (désactivé par défaut)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Name of the player.\n"
|
"Name of the player.\n"
|
||||||
"When running a server, a client connecting with this name is admin.\n"
|
"When running a server, a client connecting with this name is admin.\n"
|
||||||
"When starting from the main menu, this is overridden."
|
"When starting from the main menu, this is overridden."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nom du joueur.\n"
|
"Nom du joueur.\n"
|
||||||
"Lorsqu'un serveur est lancé, les clients se connectant avec ce nom sont "
|
"Lorsqu'un serveur est lancé, le client se connectant avec ce nom est "
|
||||||
"administrateurs.\n"
|
"administrateur.\n"
|
||||||
"Lors du démarrage à partir du menu principal, celui-ci est remplacé."
|
"Lors du démarrage à partir du menu principal, celui-ci est remplacé."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -5614,7 +5610,7 @@ msgstr ""
|
||||||
"des boutons de la souris.\n"
|
"des boutons de la souris.\n"
|
||||||
"Activer cette option lorsque vous creusez ou placez trop souvent par "
|
"Activer cette option lorsque vous creusez ou placez trop souvent par "
|
||||||
"accident.\n"
|
"accident.\n"
|
||||||
"Sur écrans tactiles, ceci a un effet seulement pour creuser."
|
"Sur écrans tactiles, cela a un effet seulement pour le minage."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Prevent mods from doing insecure things like running shell commands."
|
msgid "Prevent mods from doing insecure things like running shell commands."
|
||||||
|
@ -5847,9 +5843,9 @@ msgid ""
|
||||||
"edge pixels when images are scaled by non-integer sizes."
|
"edge pixels when images are scaled by non-integer sizes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Met à l'échelle l'interface graphique par une valeur spécifiée par "
|
"Met à l'échelle l'interface graphique par une valeur spécifiée par "
|
||||||
"l'utilisateur, à l'aide d'un filtre au plus proche voisin avec "
|
"l'utilisateur, à l'aide d'un filtre au plus proche voisin avec anticrénelage."
|
||||||
"anticrénelage.\n"
|
"\n"
|
||||||
"Ceci lisse certains bords grossiers, et mélange les pixels en réduisant "
|
"Cela lisse certains bords grossiers, et mélange les pixels en réduisant "
|
||||||
"l'échelle.\n"
|
"l'échelle.\n"
|
||||||
"Au détriment d'un effet de flou sur des pixels en bordure quand les images "
|
"Au détriment d'un effet de flou sur des pixels en bordure quand les images "
|
||||||
"sont mises à l'échelle par des valeurs fractionnelles."
|
"sont mises à l'échelle par des valeurs fractionnelles."
|
||||||
|
@ -5911,7 +5907,6 @@ msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
msgstr "Voir http://www.sqlite.org/pragma.html#pragma_synchronous"
|
msgstr "Voir http://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select the antialiasing method to apply.\n"
|
"Select the antialiasing method to apply.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -5938,17 +5933,22 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"* Aucun – Pas d'anticrénelage (par défaut)\n"
|
"* Aucun – Pas d'anticrénelage (par défaut)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* FSAA – Anticrénelage de la scène complète (incompatible avec « Post-"
|
"* FSAA – Anticrénelage matériel de la scène complète\n"
|
||||||
"traitement » et « Sous-échantillonnage »)\n"
|
|
||||||
"Alias anticrénelage multi-échantillon (MSAA), lisse les bords des blocs mais "
|
"Alias anticrénelage multi-échantillon (MSAA), lisse les bords des blocs mais "
|
||||||
"n'affecte pas l'intérieur des textures.\n"
|
"n'affecte pas l'intérieur des textures.\n"
|
||||||
"Un redémarrage est nécessaire pour modifier cette option.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"* FXAA – Anticrénelage approximatif rapide (nécessite des nuanceurs)\n"
|
"Si le post-traitement est désactivé, la modification de FSAA nécessite un "
|
||||||
|
"redémarrage.\n"
|
||||||
|
"De même, si le post-traitement est désactivé, le FSAA ne fonctionne pas avec "
|
||||||
|
"le sous-échantillonnage,\n"
|
||||||
|
"pour un paramètre « Mode 3D » défini sur une autre valeur que celle par "
|
||||||
|
"défaut.\n"
|
||||||
|
"\n"
|
||||||
|
"* FXAA – Anticrénelage approximatif rapide\n"
|
||||||
"Applique un filtre de post-traitement pour détecter et lisser les bords à "
|
"Applique un filtre de post-traitement pour détecter et lisser les bords à "
|
||||||
"contraste élevé, fournit un équilibre entre vitesse et qualité d'image.\n"
|
"contraste élevé, fournit un équilibre entre vitesse et qualité d'image.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* SSAA – Anticrénelage par super-échantillonnage (nécessite des nuanceurs)\n"
|
"* SSAA – Anticrénelage par super-échantillonnage\n"
|
||||||
"Rendu d'une image haute résolution de la scène, puis réduit l'échelle pour "
|
"Rendu d'une image haute résolution de la scène, puis réduit l'échelle pour "
|
||||||
"diminuer le crénelage. C'est la méthode la plus lente et la plus précise."
|
"diminuer le crénelage. C'est la méthode la plus lente et la plus précise."
|
||||||
|
|
||||||
|
@ -6187,7 +6187,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Définit la qualité de la texture de l'ombre sur 32 bits.\n"
|
"Définit la qualité de la texture de l'ombre sur 32 bits.\n"
|
||||||
"Si désactivé, une texture de 16 bits est utilisée.\n"
|
"Si désactivé, une texture de 16 bits est utilisée.\n"
|
||||||
"Ceci peut causer beaucoup plus d'artefacts sur l'ombre."
|
"Cela peut causer beaucoup plus d'artefacts sur l'ombre."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Shader path"
|
msgid "Shader path"
|
||||||
|
@ -6389,7 +6389,6 @@ msgstr ""
|
||||||
"certains (ou tous) objets."
|
"certains (ou tous) objets."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Spread a complete update of the shadow map over a given number of frames.\n"
|
"Spread a complete update of the shadow map over a given number of frames.\n"
|
||||||
"Higher values might make shadows laggy, lower values\n"
|
"Higher values might make shadows laggy, lower values\n"
|
||||||
|
@ -6398,8 +6397,7 @@ msgstr ""
|
||||||
"Répartit une mise à jour complète de la carte des ombres sur un nombre donné "
|
"Répartit une mise à jour complète de la carte des ombres sur un nombre donné "
|
||||||
"d'images.\n"
|
"d'images.\n"
|
||||||
"Des valeurs plus élevées peuvent rendre les ombres plus lentes, des valeurs "
|
"Des valeurs plus élevées peuvent rendre les ombres plus lentes, des valeurs "
|
||||||
"plus faibles consomment plus de ressources.\n"
|
"plus faibles consomment plus de ressources."
|
||||||
"Valeur minimale : 1 ; valeur maximale : 16"
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6666,11 +6664,11 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Le rayon du volume de blocs autour de chaque joueur soumis au bloc actif, "
|
"Le rayon du volume de blocs autour de chaque joueur soumis au bloc actif, "
|
||||||
"établi en blocs de carte (16 nœuds).\n"
|
"établi en blocs de carte (16 nœuds).\n"
|
||||||
"Dans les blocs actifs, les objets sont chargés et les « ABMs » sont "
|
"Dans les blocs actifs, les objets sont chargés et les « ABMs » sont exécutés."
|
||||||
"exécutés.\n"
|
"\n"
|
||||||
"C'est également la distance minimale dans laquelle les objets actifs (mobs) "
|
"C'est également la distance minimale dans laquelle les objets actifs (mobs) "
|
||||||
"sont conservés.\n"
|
"sont conservés.\n"
|
||||||
"Ceci doit être configuré avec « active_object_send_range_blocks »."
|
"Cela doit être configuré avec « active_object_send_range_blocks »."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6701,7 +6699,7 @@ msgstr ""
|
||||||
"Intensité (obscurité) de l'ombrage des blocs avec l'occlusion ambiante.\n"
|
"Intensité (obscurité) de l'ombrage des blocs avec l'occlusion ambiante.\n"
|
||||||
"Les valeurs plus faibles sont plus sombres, les valeurs plus hautes sont "
|
"Les valeurs plus faibles sont plus sombres, les valeurs plus hautes sont "
|
||||||
"plus claires.\n"
|
"plus claires.\n"
|
||||||
"Une plage valide de valeurs pour ceci se situe entre 0,25 et 4,0.\n"
|
"Une plage valide de valeurs pour cela se situe entre 0,25 et 4,0.\n"
|
||||||
"Si la valeur est en dehors de cette plage alors elle est définie à la plus "
|
"Si la valeur est en dehors de cette plage alors elle est définie à la plus "
|
||||||
"proche des valeurs valides."
|
"proche des valeurs valides."
|
||||||
|
|
||||||
|
@ -6798,7 +6796,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Pour réduire le décalage, le transfert des blocs est ralenti quand un joueur "
|
"Pour réduire le décalage, le transfert des blocs est ralenti quand un joueur "
|
||||||
"construit quelque chose.\n"
|
"construit quelque chose.\n"
|
||||||
"Ceci détermine la durée du ralentissement après placement ou destruction "
|
"Cela détermine la durée du ralentissement après placement ou destruction "
|
||||||
"d'un nœud."
|
"d'un nœud."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -6843,12 +6841,11 @@ msgstr "Liquides translucides"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Transparency Sorting Distance"
|
msgid "Transparency Sorting Distance"
|
||||||
msgstr "Distance de tri de la transparence"
|
msgstr "Tri de la transparence par distance"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Transparency Sorting Group by Buffers"
|
msgid "Transparency Sorting Group by Buffers"
|
||||||
msgstr "Distance de tri de la transparence"
|
msgstr "Tri de la transparence regroupés par tampons"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Trees noise"
|
msgid "Trees noise"
|
||||||
|
@ -6912,7 +6909,6 @@ msgid "Undersampling"
|
||||||
msgstr "Sous-échantillonnage"
|
msgstr "Sous-échantillonnage"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
||||||
"to the game world only, keeping the GUI intact.\n"
|
"to the game world only, keeping the GUI intact.\n"
|
||||||
|
@ -6926,9 +6922,12 @@ msgstr ""
|
||||||
"Le sous-échantillonnage ressemble à l'utilisation d'une résolution d'écran "
|
"Le sous-échantillonnage ressemble à l'utilisation d'une résolution d'écran "
|
||||||
"inférieure.\n"
|
"inférieure.\n"
|
||||||
"Il ne s'applique qu'au rendu 3D, gardant l'interface graphique intacte.\n"
|
"Il ne s'applique qu'au rendu 3D, gardant l'interface graphique intacte.\n"
|
||||||
"Ceci doit donner un bonus de performance conséquent, au détriment de la "
|
"Cela doit donner un bonus de performance conséquent, au détriment de la "
|
||||||
"qualité d'image.\n"
|
"qualité d'image.\n"
|
||||||
"Les valeurs plus élevées réduisent la qualité du détail des images."
|
"Les valeurs plus élevées réduisent la qualité du détail des images.\n"
|
||||||
|
"Note : le sous-échantillonnage n'est actuellement pas pris en charge,\n"
|
||||||
|
"si le paramètre « Mode 3D » est définie sur une autre valeur que celle par "
|
||||||
|
"défaut."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Unlimited player transfer distance"
|
msgid "Unlimited player transfer distance"
|
||||||
|
@ -6955,13 +6954,14 @@ msgid "Use a cloud animation for the main menu background."
|
||||||
msgstr "Utiliser l'animation des nuages pour l'arrière-plan du menu principal."
|
msgstr "Utiliser l'animation des nuages pour l'arrière-plan du menu principal."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Use anisotropic filtering when looking at textures from an angle.\n"
|
"Use anisotropic filtering when looking at textures from an angle.\n"
|
||||||
"This provides a significant improvement when used together with mipmapping."
|
"This provides a significant improvement when used together with mipmapping."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Utiliser le filtrage anisotrope lorsque l'on regarde les textures sous un "
|
"Utiliser le filtrage anisotrope lorsque l'on regarde les textures sous un "
|
||||||
"certain angle."
|
"certain angle.\n"
|
||||||
|
"Cela apporte une amélioration significative lorsqu'il est utilisé avec le "
|
||||||
|
"mip-mapping."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Use bilinear filtering when scaling textures."
|
msgid "Use bilinear filtering when scaling textures."
|
||||||
|
@ -6998,10 +6998,10 @@ msgid ""
|
||||||
"This flag enables use of raytraced occlusion culling test for\n"
|
"This flag enables use of raytraced occlusion culling test for\n"
|
||||||
"client mesh sizes smaller than 4x4x4 map blocks."
|
"client mesh sizes smaller than 4x4x4 map blocks."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Utiliser l'élimination des blocs invisibles par Ray Tracing avec le nouvel "
|
"Utiliser l'élimination des blocs invisibles par lancer de rayons avec le "
|
||||||
"algorithme.\n"
|
"nouvel algorithme.\n"
|
||||||
"Cette option active l'utilisation du test d'élimination des blocs invisibles "
|
"Cette option active l'utilisation du test d'élimination des blocs invisibles "
|
||||||
"par Ray Tracing,\n"
|
"par lancer de rayons,\n"
|
||||||
"pour les maillages clients de taille inférieure à 4 × 4 × 4 blocs de carte."
|
"pour les maillages clients de taille inférieure à 4 × 4 × 4 blocs de carte."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -7237,7 +7237,6 @@ msgstr ""
|
||||||
"directement par le matériel (ex. : textures des blocs dans l'inventaire)."
|
"directement par le matériel (ex. : textures des blocs dans l'inventaire)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
||||||
"can be blurred, so this option automatically upscales them to preserve\n"
|
"can be blurred, so this option automatically upscales them to preserve\n"
|
||||||
|
@ -7248,16 +7247,16 @@ msgid ""
|
||||||
"This is also used as the base node texture size for world-aligned\n"
|
"This is also used as the base node texture size for world-aligned\n"
|
||||||
"texture autoscaling."
|
"texture autoscaling."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"En utilisant le filtrage bilinéaire/trilinéaire/anisotrope, les textures de "
|
"En utilisant le filtrage bilinéaire/trilinéaire, les textures de basse "
|
||||||
"basse résolution peuvent être floues.\n"
|
"résolution peuvent être floues.\n"
|
||||||
"Elles sont donc agrandies avec l'interpolation au plus proche voisin pour "
|
"Cette option les agrandies automatiquement afin de préserver des pixels nets."
|
||||||
"préserver des pixels nets.\n"
|
"\n"
|
||||||
"Ceci détermine la taille minimale pour les textures agrandies ;\n"
|
"Cela définit la taille minimale pour les textures agrandies ;\n"
|
||||||
"les valeurs plus élevées ont un rendu plus net, mais nécessitent plus de "
|
"les valeurs plus élevées ont un rendu plus net, mais nécessitent plus de "
|
||||||
"mémoire. Les puissances de 2 sont recommandées.\n"
|
"mémoire.\n"
|
||||||
"Ce paramètre est appliqué seulement si le filtrage bilinéaire/trilinéaire/"
|
"Ce paramètre est appliqué UNIQUEMENT si l'un des filtres mentionnés est "
|
||||||
"anisotrope est activé.\n"
|
"activé.\n"
|
||||||
"Ceci est également utilisé comme taille de texture de nœud de base pour "
|
"Cela est également utilisé comme taille de texture de nœud de base pour "
|
||||||
"l'agrandissement automatique des textures alignées sur le monde."
|
"l'agrandissement automatique des textures alignées sur le monde."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -7293,14 +7292,12 @@ msgid "Whether to fog out the end of the visible area."
|
||||||
msgstr "Détermine la visibilité du brouillard au bout de l'aire visible."
|
msgstr "Détermine la visibilité du brouillard au bout de l'aire visible."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
||||||
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
||||||
"pause menu."
|
"pause menu."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"S'il faut couper le son. Vous pouvez réactiver le son à tout moment, sauf si "
|
"S'il faut couper le son. Vous pouvez réactiver le son à tout moment.\n"
|
||||||
"le système audio est désactivé (« enable_sound=false »).\n"
|
|
||||||
"Dans le jeu, vous pouvez basculer l'état du son avec la touche « Muet » ou "
|
"Dans le jeu, vous pouvez basculer l'état du son avec la touche « Muet » ou "
|
||||||
"en utilisant le menu pause."
|
"en utilisant le menu pause."
|
||||||
|
|
||||||
|
@ -7399,7 +7396,7 @@ msgstr ""
|
||||||
"Distance Y sur laquelle les terrains flottants passent d'une densité "
|
"Distance Y sur laquelle les terrains flottants passent d'une densité "
|
||||||
"maximale à une densité nulle.\n"
|
"maximale à une densité nulle.\n"
|
||||||
"L'effilage commence à cette distance, depuis la limite en Y.\n"
|
"L'effilage commence à cette distance, depuis la limite en Y.\n"
|
||||||
"Pour une couche solide de terrain flottant, ceci contrôle la hauteur des "
|
"Pour une couche solide de terrain flottant, cela contrôle la hauteur des "
|
||||||
"collines et des montagnes.\n"
|
"collines et des montagnes.\n"
|
||||||
"Doit être inférieure ou égale à la moitié de la distance entre les limites Y."
|
"Doit être inférieure ou égale à la moitié de la distance entre les limites Y."
|
||||||
|
|
||||||
|
|
196
po/gl/luanti.po
196
po/gl/luanti.po
|
@ -3,7 +3,7 @@ msgstr ""
|
||||||
"Project-Id-Version: minetest\n"
|
"Project-Id-Version: minetest\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
||||||
"PO-Revision-Date: 2024-11-24 10:00+0000\n"
|
"PO-Revision-Date: 2025-02-13 12:44+0000\n"
|
||||||
"Last-Translator: ninjum <ninhum@gmx.com>\n"
|
"Last-Translator: ninjum <ninhum@gmx.com>\n"
|
||||||
"Language-Team: Galician <https://hosted.weblate.org/projects/minetest/"
|
"Language-Team: Galician <https://hosted.weblate.org/projects/minetest/"
|
||||||
"minetest/gl/>\n"
|
"minetest/gl/>\n"
|
||||||
|
@ -12,7 +12,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.9-dev\n"
|
"X-Generator: Weblate 5.10-dev\n"
|
||||||
|
|
||||||
#: builtin/client/chatcommands.lua
|
#: builtin/client/chatcommands.lua
|
||||||
msgid "Clear the out chat queue"
|
msgid "Clear the out chat queue"
|
||||||
|
@ -263,13 +263,12 @@ msgid "Show technical names"
|
||||||
msgstr "Mostrar nomes técnicos"
|
msgstr "Mostrar nomes técnicos"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Touchscreen layout"
|
msgid "Touchscreen layout"
|
||||||
msgstr "Pantalla táctil"
|
msgstr "Disposición da pantalla táctil"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
msgid "pause_menu"
|
msgid "pause_menu"
|
||||||
msgstr ""
|
msgstr "_menú de pausa"
|
||||||
|
|
||||||
#: builtin/common/settings/settingtypes.lua
|
#: builtin/common/settings/settingtypes.lua
|
||||||
msgid "Client Mods"
|
msgid "Client Mods"
|
||||||
|
@ -609,6 +608,8 @@ msgid ""
|
||||||
"This is the list of clients connected to\n"
|
"This is the list of clients connected to\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Esta é a lista de clientes conectados a\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua
|
#: builtin/mainmenu/dlg_config_world.lua
|
||||||
msgid "(Enabled, has error)"
|
msgid "(Enabled, has error)"
|
||||||
|
@ -882,7 +883,7 @@ msgstr "Desexa eliminar \"$1\"?"
|
||||||
#: builtin/mainmenu/dlg_delete_content.lua
|
#: builtin/mainmenu/dlg_delete_content.lua
|
||||||
#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua
|
#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Eliminar"
|
msgstr "Borrar"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_delete_content.lua
|
#: builtin/mainmenu/dlg_delete_content.lua
|
||||||
msgid "pkgmgr: failed to delete \"$1\""
|
msgid "pkgmgr: failed to delete \"$1\""
|
||||||
|
@ -971,21 +972,20 @@ msgstr ""
|
||||||
"non permitirá cambios de nome aquí."
|
"non permitirá cambios de nome aquí."
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Expand all"
|
msgid "Expand all"
|
||||||
msgstr "Activar todo"
|
msgstr "Expandir todo"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "Group by prefix"
|
msgid "Group by prefix"
|
||||||
msgstr ""
|
msgstr "Agrupar por prefixo"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses a game called $2 and the following mods:"
|
msgid "The $1 server uses a game called $2 and the following mods:"
|
||||||
msgstr ""
|
msgstr "O servidor $1 usa un xogo chamado $2 e as seguintes modificacións:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses the following mods:"
|
msgid "The $1 server uses the following mods:"
|
||||||
msgstr ""
|
msgstr "O servidor $1 usa as seguintes modificacións:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_version_info.lua
|
#: builtin/mainmenu/dlg_version_info.lua
|
||||||
msgid "A new $1 version is available"
|
msgid "A new $1 version is available"
|
||||||
|
@ -1199,20 +1199,20 @@ msgid "You need to install a game before you can create a world."
|
||||||
msgstr "Tes que instalar un xogo antes de poder crear un mundo."
|
msgstr "Tes que instalar un xogo antes de poder crear un mundo."
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Add favorite"
|
msgid "Add favorite"
|
||||||
msgstr "Favorito remoto"
|
msgstr "Engadir aos favoritos"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Enderezo"
|
msgstr "Enderezo"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Clients:\n"
|
"Clients:\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr "Cliente"
|
msgstr ""
|
||||||
|
"Clientes:\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Creative mode"
|
msgid "Creative mode"
|
||||||
|
@ -1228,9 +1228,8 @@ msgid "Favorites"
|
||||||
msgstr "Favoritos"
|
msgstr "Favoritos"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Game: $1"
|
msgid "Game: $1"
|
||||||
msgstr "Xogo"
|
msgstr "Xogo: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Incompatible Servers"
|
msgid "Incompatible Servers"
|
||||||
|
@ -1245,14 +1244,12 @@ msgid "Login"
|
||||||
msgstr "Identificarse"
|
msgstr "Identificarse"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Number of mods: $1"
|
msgid "Number of mods: $1"
|
||||||
msgstr "Número de fíos emerxentes"
|
msgstr "Número de modificacións: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Open server website"
|
msgid "Open server website"
|
||||||
msgstr "Intervalo de servidor dedicado"
|
msgstr "Abrir o sitio web do servidor"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Ping"
|
msgid "Ping"
|
||||||
|
@ -1265,6 +1262,10 @@ msgid ""
|
||||||
"mod:<name>\n"
|
"mod:<name>\n"
|
||||||
"player:<name>"
|
"player:<name>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Filtros posibles\n"
|
||||||
|
"xogo:<nome>\n"
|
||||||
|
"mod:<nome>\"\n"
|
||||||
|
"xogador:<nome"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Public Servers"
|
msgid "Public Servers"
|
||||||
|
@ -1360,9 +1361,8 @@ msgid "Access denied. Reason: %s"
|
||||||
msgstr "Acceso negado. Motivo: %s"
|
msgstr "Acceso negado. Motivo: %s"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "All debug info hidden"
|
msgid "All debug info hidden"
|
||||||
msgstr "Info de depuración mostrada"
|
msgstr "Toda a información de depuración oculta"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Automatic forward disabled"
|
msgid "Automatic forward disabled"
|
||||||
|
@ -1386,7 +1386,7 @@ msgstr "Límites de bloques mostrados para bloques pretos"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Bounding boxes shown"
|
msgid "Bounding boxes shown"
|
||||||
msgstr ""
|
msgstr "Caixas delimitadoras amosadas"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Camera update disabled"
|
msgid "Camera update disabled"
|
||||||
|
@ -1627,9 +1627,8 @@ msgid "Volume changed to %d%%"
|
||||||
msgstr "Volume cambiado a %d%%"
|
msgstr "Volume cambiado a %d%%"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Wireframe not supported by video driver"
|
msgid "Wireframe not supported by video driver"
|
||||||
msgstr "Os sombreadores están habilitados pero o controlador non admite GLSL."
|
msgstr "O wireframe non é compatible co controlador de vídeo"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Wireframe shown"
|
msgid "Wireframe shown"
|
||||||
|
@ -2062,9 +2061,8 @@ msgid "Failed to compile the \"%s\" shader."
|
||||||
msgstr "Produciuse un erro ao compilar o sombreador \"%s\"."
|
msgstr "Produciuse un erro ao compilar o sombreador \"%s\"."
|
||||||
|
|
||||||
#: src/client/shader.cpp
|
#: src/client/shader.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "GLSL is not supported by the driver"
|
msgid "GLSL is not supported by the driver"
|
||||||
msgstr "Os sombreadores están habilitados pero o controlador non admite GLSL."
|
msgstr "GLSL non é compatible co controlador"
|
||||||
|
|
||||||
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
||||||
#: src/content/mod_configuration.cpp
|
#: src/content/mod_configuration.cpp
|
||||||
|
@ -2301,35 +2299,32 @@ msgid "Sound Volume: %d%%"
|
||||||
msgstr "Son: %d%%"
|
msgstr "Son: %d%%"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Add button"
|
msgid "Add button"
|
||||||
msgstr "Botón central"
|
msgstr "Engadir botón"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Done"
|
msgid "Done"
|
||||||
msgstr "Feito!"
|
msgstr "Feito"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Servidor remoto"
|
msgstr "Eliminar"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr "Restablecer"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Start dragging a button to add. Tap outside to cancel."
|
msgid "Start dragging a button to add. Tap outside to cancel."
|
||||||
msgstr ""
|
msgstr "Comeza a arrastrar un botón para engadir. Toca fóra para cancelar."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap a button to select it. Drag a button to move it."
|
msgid "Tap a button to select it. Drag a button to move it."
|
||||||
msgstr ""
|
msgstr "Toca un botón para seccionalo. Arrastra un botón para movelo."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap outside to deselect."
|
msgid "Tap outside to deselect."
|
||||||
msgstr ""
|
msgstr "Toca fóra para deseleccionar."
|
||||||
|
|
||||||
#: src/gui/touchscreenlayout.cpp
|
#: src/gui/touchscreenlayout.cpp
|
||||||
msgid "Joystick"
|
msgid "Joystick"
|
||||||
|
@ -2565,7 +2560,6 @@ msgid "3D noise that determines number of dungeons per mapchunk."
|
||||||
msgstr "Ruído 3D que determina a cantidade de calabozos por chunk."
|
msgstr "Ruído 3D que determina a cantidade de calabozos por chunk."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"3D support.\n"
|
"3D support.\n"
|
||||||
"Currently supported:\n"
|
"Currently supported:\n"
|
||||||
|
@ -2578,14 +2572,13 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Soporte 3D.\n"
|
"Soporte 3D.\n"
|
||||||
"Soportado actualmente:\n"
|
"Soportado actualmente:\n"
|
||||||
"- none: sen saída 3D.\n"
|
"- ningún: sen saída 3D.\n"
|
||||||
"- anaglyph: 3D en cor ciano/maxenta.\n"
|
"- anáglifo: 3D en cor ciano/maxenta.\n"
|
||||||
"- interlaced: soporte de pantalla polarizada baseada en liñas par/ímpar.\n"
|
"- entrelazado: soporte de pantalla polarizada baseada en liñas par/ímpar."
|
||||||
"- topbottom: pantalla dividida superior/inferior.\n"
|
"\n"
|
||||||
"- sidebyside: pantalla dividida lado a lado.\n"
|
"- arriba-abaixo: pantalla dividida superior/inferior.\n"
|
||||||
" - crossview: 3D para ver cruzado\n"
|
"- lado a lado: pantalla dividida lado a lado.\n"
|
||||||
"Teña en conta que o modo entrelazado require cos sombreadores estean "
|
"- vista cruzada: 3D para ver cruzado"
|
||||||
"activados."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -2674,11 +2667,13 @@ msgid ""
|
||||||
"All mesh buffers with less than this number of vertices will be merged\n"
|
"All mesh buffers with less than this number of vertices will be merged\n"
|
||||||
"during map rendering. This improves rendering performance."
|
"during map rendering. This improves rendering performance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Todos os buffers de malla con menos de este número de vértices serán "
|
||||||
|
"fusionados\n"
|
||||||
|
"durante o renderizado do mapa. Isto mellora o rendemento do renderizado."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Allow clouds to look 3D instead of flat."
|
msgid "Allow clouds to look 3D instead of flat."
|
||||||
msgstr "Activa as nubes 3D en lugar de nubes 2D (planas)."
|
msgstr "Permitir que as nubes se vexan en 3D en vez de planas."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Allows liquids to be translucent."
|
msgid "Allows liquids to be translucent."
|
||||||
|
@ -3089,7 +3084,7 @@ msgstr "Nubes no menú"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Color depth for post-processing texture"
|
msgid "Color depth for post-processing texture"
|
||||||
msgstr ""
|
msgstr "Profundidade de cor para a textura de post-procesamento"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Colored fog"
|
msgid "Colored fog"
|
||||||
|
@ -3108,7 +3103,6 @@ msgstr ""
|
||||||
"Útil para probas. Vexa al_extensions.[h,cpp] para máis detalles."
|
"Útil para probas. Vexa al_extensions.[h,cpp] para máis detalles."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Comma-separated list of flags to hide in the content repository.\n"
|
"Comma-separated list of flags to hide in the content repository.\n"
|
||||||
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
||||||
|
@ -3294,6 +3288,11 @@ msgid ""
|
||||||
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
||||||
"require more than 8 bits to work."
|
"require more than 8 bits to work."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Decide a profundidade de cor da textura utilizada para o proceso de post-"
|
||||||
|
"procesamento.\n"
|
||||||
|
"Reducir isto pode mellorar o rendemento, pero algúns efectos (por exemplo, "
|
||||||
|
"tramado)\n"
|
||||||
|
"require máis de 8 bits para funcionar."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dedicated server step"
|
msgid "Dedicated server step"
|
||||||
|
@ -3518,6 +3517,11 @@ msgid ""
|
||||||
"situations\n"
|
"situations\n"
|
||||||
"where transparency sorting would be very slow otherwise."
|
"where transparency sorting would be very slow otherwise."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Debuxar triángulos ordenados por transparencia agrupados polos seus buffers "
|
||||||
|
"de malla.\n"
|
||||||
|
"Isto rompe a orde de transparencia entre os buffers de malla, pero evita "
|
||||||
|
"situacións\n"
|
||||||
|
"onde a orde de transparencia sería moi lenta noutro caso."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dump the mapgen debug information."
|
msgid "Dump the mapgen debug information."
|
||||||
|
@ -3602,14 +3606,12 @@ msgstr ""
|
||||||
"simulando o comportamento do ollo humano."
|
"simulando o comportamento do ollo humano."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable colored shadows for transculent nodes.\n"
|
"Enable colored shadows for transculent nodes.\n"
|
||||||
"This is expensive."
|
"This is expensive."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Activar sombras coloridas.\n"
|
"Activar sombras coloreadas para nós translúcidos.\n"
|
||||||
"Se o valor é verdadeiro, os bloques traslúcidos proxectarán sombras "
|
"Isto é custoso."
|
||||||
"coloridas. Esta opción precisa de moitos recursos."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable console window"
|
msgid "Enable console window"
|
||||||
|
@ -3695,14 +3697,12 @@ msgstr ""
|
||||||
"Por exemplo: 0 para nada de balanceo; 1.0 para o normal; 2.0 para o dobre."
|
"Por exemplo: 0 para nada de balanceo; 1.0 para o normal; 2.0 para o dobre."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable/disable running an IPv6 server.\n"
|
"Enable/disable running an IPv6 server.\n"
|
||||||
"Ignored if bind_address is set."
|
"Ignored if bind_address is set."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Activa/desactiva a execución dun servidor IPv6.\n"
|
"Activar/desactivar a execución dun servidor IPv6.\n"
|
||||||
"Ignorado se establécese bind_address.\n"
|
"Ignorado se está configurada a bind_address."
|
||||||
"É preciso enable_ipv6 para activalo."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -4364,14 +4364,15 @@ msgstr ""
|
||||||
"cambiar o seu contrasinal a un contrasinal baleiro."
|
"cambiar o seu contrasinal a un contrasinal baleiro."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"If enabled, server account registration is separate from login in the UI.\n"
|
"If enabled, server account registration is separate from login in the UI.\n"
|
||||||
"If disabled, connecting to a server will automatically register a new "
|
"If disabled, connecting to a server will automatically register a new "
|
||||||
"account."
|
"account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Activar confirmación de rexistro ao se conectar ao servidor\n"
|
"Se está activado, o rexistro da conta do servidor é separado do inicio de "
|
||||||
"Se está desactivado, rexistrarase unha nova conta automáticamente."
|
"sesión na interface de usuario.\n"
|
||||||
|
"Se está desactivado, conectar a un servidor rexistrará automaticamente unha "
|
||||||
|
"nova conta."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5262,7 +5263,7 @@ msgstr "Límite mínimo do número aleatorio de covas pequenas por chunk."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Minimum vertex count for mesh buffers"
|
msgid "Minimum vertex count for mesh buffers"
|
||||||
msgstr ""
|
msgstr "Contaxe mínima de vértices para os buffers de malla"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Mipmapping"
|
msgid "Mipmapping"
|
||||||
|
@ -5357,16 +5358,15 @@ msgstr ""
|
||||||
"- Os terreos flotantes opcionais de v7 (desactivados por defecto)."
|
"- Os terreos flotantes opcionais de v7 (desactivados por defecto)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Name of the player.\n"
|
"Name of the player.\n"
|
||||||
"When running a server, a client connecting with this name is admin.\n"
|
"When running a server, a client connecting with this name is admin.\n"
|
||||||
"When starting from the main menu, this is overridden."
|
"When starting from the main menu, this is overridden."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nome do xogador.\n"
|
"Nome do xogador.\n"
|
||||||
"Cando se executa un servidor, os clientes que se conectan con este nome son "
|
"Cando se executa un servidor, un cliente que se conecte con este nome será "
|
||||||
"administradores.\n"
|
"administrador.\n"
|
||||||
"Ao comezar desde o menú principal, isto substitúese."
|
"Cando se inicie desde o menú principal, isto será substituído."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6356,18 +6356,16 @@ msgstr ""
|
||||||
"cantidade na que agrupar algúns (ou todos) os obxectos."
|
"cantidade na que agrupar algúns (ou todos) os obxectos."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Spread a complete update of the shadow map over a given number of frames.\n"
|
"Spread a complete update of the shadow map over a given number of frames.\n"
|
||||||
"Higher values might make shadows laggy, lower values\n"
|
"Higher values might make shadows laggy, lower values\n"
|
||||||
"will consume more resources."
|
"will consume more resources."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Distribuír unha actualización completa do mapa de sombras sobre unha "
|
"Espallar unha actualización completa do mapa de sombras ao longo dun número "
|
||||||
"determinada cantidade de fotogramas.\n"
|
"determinado de fotogramas.\n"
|
||||||
"Os valores máis altos poden facer cas sombras sexan lentas e os valores máis "
|
"Valores máis altos poden facer que as sombras vaian con retardo, mentres que "
|
||||||
"baixos\n"
|
"valores máis baixos\n"
|
||||||
"consumirán máis recursos.\n"
|
"consumirán máis recursos."
|
||||||
"Valor mínimo: 1; Valor máximo 16"
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6650,7 +6648,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"O backend de renderizado.\n"
|
"O backend de renderizado.\n"
|
||||||
"Nota: É necesario reiniciar despois de cambiar isto!\n"
|
"Nota: É necesario reiniciar despois de cambiar isto!\n"
|
||||||
"OpenGL é o predeterminado para escritorio, e OGLES2 para Android"
|
"OpenGL é o predeterminado para escritorio, e OGLES2 para Android."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6814,9 +6812,8 @@ msgid "Transparency Sorting Distance"
|
||||||
msgstr "Distancia de ordenación de transparencias"
|
msgstr "Distancia de ordenación de transparencias"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Transparency Sorting Group by Buffers"
|
msgid "Transparency Sorting Group by Buffers"
|
||||||
msgstr "Distancia de ordenación de transparencias"
|
msgstr "Grupo de orde de transparencia por buffers"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Trees noise"
|
msgid "Trees noise"
|
||||||
|
@ -6876,7 +6873,6 @@ msgid "Undersampling"
|
||||||
msgstr "Submostraxe"
|
msgstr "Submostraxe"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
||||||
"to the game world only, keeping the GUI intact.\n"
|
"to the game world only, keeping the GUI intact.\n"
|
||||||
|
@ -6892,7 +6888,10 @@ msgstr ""
|
||||||
"só para o mundo, mantendo a GUI intacta.\n"
|
"só para o mundo, mantendo a GUI intacta.\n"
|
||||||
"Debería dar un aumento máis significativo do rendemento a costa dunha imaxe "
|
"Debería dar un aumento máis significativo do rendemento a costa dunha imaxe "
|
||||||
"menos detallada.\n"
|
"menos detallada.\n"
|
||||||
"Os valores máis altos dan como resultado unha imaxe menos detallada."
|
"Os valores máis altos dan como resultado unha imaxe menos detallada.\n"
|
||||||
|
"Nota: A submostraxe actualmente non está soportada se a configuración "
|
||||||
|
"'3d_mode' está establecida\n"
|
||||||
|
"cun valor non predeterminado."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Unlimited player transfer distance"
|
msgid "Unlimited player transfer distance"
|
||||||
|
@ -6919,11 +6918,13 @@ msgid "Use a cloud animation for the main menu background."
|
||||||
msgstr "Usa unha animación de nube para o fondo do menú principal."
|
msgstr "Usa unha animación de nube para o fondo do menú principal."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Use anisotropic filtering when looking at textures from an angle.\n"
|
"Use anisotropic filtering when looking at textures from an angle.\n"
|
||||||
"This provides a significant improvement when used together with mipmapping."
|
"This provides a significant improvement when used together with mipmapping."
|
||||||
msgstr "Usar filtrado anisotrópico ao observar texturas desde un ángulo."
|
msgstr ""
|
||||||
|
"Usar filtrado anisotrópico ao observar texturas desde un ángulo.\n"
|
||||||
|
"Isto proporciona unha mellora significativa cando se usa xunto con "
|
||||||
|
"mipmapping."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Use bilinear filtering when scaling textures."
|
msgid "Use bilinear filtering when scaling textures."
|
||||||
|
@ -7195,7 +7196,6 @@ msgstr ""
|
||||||
"ao hardware (por exemplo, renderizado en textura para nós do inventario)."
|
"ao hardware (por exemplo, renderizado en textura para nós do inventario)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
||||||
"can be blurred, so this option automatically upscales them to preserve\n"
|
"can be blurred, so this option automatically upscales them to preserve\n"
|
||||||
|
@ -7206,17 +7206,16 @@ msgid ""
|
||||||
"This is also used as the base node texture size for world-aligned\n"
|
"This is also used as the base node texture size for world-aligned\n"
|
||||||
"texture autoscaling."
|
"texture autoscaling."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Cando se usan filtros bilineais/trilineais/anisótropos, texturas de baixa "
|
"Cando se usa filtrado bilineal/trilineal, as texturas de baixa resolución\n"
|
||||||
"resolución\n"
|
"poden quedar borrosas, polo que esta opción amplía automaticamente as "
|
||||||
"poden ser borrosas, polo que amplíaos automaticamente co veciño máis "
|
"texturas para preservar\n"
|
||||||
"próximo\n"
|
"píxeles nítidos. Isto define o tamaño mínimo da textura para as texturas "
|
||||||
"interpolación para preservar píxeles nítidos. Isto establece o tamaño mínimo "
|
"ampliadas;\n"
|
||||||
"de textura\n"
|
"valores máis altos son máis nítidos, pero requiren máis memoria.\n"
|
||||||
"para as texturas mejoradas; valores máis altos parecen máis nítidos, pero "
|
"Esta configuración APLÍCASE SÓ se algún dos filtros mencionados está "
|
||||||
"requiren máis\n"
|
"habilitado.\n"
|
||||||
"memoria. Recoméndase potencias de 2. Esta configuración só se aplica se\n"
|
"Este tamén se usa como tamaño de textura do nodo base para aliñados ao "
|
||||||
"O filtrado bilineal/trilineal/anisótropo está activado.\n"
|
"mundo\n"
|
||||||
"Tamén se usa como tamaño de textura do nodo base para aliñados ao mundo\n"
|
|
||||||
"autoescalado de texturas."
|
"autoescalado de texturas."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -7253,17 +7252,16 @@ msgid "Whether to fog out the end of the visible area."
|
||||||
msgstr "Indica se hai que poñar néboa ao final da zona visible."
|
msgstr "Indica se hai que poñar néboa ao final da zona visible."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
||||||
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
||||||
"pause menu."
|
"pause menu."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Indica se hai que silenciar os sons. Podes activar o son en calquera "
|
"Se activar ou desactivar os sons. Pódese reactivar o son en calquera momento."
|
||||||
"momento, a non ser que\n"
|
"\n"
|
||||||
"esté desactivado (enable_sound=false).\n"
|
"No xogo, podes alternar o estado de silencio coa tecla de silencio ou "
|
||||||
"No xogo podes cambiar o estado de silencio coa tecla de silencio ou no\n"
|
"utilizando\n"
|
||||||
"menú de pausa."
|
"o menú de pausa."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
6450
po/ia/luanti.po
6450
po/ia/luanti.po
File diff suppressed because it is too large
Load diff
229
po/id/luanti.po
229
po/id/luanti.po
|
@ -3,7 +3,7 @@ msgstr ""
|
||||||
"Project-Id-Version: Indonesian (Minetest)\n"
|
"Project-Id-Version: Indonesian (Minetest)\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
||||||
"PO-Revision-Date: 2024-12-22 16:00+0000\n"
|
"PO-Revision-Date: 2025-02-11 02:02+0000\n"
|
||||||
"Last-Translator: Linerly <linerly@proton.me>\n"
|
"Last-Translator: Linerly <linerly@proton.me>\n"
|
||||||
"Language-Team: Indonesian <https://hosted.weblate.org/projects/minetest/"
|
"Language-Team: Indonesian <https://hosted.weblate.org/projects/minetest/"
|
||||||
"minetest/id/>\n"
|
"minetest/id/>\n"
|
||||||
|
@ -263,14 +263,12 @@ msgid "Show technical names"
|
||||||
msgstr "Tampilkan nama teknis"
|
msgstr "Tampilkan nama teknis"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Touchscreen layout"
|
msgid "Touchscreen layout"
|
||||||
msgstr "Layar Sentuh"
|
msgstr "Tata letak layar sentuh"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "pause_menu"
|
msgid "pause_menu"
|
||||||
msgstr "FPS (bingkai per detik) pada menu jeda"
|
msgstr "pause_menu"
|
||||||
|
|
||||||
#: builtin/common/settings/settingtypes.lua
|
#: builtin/common/settings/settingtypes.lua
|
||||||
msgid "Client Mods"
|
msgid "Client Mods"
|
||||||
|
@ -608,6 +606,8 @@ msgid ""
|
||||||
"This is the list of clients connected to\n"
|
"This is the list of clients connected to\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Ini daftar klien yang terhubung ke\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua
|
#: builtin/mainmenu/dlg_config_world.lua
|
||||||
msgid "(Enabled, has error)"
|
msgid "(Enabled, has error)"
|
||||||
|
@ -967,21 +967,20 @@ msgstr ""
|
||||||
"akan menimpa penggantian nama yang ada."
|
"akan menimpa penggantian nama yang ada."
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Expand all"
|
msgid "Expand all"
|
||||||
msgstr "Nyalakan semua"
|
msgstr "Buka semua"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "Group by prefix"
|
msgid "Group by prefix"
|
||||||
msgstr ""
|
msgstr "Kelompokkan berdasarkan awalan"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses a game called $2 and the following mods:"
|
msgid "The $1 server uses a game called $2 and the following mods:"
|
||||||
msgstr ""
|
msgstr "Server $1 menggunakan permainan bernama $2 dan mod berikut:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses the following mods:"
|
msgid "The $1 server uses the following mods:"
|
||||||
msgstr ""
|
msgstr "Server $1 menggunakan mod berikut:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_version_info.lua
|
#: builtin/mainmenu/dlg_version_info.lua
|
||||||
msgid "A new $1 version is available"
|
msgid "A new $1 version is available"
|
||||||
|
@ -1193,20 +1192,20 @@ msgid "You need to install a game before you can create a world."
|
||||||
msgstr "Anda perlu pasang sebuah permainan sebelum bisa membuat dunia."
|
msgstr "Anda perlu pasang sebuah permainan sebelum bisa membuat dunia."
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Add favorite"
|
msgid "Add favorite"
|
||||||
msgstr "Hapus favorit"
|
msgstr "Tambahkan favorit"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Alamat"
|
msgstr "Alamat"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Clients:\n"
|
"Clients:\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr "Klien"
|
msgstr ""
|
||||||
|
"Klien:\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Creative mode"
|
msgid "Creative mode"
|
||||||
|
@ -1222,9 +1221,8 @@ msgid "Favorites"
|
||||||
msgstr "Favorit"
|
msgstr "Favorit"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Game: $1"
|
msgid "Game: $1"
|
||||||
msgstr "Permainan"
|
msgstr "Permainan: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Incompatible Servers"
|
msgid "Incompatible Servers"
|
||||||
|
@ -1239,14 +1237,12 @@ msgid "Login"
|
||||||
msgstr "Masuk"
|
msgstr "Masuk"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Number of mods: $1"
|
msgid "Number of mods: $1"
|
||||||
msgstr "Jumlah utas kemunculan"
|
msgstr "Jumlah mod: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Open server website"
|
msgid "Open server website"
|
||||||
msgstr "Langkah server khusus"
|
msgstr "Buka situs web server"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Ping"
|
msgid "Ping"
|
||||||
|
@ -1259,6 +1255,10 @@ msgid ""
|
||||||
"mod:<name>\n"
|
"mod:<name>\n"
|
||||||
"player:<name>"
|
"player:<name>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Filter yang memungkinkan\n"
|
||||||
|
"game:<nama>\n"
|
||||||
|
"mod:<nama>\n"
|
||||||
|
"player:<name>"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Public Servers"
|
msgid "Public Servers"
|
||||||
|
@ -1354,9 +1354,8 @@ msgid "Access denied. Reason: %s"
|
||||||
msgstr "Akses ditolak. Alasan: %s"
|
msgstr "Akses ditolak. Alasan: %s"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "All debug info hidden"
|
msgid "All debug info hidden"
|
||||||
msgstr "Info awakutu ditampilkan"
|
msgstr "Semua info awakutu disembunyikan"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Automatic forward disabled"
|
msgid "Automatic forward disabled"
|
||||||
|
@ -1380,7 +1379,7 @@ msgstr "Batasan blok ditampilkan untuk blok sekitar"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Bounding boxes shown"
|
msgid "Bounding boxes shown"
|
||||||
msgstr ""
|
msgstr "Kotak ikatan ditampilkan"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Camera update disabled"
|
msgid "Camera update disabled"
|
||||||
|
@ -1623,9 +1622,8 @@ msgid "Volume changed to %d%%"
|
||||||
msgstr "Volume diubah ke %d%%"
|
msgstr "Volume diubah ke %d%%"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Wireframe not supported by video driver"
|
msgid "Wireframe not supported by video driver"
|
||||||
msgstr "Shader dinyalakan, tetapi GLSL tidak didukung oleh pengandar."
|
msgstr "Kerangka tidak didukung oleh pengandar video"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Wireframe shown"
|
msgid "Wireframe shown"
|
||||||
|
@ -2058,9 +2056,8 @@ msgid "Failed to compile the \"%s\" shader."
|
||||||
msgstr "Gagal mengompilasi shader \"%s\"."
|
msgstr "Gagal mengompilasi shader \"%s\"."
|
||||||
|
|
||||||
#: src/client/shader.cpp
|
#: src/client/shader.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "GLSL is not supported by the driver"
|
msgid "GLSL is not supported by the driver"
|
||||||
msgstr "Shader dinyalakan, tetapi GLSL tidak didukung oleh pengandar."
|
msgstr "GLSL tidak didukung oleh pengandar"
|
||||||
|
|
||||||
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
||||||
#: src/content/mod_configuration.cpp
|
#: src/content/mod_configuration.cpp
|
||||||
|
@ -2297,35 +2294,33 @@ msgid "Sound Volume: %d%%"
|
||||||
msgstr "Volume Suara: %d%%"
|
msgstr "Volume Suara: %d%%"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Add button"
|
msgid "Add button"
|
||||||
msgstr "Klik Tengah"
|
msgstr "Tambahkan tombol"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Done"
|
msgid "Done"
|
||||||
msgstr "Selesai!"
|
msgstr "Selesai"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Server jarak jauh"
|
msgstr "Hapus"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr "Atur ulang"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Start dragging a button to add. Tap outside to cancel."
|
msgid "Start dragging a button to add. Tap outside to cancel."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Mulai menarik tombol untuk menambahkan. Ketuk di luar untuk membatalkan."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap a button to select it. Drag a button to move it."
|
msgid "Tap a button to select it. Drag a button to move it."
|
||||||
msgstr ""
|
msgstr "Ketuk tombol untuk memilih. Tarik tombol untuk memindahkan."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap outside to deselect."
|
msgid "Tap outside to deselect."
|
||||||
msgstr ""
|
msgstr "Ketuk di luar untuk membatalkan pilihan."
|
||||||
|
|
||||||
#: src/gui/touchscreenlayout.cpp
|
#: src/gui/touchscreenlayout.cpp
|
||||||
msgid "Joystick"
|
msgid "Joystick"
|
||||||
|
@ -2553,7 +2548,6 @@ msgid "3D noise that determines number of dungeons per mapchunk."
|
||||||
msgstr "Noise 3D yang mengatur jumlah dungeon per potongan peta."
|
msgstr "Noise 3D yang mengatur jumlah dungeon per potongan peta."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"3D support.\n"
|
"3D support.\n"
|
||||||
"Currently supported:\n"
|
"Currently supported:\n"
|
||||||
|
@ -2571,8 +2565,7 @@ msgstr ""
|
||||||
"- interlaced: garis ganjil/genap berdasarkan polarisasi layar.\n"
|
"- interlaced: garis ganjil/genap berdasarkan polarisasi layar.\n"
|
||||||
"- topbottom: pisahkan layar atas/bawah.\n"
|
"- topbottom: pisahkan layar atas/bawah.\n"
|
||||||
"- sidebyside: pisahkan layar kiri/kanan.\n"
|
"- sidebyside: pisahkan layar kiri/kanan.\n"
|
||||||
"- crossview: 3d dengan pandang silang\n"
|
"- crossview: 3d dengan pandang silang"
|
||||||
"Catat bahwa mode interlaced memerlukan penggunaan shader."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -2661,11 +2654,12 @@ msgid ""
|
||||||
"All mesh buffers with less than this number of vertices will be merged\n"
|
"All mesh buffers with less than this number of vertices will be merged\n"
|
||||||
"during map rendering. This improves rendering performance."
|
"during map rendering. This improves rendering performance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Semua penyangga jaring kurang dari jumlah verteks ini akan digabungkan\n"
|
||||||
|
"saat perenderan peta. Ini meningkatkan performa perenderan."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Allow clouds to look 3D instead of flat."
|
msgid "Allow clouds to look 3D instead of flat."
|
||||||
msgstr "Gunakan tampilan awan 3D alih-alih datar."
|
msgstr "Perbolehkan awan terlihat 3D daripada datar."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Allows liquids to be translucent."
|
msgid "Allows liquids to be translucent."
|
||||||
|
@ -3075,7 +3069,7 @@ msgstr "Awan dalam menu"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Color depth for post-processing texture"
|
msgid "Color depth for post-processing texture"
|
||||||
msgstr ""
|
msgstr "Kedalaman warna untuk tekstur pasca-pemrosesan"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Colored fog"
|
msgid "Colored fog"
|
||||||
|
@ -3095,7 +3089,6 @@ msgstr ""
|
||||||
"Berguna untuk pengujian. Lihat al_extensions.[h,cpp] untuk detailnya."
|
"Berguna untuk pengujian. Lihat al_extensions.[h,cpp] untuk detailnya."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Comma-separated list of flags to hide in the content repository.\n"
|
"Comma-separated list of flags to hide in the content repository.\n"
|
||||||
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
||||||
|
@ -3281,6 +3274,11 @@ msgid ""
|
||||||
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
||||||
"require more than 8 bits to work."
|
"require more than 8 bits to work."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Tentukan kedalaman warna tekstur yang digunakan untuk alur pasca-pemrosesan."
|
||||||
|
"\n"
|
||||||
|
"Mengurangi ini dapat meningkatkan performa, tetapi beberapa efek (mis. "
|
||||||
|
"debanding)\n"
|
||||||
|
"memerlukan lebih dari 8 bit supaya bekerja."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dedicated server step"
|
msgid "Dedicated server step"
|
||||||
|
@ -3500,6 +3498,11 @@ msgid ""
|
||||||
"situations\n"
|
"situations\n"
|
||||||
"where transparency sorting would be very slow otherwise."
|
"where transparency sorting would be very slow otherwise."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Gambar segitiga diurutkan berdasarkan transparansi berdasarkan penyangga "
|
||||||
|
"jaringnya.\n"
|
||||||
|
"Ini merusak pengurutan transparansi antara penyangga jaring, tetapi "
|
||||||
|
"menghindari situasi\n"
|
||||||
|
"di mana pengurutan transparansi akan menjadi lebih lambat."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dump the mapgen debug information."
|
msgid "Dump the mapgen debug information."
|
||||||
|
@ -3584,14 +3587,12 @@ msgstr ""
|
||||||
"menyimulasikan perilaku mata manusia."
|
"menyimulasikan perilaku mata manusia."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable colored shadows for transculent nodes.\n"
|
"Enable colored shadows for transculent nodes.\n"
|
||||||
"This is expensive."
|
"This is expensive."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Menyalakan bayangan berwarna.\n"
|
"Aktif kan bayangan berwarna untuk nodus translusen.\n"
|
||||||
"Nilai true berarti nodus agak tembus pandang memiliki bayangan berwarna. Ini "
|
"Ini komputasi mahal."
|
||||||
"memerlukan sumber daya besar."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable console window"
|
msgid "Enable console window"
|
||||||
|
@ -3670,14 +3671,12 @@ msgstr ""
|
||||||
"Contoh: 0 untuk tanpa view bobbing; 1.0 untuk normal; 2.0 untuk 2x lipat."
|
"Contoh: 0 untuk tanpa view bobbing; 1.0 untuk normal; 2.0 untuk 2x lipat."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable/disable running an IPv6 server.\n"
|
"Enable/disable running an IPv6 server.\n"
|
||||||
"Ignored if bind_address is set."
|
"Ignored if bind_address is set."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nyalakan/matikan server IPv6.\n"
|
"Aktif kan/nonaktifkan menjalankan server IPv6.\n"
|
||||||
"Diabaikan jika bind_address telah diatur.\n"
|
"Diabaikan jika bind_address telah diatur."
|
||||||
"Perlu menyalakan enable_ipv6."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -4323,14 +4322,14 @@ msgstr ""
|
||||||
"menggantinya dengan kata sandi kosong."
|
"menggantinya dengan kata sandi kosong."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"If enabled, server account registration is separate from login in the UI.\n"
|
"If enabled, server account registration is separate from login in the UI.\n"
|
||||||
"If disabled, connecting to a server will automatically register a new "
|
"If disabled, connecting to a server will automatically register a new "
|
||||||
"account."
|
"account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Jika dinyalakan, tampilan pendaftaran akun dan masuk akan dipisah.\n"
|
"Jika diaktifkan, pendaftaran akun server terpisah dari log masuk dalam UI.\n"
|
||||||
"Jika dimatikan, akun baru akan didaftarkan secara otomatis saat masuk."
|
"Jika dinonaktifkan, menghubungkan ke server akan mendaftarkan akun secara "
|
||||||
|
"otomatis."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5204,7 +5203,7 @@ msgstr "Batas minimal nilai acak untuk gua kecil per potongan peta."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Minimum vertex count for mesh buffers"
|
msgid "Minimum vertex count for mesh buffers"
|
||||||
msgstr ""
|
msgstr "Jumlah verteks minimum untuk penyangga jaring"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Mipmapping"
|
msgid "Mipmapping"
|
||||||
|
@ -5299,16 +5298,15 @@ msgstr ""
|
||||||
"- \"floatlands\" pada pembuat peta v7 (dimatikan secara bawaan)."
|
"- \"floatlands\" pada pembuat peta v7 (dimatikan secara bawaan)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Name of the player.\n"
|
"Name of the player.\n"
|
||||||
"When running a server, a client connecting with this name is admin.\n"
|
"When running a server, a client connecting with this name is admin.\n"
|
||||||
"When starting from the main menu, this is overridden."
|
"When starting from the main menu, this is overridden."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nama si pemain.\n"
|
"Nama pemain.\n"
|
||||||
"Saat menjalankan server, klien yang tersambung dengan nama ini adalah "
|
"Saat menjalankan server, klien yang tersambung dengan nama ini adalah admin."
|
||||||
"pengurus.\n"
|
"\n"
|
||||||
"Saat menjalankan dari menu utama, nilai ini ditimpa."
|
"Saat memulai dari menu utama, ini ditimpa."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5814,7 +5812,6 @@ msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
msgstr "Lihat https://www.sqlite.org/pragma.html#pragma_synchronous"
|
msgstr "Lihat https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select the antialiasing method to apply.\n"
|
"Select the antialiasing method to apply.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -5837,26 +5834,46 @@ msgid ""
|
||||||
"Renders higher-resolution image of the scene, then scales down to reduce\n"
|
"Renders higher-resolution image of the scene, then scales down to reduce\n"
|
||||||
"the aliasing effects. This is the slowest and the most accurate method."
|
"the aliasing effects. This is the slowest and the most accurate method."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Pilih metode antialiasing yang akan diterapkan.\n"
|
"Pilih metode antialiasing untuk diterapkan.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* Tidak ada - Tidak ada antialiasing (bawaan)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"* FSAA - Antialiasing layar penuh yang disediakan perangkat keras\n"
|
|
||||||
"(tidak kompatibel dengan Post Processing dan Undersampling)\n"
|
|
||||||
"Antialiasing multi-sampel (MSAA)\n"
|
|
||||||
"Menghaluskan tepi blok, tetapi tidak memengaruhi bagian dalam tekstur.\n"
|
|
||||||
"Diperlukan pengaktifan ulang untuk mengubah opsi ini.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"* FXAA - Antialiasing perkiraan cepat (memerlukan shader)\n"
|
"* Tidak ada - tidak ada antialiasing (default)\n"
|
||||||
"Menerapkan filter pasca-pemrosesan untuk mendeteksi dan memperhalus tepi "
|
"\n"
|
||||||
"yang sangat kontras.\n"
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"* FSAA-Antialiasing layar penuh yang disediakan perangkat keras\n"
|
||||||
|
"\n"
|
||||||
|
"A.k.a antialiasing multi-sampel (MSAA)\n"
|
||||||
|
"\n"
|
||||||
|
"Menghancur tepi blok tetapi tidak mempengaruhi bagian dalam tekstur.\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"Jika pemrosesan pos dinonaktifkan, mengubah FSAA memerlukan restart.\n"
|
||||||
|
"\n"
|
||||||
|
"Juga, jika pemrosesan pos dinonaktifkan, FSAA tidak akan bekerja sama "
|
||||||
|
"dengannya\n"
|
||||||
|
"\n"
|
||||||
|
"pengaturan undersampling atau non-default \"3D_MODE\".\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"* Fxaa - perkiraan cepat antialiasing\n"
|
||||||
|
"\n"
|
||||||
|
"Menerapkan filter pasca pemrosesan untuk mendeteksi dan menghaluskan tepi "
|
||||||
|
"kontras tinggi.\n"
|
||||||
|
"\n"
|
||||||
"Memberikan keseimbangan antara kecepatan dan kualitas gambar.\n"
|
"Memberikan keseimbangan antara kecepatan dan kualitas gambar.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* SSAA - Antialiasing super-sampling (memerlukan shader)\n"
|
"\n"
|
||||||
"Merender gambar pemandangan dengan resolusi lebih tinggi, kemudian "
|
"\n"
|
||||||
"memperkecil skala untuk mengurangi\n"
|
"* SSAA - Antialiasing Super -Sampling\n"
|
||||||
"mengurangi efek aliasing. Ini adalah metode yang paling lambat dan paling "
|
"\n"
|
||||||
"akurat."
|
"Membuat gambar resolusi yang lebih tinggi dari pemandangan itu, lalu "
|
||||||
|
"berskala ke bawah untuk mengurangi\n"
|
||||||
|
"\n"
|
||||||
|
"Efek aliasing. Ini adalah metode paling lambat dan paling akurat."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Selection box border color (R,G,B)."
|
msgid "Selection box border color (R,G,B)."
|
||||||
|
@ -6283,16 +6300,15 @@ msgstr ""
|
||||||
"semua) barang."
|
"semua) barang."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Spread a complete update of the shadow map over a given number of frames.\n"
|
"Spread a complete update of the shadow map over a given number of frames.\n"
|
||||||
"Higher values might make shadows laggy, lower values\n"
|
"Higher values might make shadows laggy, lower values\n"
|
||||||
"will consume more resources."
|
"will consume more resources."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Menyebarkan pembaruan peta bayangan dalam jumlah bingkai yang diberikan.\n"
|
"Sebarkan pembaruan lengkap peta bayangan pada sejumlah bingkai tertentu.\n"
|
||||||
"Nilai tinggi bisa membuat bayangan patah-patah, nilai rendah akan perlu\n"
|
"Nilai yang lebih tinggi mungkin membuat bayangan lambat, nilai yang lebih "
|
||||||
"sumber daya lebih banyak.\n"
|
"rendah\n"
|
||||||
"Nilai minimum: 1; nilai maksimum: 16"
|
"akan mengkonsumsi lebih banyak sumber daya."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6721,9 +6737,8 @@ msgid "Transparency Sorting Distance"
|
||||||
msgstr "Jarak Pengurutan Transparansi"
|
msgstr "Jarak Pengurutan Transparansi"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Transparency Sorting Group by Buffers"
|
msgid "Transparency Sorting Group by Buffers"
|
||||||
msgstr "Jarak Pengurutan Transparansi"
|
msgstr "Jarak Pengurutan Transparansi berdasarkan Penyangga"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Trees noise"
|
msgid "Trees noise"
|
||||||
|
@ -6783,7 +6798,6 @@ msgid "Undersampling"
|
||||||
msgstr "Undersampling(Pengambilan sampel yang terlalu rendah)"
|
msgstr "Undersampling(Pengambilan sampel yang terlalu rendah)"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
||||||
"to the game world only, keeping the GUI intact.\n"
|
"to the game world only, keeping the GUI intact.\n"
|
||||||
|
@ -6794,10 +6808,13 @@ msgid ""
|
||||||
"set\n"
|
"set\n"
|
||||||
"to a non-default value."
|
"to a non-default value."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Undersampling seperti menggunakan resolusi layar yang lebih rendah, tetapi\n"
|
"Undersampling hampir mirip seperti menggunakan resolusi layer yang lebih "
|
||||||
"hanya berlaku untuk dunia permainan saja, antarmuka grafis tetap.\n"
|
"rendah, tetapi hanya diterapkan ke dunia permainan saja sambil menjaga GUI.\n"
|
||||||
"Seharusnya memberikan dorongan kinerja dengan gambar yang kurang detail.\n"
|
"Ini seharusnya memberikan peningkatan performa dengan mengurangi detail "
|
||||||
"Nilai yang lebih tinggi menghasilkan gambar yang kurang detail."
|
"gambar.\n"
|
||||||
|
"Nilai yang lebih tinggi membuat detail gambar lebih sedikit.\n"
|
||||||
|
"Catatan: Undersampling saat ini tidak didukung jika pengaturan \"3d_mode\" "
|
||||||
|
"ditetapkan ke nilai non-bawaan."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Unlimited player transfer distance"
|
msgid "Unlimited player transfer distance"
|
||||||
|
@ -6824,12 +6841,13 @@ msgid "Use a cloud animation for the main menu background."
|
||||||
msgstr "Gunakan animasi awan untuk latar belakang menu utama."
|
msgstr "Gunakan animasi awan untuk latar belakang menu utama."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Use anisotropic filtering when looking at textures from an angle.\n"
|
"Use anisotropic filtering when looking at textures from an angle.\n"
|
||||||
"This provides a significant improvement when used together with mipmapping."
|
"This provides a significant improvement when used together with mipmapping."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Gunakan pemfilteran anisotropik saat melihat tekstur pada sudut tertentu."
|
"Gunakan pemfilteran anisotropik saat melihat tekstur pada sudut tertentu.\n"
|
||||||
|
"Ini menyediakan peningkatan yang lebih baik ketika digunakan bersama dengan "
|
||||||
|
"mipmapping."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Use bilinear filtering when scaling textures."
|
msgid "Use bilinear filtering when scaling textures."
|
||||||
|
@ -7102,7 +7120,6 @@ msgstr ""
|
||||||
"perangkat keras (misal gambar ke tekstur untuk nodus dalam inventaris)."
|
"perangkat keras (misal gambar ke tekstur untuk nodus dalam inventaris)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
||||||
"can be blurred, so this option automatically upscales them to preserve\n"
|
"can be blurred, so this option automatically upscales them to preserve\n"
|
||||||
|
@ -7113,15 +7130,18 @@ msgid ""
|
||||||
"This is also used as the base node texture size for world-aligned\n"
|
"This is also used as the base node texture size for world-aligned\n"
|
||||||
"texture autoscaling."
|
"texture autoscaling."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Saat menggunakan filter bilinear/trilinear/anisotropik, tekstur resolusi\n"
|
"Saat menggunakan pemfilteran bilinear/trilinear, tekstur resolusi rendah\n"
|
||||||
"rendah dapat dikaburkan sehingga diperbesar otomatis dengan interpolasi\n"
|
"bisa dikaburkan, jadi opsi ini secara otomatis meningkatkannya untuk "
|
||||||
"nearest-neighbor untuk menjaga ketajaman piksel. Ini mengatur ukuran\n"
|
"menjaga\n"
|
||||||
"tekstur minimum untuk tekstur yang diperbesar; semakin tinggi semakin\n"
|
"piksel tajam. Ini mendefinisikan ukuran tekstur minimum untuk tekstur yang "
|
||||||
"tajam, tetapi butuh memori lebih. Perpangkatan dua disarankan. Pengaturan\n"
|
"ditingkatkan;\n"
|
||||||
"ini HANYA diterapkan jika menggunakan filter bilinear/trilinear/"
|
"Nilai yang lebih tinggi terlihat lebih tajam, tetapi membutuhkan lebih "
|
||||||
"anisotropik.\n"
|
"banyak memori.\n"
|
||||||
"Ini juga digunakan sebagai ukuran dasar tekstur nodus untuk penyekalaan\n"
|
"Pengaturan ini hanya diterapkan jika salah satu filter yang disebutkan "
|
||||||
"otomatis tekstur yang sejajar dengan dunia."
|
"diaktifkan.\n"
|
||||||
|
"Ini juga digunakan sebagai ukuran tekstur simpul dasar untuk dunia yang "
|
||||||
|
"selaras\n"
|
||||||
|
"Tekstur Autoscaling."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -7156,16 +7176,15 @@ msgid "Whether to fog out the end of the visible area."
|
||||||
msgstr "Apakah harus memberi kabut pada akhir daerah yang terlihat."
|
msgstr "Apakah harus memberi kabut pada akhir daerah yang terlihat."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
||||||
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
||||||
"pause menu."
|
"pause menu."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Apakah akan membisukan suara atau tidak. Anda dapat membunyikan\n"
|
"Apakah suara dibisukan atau tidak. Kamu bisa membunyikan suara kapan pun.\n"
|
||||||
"suara kapan pun, kecuali sistem suara dimatikan (enable_sound = false).\n"
|
"Dalam permainan, kamu bisa sakelar keadaan bisu dengan tombol bisikan atau "
|
||||||
"Dalam permainan, Anda dapat beralih mode bisu dengan tombol bisu\n"
|
"menggunakan\n"
|
||||||
"atau melalui menu jeda."
|
"menu jeda."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
227
po/ru/luanti.po
227
po/ru/luanti.po
|
@ -3,7 +3,7 @@ msgstr ""
|
||||||
"Project-Id-Version: Russian (Minetest)\n"
|
"Project-Id-Version: Russian (Minetest)\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
"POT-Creation-Date: 2025-02-09 13:23+0100\n"
|
||||||
"PO-Revision-Date: 2025-01-27 06:02+0000\n"
|
"PO-Revision-Date: 2025-02-12 12:18+0000\n"
|
||||||
"Last-Translator: BlackImpostor <SkyBuilderOFFICAL@yandex.ru>\n"
|
"Last-Translator: BlackImpostor <SkyBuilderOFFICAL@yandex.ru>\n"
|
||||||
"Language-Team: Russian <https://hosted.weblate.org/projects/minetest/"
|
"Language-Team: Russian <https://hosted.weblate.org/projects/minetest/"
|
||||||
"minetest/ru/>\n"
|
"minetest/ru/>\n"
|
||||||
|
@ -264,14 +264,12 @@ msgid "Show technical names"
|
||||||
msgstr "Показывать технические названия"
|
msgstr "Показывать технические названия"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Touchscreen layout"
|
msgid "Touchscreen layout"
|
||||||
msgstr "Сенсорный экран"
|
msgstr "Pазложение сенсорного экрана"
|
||||||
|
|
||||||
#: builtin/common/settings/dlg_settings.lua
|
#: builtin/common/settings/dlg_settings.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "pause_menu"
|
msgid "pause_menu"
|
||||||
msgstr "Кадровая частота во время паузы"
|
msgstr "меню_паузы"
|
||||||
|
|
||||||
#: builtin/common/settings/settingtypes.lua
|
#: builtin/common/settings/settingtypes.lua
|
||||||
msgid "Client Mods"
|
msgid "Client Mods"
|
||||||
|
@ -609,6 +607,8 @@ msgid ""
|
||||||
"This is the list of clients connected to\n"
|
"This is the list of clients connected to\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Это список подключённых клиентов к\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_config_world.lua
|
#: builtin/mainmenu/dlg_config_world.lua
|
||||||
msgid "(Enabled, has error)"
|
msgid "(Enabled, has error)"
|
||||||
|
@ -972,21 +972,21 @@ msgstr ""
|
||||||
"перезапишет указанное здесь значение."
|
"перезапишет указанное здесь значение."
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Expand all"
|
msgid "Expand all"
|
||||||
msgstr "Включить всё"
|
msgstr "Расширить всё"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "Group by prefix"
|
msgid "Group by prefix"
|
||||||
msgstr ""
|
msgstr "Сгруппировать по префиксу"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses a game called $2 and the following mods:"
|
msgid "The $1 server uses a game called $2 and the following mods:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"На сервере $1 используется игра под названием $2 со следующими дополнениями:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_server_list_mods.lua
|
#: builtin/mainmenu/dlg_server_list_mods.lua
|
||||||
msgid "The $1 server uses the following mods:"
|
msgid "The $1 server uses the following mods:"
|
||||||
msgstr ""
|
msgstr "Сервер $1 использует следующие дополнения:"
|
||||||
|
|
||||||
#: builtin/mainmenu/dlg_version_info.lua
|
#: builtin/mainmenu/dlg_version_info.lua
|
||||||
msgid "A new $1 version is available"
|
msgid "A new $1 version is available"
|
||||||
|
@ -1198,20 +1198,20 @@ msgid "You need to install a game before you can create a world."
|
||||||
msgstr "Вам требуется установить игру, прежде чем вы сможете создать мир."
|
msgstr "Вам требуется установить игру, прежде чем вы сможете создать мир."
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Add favorite"
|
msgid "Add favorite"
|
||||||
msgstr "Удалить избранное"
|
msgstr "Добавить избранное"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Адрес"
|
msgstr "Адрес"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Clients:\n"
|
"Clients:\n"
|
||||||
"$1"
|
"$1"
|
||||||
msgstr "Клиент"
|
msgstr ""
|
||||||
|
"Клиенты:\n"
|
||||||
|
"$1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Creative mode"
|
msgid "Creative mode"
|
||||||
|
@ -1227,9 +1227,8 @@ msgid "Favorites"
|
||||||
msgstr "Избранное"
|
msgstr "Избранное"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Game: $1"
|
msgid "Game: $1"
|
||||||
msgstr "Игра"
|
msgstr "Игра: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Incompatible Servers"
|
msgid "Incompatible Servers"
|
||||||
|
@ -1244,14 +1243,12 @@ msgid "Login"
|
||||||
msgstr "Войти"
|
msgstr "Войти"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Number of mods: $1"
|
msgid "Number of mods: $1"
|
||||||
msgstr "Количество потоков подгрузки"
|
msgstr "Количество модов: $1"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
#, fuzzy
|
|
||||||
msgid "Open server website"
|
msgid "Open server website"
|
||||||
msgstr "Шаг выделенного сервера"
|
msgstr "Открыть веб-сайт сервера"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Ping"
|
msgid "Ping"
|
||||||
|
@ -1264,6 +1261,10 @@ msgid ""
|
||||||
"mod:<name>\n"
|
"mod:<name>\n"
|
||||||
"player:<name>"
|
"player:<name>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Возможные фильтры\n"
|
||||||
|
"игра:<имя>\n"
|
||||||
|
"дополнение:<имя>\n"
|
||||||
|
"игрок:<имя>"
|
||||||
|
|
||||||
#: builtin/mainmenu/tab_online.lua
|
#: builtin/mainmenu/tab_online.lua
|
||||||
msgid "Public Servers"
|
msgid "Public Servers"
|
||||||
|
@ -1359,9 +1360,8 @@ msgid "Access denied. Reason: %s"
|
||||||
msgstr "Доступ запрещён. Причина: %s"
|
msgstr "Доступ запрещён. Причина: %s"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "All debug info hidden"
|
msgid "All debug info hidden"
|
||||||
msgstr "Отладочные сведения отображены"
|
msgstr "Все отладочные сведения скрыты"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Automatic forward disabled"
|
msgid "Automatic forward disabled"
|
||||||
|
@ -1385,7 +1385,7 @@ msgstr "Границы показаны для ближайших мапблок
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Bounding boxes shown"
|
msgid "Bounding boxes shown"
|
||||||
msgstr ""
|
msgstr "Показаны ограничивающие рамки"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Camera update disabled"
|
msgid "Camera update disabled"
|
||||||
|
@ -1623,9 +1623,8 @@ msgid "Volume changed to %d%%"
|
||||||
msgstr "Громкость установлена на %d%%"
|
msgstr "Громкость установлена на %d%%"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Wireframe not supported by video driver"
|
msgid "Wireframe not supported by video driver"
|
||||||
msgstr "Шейдеры включены, но GLSL не поддерживается драйвером."
|
msgstr "Полигоны не доступны этим видео драйвером"
|
||||||
|
|
||||||
#: src/client/game.cpp
|
#: src/client/game.cpp
|
||||||
msgid "Wireframe shown"
|
msgid "Wireframe shown"
|
||||||
|
@ -2058,9 +2057,8 @@ msgid "Failed to compile the \"%s\" shader."
|
||||||
msgstr "Не удалось скомпилировать шейдер «%s»."
|
msgstr "Не удалось скомпилировать шейдер «%s»."
|
||||||
|
|
||||||
#: src/client/shader.cpp
|
#: src/client/shader.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "GLSL is not supported by the driver"
|
msgid "GLSL is not supported by the driver"
|
||||||
msgstr "Шейдеры включены, но GLSL не поддерживается драйвером."
|
msgstr "GLSL не поддерживается драйвером"
|
||||||
|
|
||||||
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
#. ~ Error when a mod is missing dependencies. Ex: "Mod Title is missing: mod1, mod2, mod3"
|
||||||
#: src/content/mod_configuration.cpp
|
#: src/content/mod_configuration.cpp
|
||||||
|
@ -2296,35 +2294,35 @@ msgid "Sound Volume: %d%%"
|
||||||
msgstr "Громкость звука: %d%%"
|
msgstr "Громкость звука: %d%%"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Add button"
|
msgid "Add button"
|
||||||
msgstr "Средняя кнопка"
|
msgstr "Добавить кнопку"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Done"
|
msgid "Done"
|
||||||
msgstr "Готово!"
|
msgstr "Готово"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Удалённый сервер"
|
msgstr "Убрать"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr "Сбросить"
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Start dragging a button to add. Tap outside to cancel."
|
msgid "Start dragging a button to add. Tap outside to cancel."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Начните перетаскивать кнопку, чтобы добавить. Нажмите \"За пределами\", "
|
||||||
|
"чтобы отменить."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap a button to select it. Drag a button to move it."
|
msgid "Tap a button to select it. Drag a button to move it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Нажмите на кнопку, чтобы выбрать её. Перетащите кнопку, чтобы перемещать её."
|
||||||
|
|
||||||
#: src/gui/touchscreeneditor.cpp
|
#: src/gui/touchscreeneditor.cpp
|
||||||
msgid "Tap outside to deselect."
|
msgid "Tap outside to deselect."
|
||||||
msgstr ""
|
msgstr "Нажмите \"Снаружи\", чтобы отменить выбор."
|
||||||
|
|
||||||
#: src/gui/touchscreenlayout.cpp
|
#: src/gui/touchscreenlayout.cpp
|
||||||
msgid "Joystick"
|
msgid "Joystick"
|
||||||
|
@ -2555,7 +2553,6 @@ msgid "3D noise that determines number of dungeons per mapchunk."
|
||||||
msgstr "3D-шум, определяющий количество подземелий на мапчанк карты."
|
msgstr "3D-шум, определяющий количество подземелий на мапчанк карты."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"3D support.\n"
|
"3D support.\n"
|
||||||
"Currently supported:\n"
|
"Currently supported:\n"
|
||||||
|
@ -2566,15 +2563,14 @@ msgid ""
|
||||||
"- sidebyside: split screen side by side.\n"
|
"- sidebyside: split screen side by side.\n"
|
||||||
"- crossview: Cross-eyed 3d"
|
"- crossview: Cross-eyed 3d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"3D-анаглиф.\n"
|
"Поддержка 3D.\n"
|
||||||
"Сейчас поддерживаются:\n"
|
"Сейчас поддерживаются:\n"
|
||||||
"- none: без 3D.\n"
|
"- none: без 3d выхода.\n"
|
||||||
"- anaglyph: для красно/синих очков.\n"
|
"- anaglyph: для красно/синих очков.\n"
|
||||||
"- interlaced: поляризация с чётными/нечётными линиями.\n"
|
"- interlaced: поляризация с чётными/нечётными линиями.\n"
|
||||||
"- topbottom: горизонтальное разделение экрана.\n"
|
"- topbottom: горизонтальное разделение экрана.\n"
|
||||||
"- sidebyside: вертикальное разделение экрана.\n"
|
"- sidebyside: вертикальное разделение экрана.\n"
|
||||||
"- crossview: перекрёстная стереопара.\n"
|
"- crossview: перекрёстная стереопара 3d"
|
||||||
"Примечание: для режима «interlaced» должны быть включены шейдеры."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -2663,11 +2659,12 @@ msgid ""
|
||||||
"All mesh buffers with less than this number of vertices will be merged\n"
|
"All mesh buffers with less than this number of vertices will be merged\n"
|
||||||
"during map rendering. This improves rendering performance."
|
"during map rendering. This improves rendering performance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Все буферы мешей с меньшим количеством вершин будут объединены\n"
|
||||||
|
"во время рендера карты. Это повышает производительность рендеринга."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Allow clouds to look 3D instead of flat."
|
msgid "Allow clouds to look 3D instead of flat."
|
||||||
msgstr "Объёмные облака вместо плоских."
|
msgstr "Позволяет облакам выглядеть больше 3D, чем плоскими."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Allows liquids to be translucent."
|
msgid "Allows liquids to be translucent."
|
||||||
|
@ -3080,7 +3077,7 @@ msgstr "Облака в меню"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Color depth for post-processing texture"
|
msgid "Color depth for post-processing texture"
|
||||||
msgstr ""
|
msgstr "Глубина цвета для постобработки текстуры"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Colored fog"
|
msgid "Colored fog"
|
||||||
|
@ -3101,7 +3098,6 @@ msgstr ""
|
||||||
"[h,cpp]."
|
"[h,cpp]."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Comma-separated list of flags to hide in the content repository.\n"
|
"Comma-separated list of flags to hide in the content repository.\n"
|
||||||
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
"\"nonfree\" can be used to hide packages which do not qualify as 'free "
|
||||||
|
@ -3112,12 +3108,12 @@ msgid ""
|
||||||
"so see a full list at https://content.luanti.org/help/content_flags/"
|
"so see a full list at https://content.luanti.org/help/content_flags/"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Список разделенных запятыми флажков для скрытия в хранилище контента.\n"
|
"Список разделенных запятыми флажков для скрытия в хранилище контента.\n"
|
||||||
"\"nonfree\" может использоваться для скрытия пакетов,\n"
|
"«несвободный» может использоваться для скрытия пакетов, которые не подпадают "
|
||||||
"которые не подпадают под категорию Free Software Foundation,\n"
|
"под категорию «свободного программного обеспечения»,\n"
|
||||||
"как это определено Фондом свободного программного обеспечения.\n"
|
"как это определено Фондом Свободного Программного Обеспечения.\n"
|
||||||
"Вы также можете указать рейтинг контента. Эти флаги не зависят от версий "
|
"Вы также можете указать рейтинг контента.\n"
|
||||||
"Luanti,\n"
|
"Эти флаги не зависят от версий Luanti,\n"
|
||||||
"поэтому смотрите полный список по адресу https://content.minetest.net/help/"
|
"поэтому смотрите полный список по адресу https://content.luanti.org/help/"
|
||||||
"content_flags/"
|
"content_flags/"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
|
@ -3287,6 +3283,11 @@ msgid ""
|
||||||
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
"Reducing this can improve performance, but some effects (e.g. debanding)\n"
|
||||||
"require more than 8 bits to work."
|
"require more than 8 bits to work."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Определить глубину цвета текстуры, используемой для конвейера постобработки."
|
||||||
|
"\n"
|
||||||
|
"Уменьшение этого параметра может повысить производительность, но для работы "
|
||||||
|
"некоторых эффектов (например, для удаления пятен)\n"
|
||||||
|
"требуется более 8 бит."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dedicated server step"
|
msgid "Dedicated server step"
|
||||||
|
@ -3507,6 +3508,11 @@ msgid ""
|
||||||
"situations\n"
|
"situations\n"
|
||||||
"where transparency sorting would be very slow otherwise."
|
"where transparency sorting would be very slow otherwise."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Рисовать треугольники, отсортированные по прозрачности, сгруппированные по "
|
||||||
|
"их меш буферам.\n"
|
||||||
|
"Это нарушает сортировку по прозрачности между меш буферами, но позволяет "
|
||||||
|
"избежать ситуаций,\n"
|
||||||
|
"когда в противном случае сортировка по прозрачности была бы очень медленной."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Dump the mapgen debug information."
|
msgid "Dump the mapgen debug information."
|
||||||
|
@ -3591,14 +3597,12 @@ msgstr ""
|
||||||
"имитируя поведение человеческого глаза."
|
"имитируя поведение человеческого глаза."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable colored shadows for transculent nodes.\n"
|
"Enable colored shadows for transculent nodes.\n"
|
||||||
"This is expensive."
|
"This is expensive."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Включить цветные тени.\n"
|
"Включите цветные тени для трансгенных блоков.\n"
|
||||||
"Когда включено, прозрачные ноды отбрасывают цветные тени. Это "
|
"Это дорого."
|
||||||
"ресурсозатратно."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Enable console window"
|
msgid "Enable console window"
|
||||||
|
@ -3681,14 +3685,12 @@ msgstr ""
|
||||||
"Например: 0 отключает покачивание, 1.0 для обычного, 2.0 для двойного."
|
"Например: 0 отключает покачивание, 1.0 для обычного, 2.0 для двойного."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enable/disable running an IPv6 server.\n"
|
"Enable/disable running an IPv6 server.\n"
|
||||||
"Ignored if bind_address is set."
|
"Ignored if bind_address is set."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Включить/отключить запуск IPv6-сервера.\n"
|
"Включить/отключить запуск сервера IPv6.\n"
|
||||||
"Игнорируется, если задан «bind_address».\n"
|
"Игнорируется, если задан параметр bind_address."
|
||||||
"Для включения необходим «enable_ipv6»."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -4333,16 +4335,15 @@ msgstr ""
|
||||||
"Если включено, то новые игроки не смогут подключаться с пустым паролем."
|
"Если включено, то новые игроки не смогут подключаться с пустым паролем."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"If enabled, server account registration is separate from login in the UI.\n"
|
"If enabled, server account registration is separate from login in the UI.\n"
|
||||||
"If disabled, connecting to a server will automatically register a new "
|
"If disabled, connecting to a server will automatically register a new "
|
||||||
"account."
|
"account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Если включено, регистрация аккаунта выполняется в интерфейсе отдельно от "
|
"Если этот параметр включен, регистрация учетной записи сервера выполняется "
|
||||||
"входа.\n"
|
"отдельно от входа в пользовательский интерфейс.\n"
|
||||||
"Если отключено, новые учётные записи будут регистрироваться автоматически "
|
"Если он отключен, при подключении к серверу автоматически регистрируется "
|
||||||
"при входе."
|
"новая учетная запись."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5212,7 +5213,7 @@ msgstr "Минимум малых пещер на мапчанк."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Minimum vertex count for mesh buffers"
|
msgid "Minimum vertex count for mesh buffers"
|
||||||
msgstr ""
|
msgstr "Минимальное количество вершин для меш буферов"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Mipmapping"
|
msgid "Mipmapping"
|
||||||
|
@ -5307,15 +5308,15 @@ msgstr ""
|
||||||
"- Дополнительные парящие острова из v7 (выключено по умолчанию)."
|
"- Дополнительные парящие острова из v7 (выключено по умолчанию)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Name of the player.\n"
|
"Name of the player.\n"
|
||||||
"When running a server, a client connecting with this name is admin.\n"
|
"When running a server, a client connecting with this name is admin.\n"
|
||||||
"When starting from the main menu, this is overridden."
|
"When starting from the main menu, this is overridden."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Имя игрока.\n"
|
"Имя игрока.\n"
|
||||||
"При запуске сервера клиенты с этим именем будут администраторами.\n"
|
"При запуске сервера клиент, подключающийся под этим именем, является "
|
||||||
"Будет переопределено при запуске из главного меню."
|
"администратором.\n"
|
||||||
|
"При запуске из главного меню это значение переопределяется."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -5824,7 +5825,6 @@ msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
msgstr "См. http://www.sqlite.org/pragma.html#pragma_synchronous"
|
msgstr "См. http://www.sqlite.org/pragma.html#pragma_synchronous"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select the antialiasing method to apply.\n"
|
"Select the antialiasing method to apply.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -5849,25 +5849,27 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Выберите метод сглаживания, который необходимо применить.\n"
|
"Выберите метод сглаживания, который необходимо применить.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* * Нет - сглаживание отсутствует (по умолчанию).\n"
|
"* None - Нет сглаживания (по умолчанию)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* FSAA - Аппаратное полноэкранное сглаживание\n"
|
"* FSAA - Аппаратное полноэкранное сглаживание,\n"
|
||||||
"(несовместимое с постобработкой и недостаточной дискретизацией)\n"
|
"аналогичное сглаживанию с несколькими выборками (MSAA).\n"
|
||||||
", аналогичное сглаживанию с несколькими выборками (MSAA)\n"
|
|
||||||
"Сглаживает края блоков, но не влияет на внутреннюю часть текстур.\n"
|
"Сглаживает края блоков, но не влияет на внутреннюю часть текстур.\n"
|
||||||
"Для изменения этого параметра требуется перезагрузка.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"* FXAA - Быстрое приблизительное сглаживание (требуется использование "
|
"Если постобработка отключена, для изменения FSAA требуется перезапуск.\n"
|
||||||
"шейдеров)\n"
|
"Кроме того, если постобработка отключена, FSAA не будет работать в сочетании "
|
||||||
"Применяется фильтр последующей обработки для обнаружения и сглаживания "
|
"с\n"
|
||||||
|
"недостаточной дискретизацией или настройкой \"3d_mode\", не используемой по "
|
||||||
|
"умолчанию.\n"
|
||||||
|
"\n"
|
||||||
|
"* FXAA - Быстрое приблизительное сглаживание\n"
|
||||||
|
"Применяет фильтр последующей обработки для обнаружения и сглаживания "
|
||||||
"высококонтрастных краев.\n"
|
"высококонтрастных краев.\n"
|
||||||
"Обеспечивает баланс между скоростью и качеством изображения.\n"
|
"Обеспечивает баланс между скоростью и качеством изображения.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"* SSAA - сглаживание с использованием суперсэмплирования (требуются "
|
"* SSAA - Сглаживание с использованием суперсэмплирования\n"
|
||||||
"шейдеры)\n"
|
"Позволяет получить изображение сцены с более высоким разрешением, а затем "
|
||||||
"Визуализирует изображение сцены с более высоким разрешением, затем уменьшает "
|
"уменьшить масштаб, чтобы уменьшить\n"
|
||||||
"масштаб, чтобы уменьшить\n"
|
"эффекты сглаживания. Это самый медленный и точный метод."
|
||||||
"эффекты наложения. Это самый медленный и точный метод."
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Selection box border color (R,G,B)."
|
msgid "Selection box border color (R,G,B)."
|
||||||
|
@ -6300,17 +6302,14 @@ msgstr ""
|
||||||
"(или всех) предметов."
|
"(или всех) предметов."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Spread a complete update of the shadow map over a given number of frames.\n"
|
"Spread a complete update of the shadow map over a given number of frames.\n"
|
||||||
"Higher values might make shadows laggy, lower values\n"
|
"Higher values might make shadows laggy, lower values\n"
|
||||||
"will consume more resources."
|
"will consume more resources."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Распространяет полное обновление карты теней на заданное количество кадров.\n"
|
"Распространить полное обновление карты теней на заданное количество кадров.\n"
|
||||||
"Более высокие значения могут сделать тени нестабильными, более низкие "
|
"Более высокие значения могут привести к запаздыванию теней,\n"
|
||||||
"значения\n"
|
"более низкие значения потребляют больше ресурсов."
|
||||||
"будут потреблять больше ресурсов.\n"
|
|
||||||
"Минимум: 1; максимум: 16"
|
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -6753,9 +6752,8 @@ msgid "Transparency Sorting Distance"
|
||||||
msgstr "Дальность сортировки по прозрачности"
|
msgstr "Дальность сортировки по прозрачности"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid "Transparency Sorting Group by Buffers"
|
msgid "Transparency Sorting Group by Buffers"
|
||||||
msgstr "Дальность сортировки по прозрачности"
|
msgstr "Прозрачность Сортировки Групп по Буферам"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Trees noise"
|
msgid "Trees noise"
|
||||||
|
@ -6816,7 +6814,6 @@ msgid "Undersampling"
|
||||||
msgstr "Субдискретизация"
|
msgstr "Субдискретизация"
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
"Undersampling is similar to using a lower screen resolution, but it applies\n"
|
||||||
"to the game world only, keeping the GUI intact.\n"
|
"to the game world only, keeping the GUI intact.\n"
|
||||||
|
@ -6827,12 +6824,15 @@ msgid ""
|
||||||
"set\n"
|
"set\n"
|
||||||
"to a non-default value."
|
"to a non-default value."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Субдискретизация аналогична использованию низкого разрешения экрана,\n"
|
"Недостаточная дискретизация аналогична использованию более низкого "
|
||||||
"но она применяется только к игровому миру, графический интерфейс не "
|
"разрешения экрана, но применяется\n"
|
||||||
"затрагивается.\n"
|
"только к игровому миру, сохраняя графический интерфейс без изменений.\n"
|
||||||
"Значительно увеличивает производительность за счёт вывода менее подробного "
|
"Это должно значительно повысить производительность за счет снижения "
|
||||||
"изображения.\n"
|
"детализации изображения.\n"
|
||||||
"Высокие значения приводят к менее проработанному изображению."
|
"Более высокие значения приводят к снижению детализации изображения.\n"
|
||||||
|
"Примечание: В настоящее время недостаточная дискретизация не поддерживается, "
|
||||||
|
"если для параметра \"3d_mode\" установлено\n"
|
||||||
|
"значение, отличное от значения по умолчанию."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Unlimited player transfer distance"
|
msgid "Unlimited player transfer distance"
|
||||||
|
@ -6859,12 +6859,13 @@ msgid "Use a cloud animation for the main menu background."
|
||||||
msgstr "Анимированные облака в главном меню."
|
msgstr "Анимированные облака в главном меню."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Use anisotropic filtering when looking at textures from an angle.\n"
|
"Use anisotropic filtering when looking at textures from an angle.\n"
|
||||||
"This provides a significant improvement when used together with mipmapping."
|
"This provides a significant improvement when used together with mipmapping."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Использовать анизотропную фильтрацию при взгляде на текстуры под углом."
|
"Использовать анизотропную фильтрацию при просмотре текстур под углом.\n"
|
||||||
|
"Это обеспечивает значительное улучшение при использовании в сочетании с "
|
||||||
|
"мип-картированием."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid "Use bilinear filtering when scaling textures."
|
msgid "Use bilinear filtering when scaling textures."
|
||||||
|
@ -7138,7 +7139,6 @@ msgstr ""
|
||||||
"аппаратно (прим. render-to-texture для нод в инвентаре)."
|
"аппаратно (прим. render-to-texture для нод в инвентаре)."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
"When using bilinear/trilinear filtering, low-resolution textures\n"
|
||||||
"can be blurred, so this option automatically upscales them to preserve\n"
|
"can be blurred, so this option automatically upscales them to preserve\n"
|
||||||
|
@ -7149,17 +7149,17 @@ msgid ""
|
||||||
"This is also used as the base node texture size for world-aligned\n"
|
"This is also used as the base node texture size for world-aligned\n"
|
||||||
"texture autoscaling."
|
"texture autoscaling."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Когда используются билинейный/трилинейный/анизотропный фильтры, то текстуры "
|
"При использовании билинейной/трилинейной фильтрации текстуры с низким "
|
||||||
"низкого разрешения\n"
|
"разрешением\n"
|
||||||
"могут быть размытыми, поэтому они автоматически увеличиваются ближайшей\n"
|
"могут быть размыты, поэтому этот параметр автоматически увеличивает их "
|
||||||
"интерполяцией для сохранения четкости пикселей. Это устанавливает "
|
"масштаб, чтобы сохранить\n"
|
||||||
"минимальный размер текстуры\n"
|
"четкие пиксели. Это определяет минимальный размер текстуры для текстур в "
|
||||||
"для увеличенных текстур; большие значения выглядят чётче, но требуют больше\n"
|
"увеличенном масштабе;\n"
|
||||||
"памяти. Рекомендуются степени числа 2. Эта настройки применяется ТОЛЬКО "
|
"более высокие значения выглядят четче, но требуют больше памяти.\n"
|
||||||
"если\n"
|
"Этот параметр применяется ТОЛЬКО в том случае, если включен любой из "
|
||||||
"билинейный/трилинейный/анизотропный фильтр включен.\n"
|
"упомянутых фильтров.\n"
|
||||||
"Это также используется для автомасштабирования как основной размер для\n"
|
"Он также используется в качестве базового размера текстуры узла для\n"
|
||||||
"повёрнутых по сторонам света текстур блока."
|
"автоматического масштабирования текстуры, выровненной по окружности."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -7194,16 +7194,15 @@ msgid "Whether to fog out the end of the visible area."
|
||||||
msgstr "Затуманивает конец видимой области."
|
msgstr "Затуманивает конец видимой области."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
"Whether to mute sounds. You can unmute sounds at any time.\n"
|
||||||
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
"In-game, you can toggle the mute state with the mute key or by using the\n"
|
||||||
"pause menu."
|
"pause menu."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Заглушает звуки. Вы можете включить звуки в любое время, если\n"
|
"Следует ли отключать звук. Вы можете включить звук в любое время.\n"
|
||||||
"звуковая система не отключена (enable_sound=false).\n"
|
"В игре вы можете переключать режим отключения звука с помощью клавиши "
|
||||||
"Внутри игры, вы можете включить переключать звуки, нажав на клавишу\n"
|
"отключения звука\n"
|
||||||
"заглушения звука или используя меню паузы."
|
"или с помощью меню паузы."
|
||||||
|
|
||||||
#: src/settings_translation_file.cpp
|
#: src/settings_translation_file.cpp
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
6445
po/yue/luanti.po
6445
po/yue/luanti.po
File diff suppressed because it is too large
Load diff
|
@ -34,7 +34,7 @@ static constexpr f32 CAMERA_OFFSET_STEP = 200;
|
||||||
#define WIELDMESH_AMPLITUDE_Y 10.0f
|
#define WIELDMESH_AMPLITUDE_Y 10.0f
|
||||||
|
|
||||||
static const char *setting_names[] = {
|
static const char *setting_names[] = {
|
||||||
"fall_bobbing_amount", "view_bobbing_amount", "fov", "arm_inertia",
|
"view_bobbing_amount", "fov", "arm_inertia",
|
||||||
"show_nametag_backgrounds",
|
"show_nametag_backgrounds",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,7 +78,6 @@ void Camera::readSettings()
|
||||||
* (as opposed to the this local caching). This can be addressed in
|
* (as opposed to the this local caching). This can be addressed in
|
||||||
* a later release.
|
* a later release.
|
||||||
*/
|
*/
|
||||||
m_cache_fall_bobbing_amount = g_settings->getFloat("fall_bobbing_amount", 0.0f, 100.0f);
|
|
||||||
m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount", 0.0f, 7.9f);
|
m_cache_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount", 0.0f, 7.9f);
|
||||||
// 45 degrees is the lowest FOV that doesn't cause the server to treat this
|
// 45 degrees is the lowest FOV that doesn't cause the server to treat this
|
||||||
// as a zoom FOV and load world beyond the set server limits.
|
// as a zoom FOV and load world beyond the set server limits.
|
||||||
|
@ -130,13 +129,6 @@ inline f32 my_modf(f32 x)
|
||||||
|
|
||||||
void Camera::step(f32 dtime)
|
void Camera::step(f32 dtime)
|
||||||
{
|
{
|
||||||
if(m_view_bobbing_fall > 0)
|
|
||||||
{
|
|
||||||
m_view_bobbing_fall -= 3 * dtime;
|
|
||||||
if(m_view_bobbing_fall <= 0)
|
|
||||||
m_view_bobbing_fall = -1; // Mark the effect as finished
|
|
||||||
}
|
|
||||||
|
|
||||||
bool was_under_zero = m_wield_change_timer < 0;
|
bool was_under_zero = m_wield_change_timer < 0;
|
||||||
m_wield_change_timer = MYMIN(m_wield_change_timer + dtime, 0.125);
|
m_wield_change_timer = MYMIN(m_wield_change_timer + dtime, 0.125);
|
||||||
|
|
||||||
|
@ -351,30 +343,13 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio)
|
||||||
// Get camera tilt timer (hurt animation)
|
// Get camera tilt timer (hurt animation)
|
||||||
float cameratilt = fabs(fabs(player->hurt_tilt_timer-0.75)-0.75);
|
float cameratilt = fabs(fabs(player->hurt_tilt_timer-0.75)-0.75);
|
||||||
|
|
||||||
// Fall bobbing animation
|
|
||||||
float fall_bobbing = 0;
|
|
||||||
if(player->camera_impact >= 1 && m_camera_mode < CAMERA_MODE_THIRD)
|
|
||||||
{
|
|
||||||
if(m_view_bobbing_fall == -1) // Effect took place and has finished
|
|
||||||
player->camera_impact = m_view_bobbing_fall = 0;
|
|
||||||
else if(m_view_bobbing_fall == 0) // Initialize effect
|
|
||||||
m_view_bobbing_fall = 1;
|
|
||||||
|
|
||||||
// Convert 0 -> 1 to 0 -> 1 -> 0
|
|
||||||
fall_bobbing = m_view_bobbing_fall < 0.5 ? m_view_bobbing_fall * 2 : -(m_view_bobbing_fall - 0.5) * 2 + 1;
|
|
||||||
// Smoothen and invert the above
|
|
||||||
fall_bobbing = sin(fall_bobbing * 0.5 * M_PI) * -1;
|
|
||||||
// Amplify according to the intensity of the impact
|
|
||||||
if (player->camera_impact > 0.0f)
|
|
||||||
fall_bobbing *= (1 - rangelim(50 / player->camera_impact, 0, 1)) * 5;
|
|
||||||
|
|
||||||
fall_bobbing *= m_cache_fall_bobbing_amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate and translate the head SceneNode offsets
|
// Calculate and translate the head SceneNode offsets
|
||||||
{
|
{
|
||||||
v3f eye_offset = player->getEyeOffset();
|
v3f eye_offset = player->getEyeOffset();
|
||||||
switch(m_camera_mode) {
|
switch(m_camera_mode) {
|
||||||
|
case CAMERA_MODE_ANY:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
case CAMERA_MODE_FIRST:
|
case CAMERA_MODE_FIRST:
|
||||||
eye_offset += player->eye_offset_first;
|
eye_offset += player->eye_offset_first;
|
||||||
break;
|
break;
|
||||||
|
@ -389,7 +364,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set head node transformation
|
// Set head node transformation
|
||||||
eye_offset.Y += cameratilt * -player->hurt_tilt_strength + fall_bobbing;
|
eye_offset.Y += cameratilt * -player->hurt_tilt_strength;
|
||||||
m_headnode->setPosition(eye_offset);
|
m_headnode->setPosition(eye_offset);
|
||||||
m_headnode->setRotation(v3f(pitch, 0,
|
m_headnode->setRotation(v3f(pitch, 0,
|
||||||
cameratilt * player->hurt_tilt_strength));
|
cameratilt * player->hurt_tilt_strength));
|
||||||
|
|
|
@ -57,8 +57,6 @@ struct Nametag
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Client camera class, manages the player and camera scene nodes, the viewing distance
|
Client camera class, manages the player and camera scene nodes, the viewing distance
|
||||||
and performs view bobbing etc. It also displays the wielded tool in front of the
|
and performs view bobbing etc. It also displays the wielded tool in front of the
|
||||||
|
@ -169,7 +167,8 @@ public:
|
||||||
void drawWieldedTool(irr::core::matrix4* translation=NULL);
|
void drawWieldedTool(irr::core::matrix4* translation=NULL);
|
||||||
|
|
||||||
// Toggle the current camera mode
|
// Toggle the current camera mode
|
||||||
void toggleCameraMode() {
|
void toggleCameraMode()
|
||||||
|
{
|
||||||
if (m_camera_mode == CAMERA_MODE_FIRST)
|
if (m_camera_mode == CAMERA_MODE_FIRST)
|
||||||
m_camera_mode = CAMERA_MODE_THIRD;
|
m_camera_mode = CAMERA_MODE_THIRD;
|
||||||
else if (m_camera_mode == CAMERA_MODE_THIRD)
|
else if (m_camera_mode == CAMERA_MODE_THIRD)
|
||||||
|
@ -185,7 +184,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//read the current camera mode
|
//read the current camera mode
|
||||||
inline CameraMode getCameraMode()
|
inline CameraMode getCameraMode() const
|
||||||
{
|
{
|
||||||
return m_camera_mode;
|
return m_camera_mode;
|
||||||
}
|
}
|
||||||
|
@ -257,8 +256,6 @@ private:
|
||||||
s32 m_view_bobbing_state = 0;
|
s32 m_view_bobbing_state = 0;
|
||||||
// Speed of view bobbing animation
|
// Speed of view bobbing animation
|
||||||
f32 m_view_bobbing_speed = 0.0f;
|
f32 m_view_bobbing_speed = 0.0f;
|
||||||
// Fall view bobbing
|
|
||||||
f32 m_view_bobbing_fall = 0.0f;
|
|
||||||
|
|
||||||
// Digging animation frame (0 <= m_digging_anim < 1)
|
// Digging animation frame (0 <= m_digging_anim < 1)
|
||||||
f32 m_digging_anim = 0.0f;
|
f32 m_digging_anim = 0.0f;
|
||||||
|
@ -273,7 +270,6 @@ private:
|
||||||
|
|
||||||
CameraMode m_camera_mode = CAMERA_MODE_FIRST;
|
CameraMode m_camera_mode = CAMERA_MODE_FIRST;
|
||||||
|
|
||||||
f32 m_cache_fall_bobbing_amount;
|
|
||||||
f32 m_cache_view_bobbing_amount;
|
f32 m_cache_view_bobbing_amount;
|
||||||
bool m_arm_inertia;
|
bool m_arm_inertia;
|
||||||
|
|
||||||
|
|
|
@ -398,11 +398,7 @@ void Client::step(float dtime)
|
||||||
if (dtime > DTIME_LIMIT)
|
if (dtime > DTIME_LIMIT)
|
||||||
dtime = DTIME_LIMIT;
|
dtime = DTIME_LIMIT;
|
||||||
|
|
||||||
m_animation_time += dtime;
|
m_animation_time = fmodf(m_animation_time + dtime, 60.0f);
|
||||||
if(m_animation_time > 60.0)
|
|
||||||
m_animation_time -= 60.0;
|
|
||||||
|
|
||||||
m_time_of_day_update_timer += dtime;
|
|
||||||
|
|
||||||
ReceiveAll();
|
ReceiveAll();
|
||||||
|
|
||||||
|
@ -450,20 +446,43 @@ void Client::step(float dtime)
|
||||||
/*
|
/*
|
||||||
Run Map's timers and unload unused data
|
Run Map's timers and unload unused data
|
||||||
*/
|
*/
|
||||||
const float map_timer_and_unload_dtime = 5.25;
|
constexpr float map_timer_and_unload_dtime = 5.25f;
|
||||||
|
constexpr s32 mapblock_limit_enforce_distance = 200;
|
||||||
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) {
|
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) {
|
||||||
std::vector<v3s16> deleted_blocks;
|
std::vector<v3s16> deleted_blocks;
|
||||||
|
|
||||||
|
// Determine actual block limit to use
|
||||||
|
const s32 configured_limit = g_settings->getS32("client_mapblock_limit");
|
||||||
|
s32 mapblock_limit;
|
||||||
|
if (configured_limit < 0) {
|
||||||
|
mapblock_limit = -1;
|
||||||
|
} else {
|
||||||
|
s32 view_range = g_settings->getS16("viewing_range");
|
||||||
|
// Up to a certain limit we want to guarantee that the client can keep
|
||||||
|
// a full 360° view loaded in memory without blocks vanishing behind
|
||||||
|
// the players back.
|
||||||
|
// We use a sphere volume to approximate this. In practice far less
|
||||||
|
// blocks will be needed due to occlusion/culling.
|
||||||
|
float blocks_range = ceilf(std::min(mapblock_limit_enforce_distance, view_range)
|
||||||
|
/ (float) MAP_BLOCKSIZE);
|
||||||
|
mapblock_limit = (4.f/3.f) * M_PI * powf(blocks_range, 3);
|
||||||
|
assert(mapblock_limit > 0);
|
||||||
|
mapblock_limit = std::max(mapblock_limit, configured_limit);
|
||||||
|
if (mapblock_limit > std::max(configured_limit, m_mapblock_limit_logged)) {
|
||||||
|
infostream << "Client: using block limit of " << mapblock_limit
|
||||||
|
<< " rather than configured " << configured_limit
|
||||||
|
<< " due to view range." << std::endl;
|
||||||
|
m_mapblock_limit_logged = mapblock_limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
|
m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
|
||||||
std::max(g_settings->getFloat("client_unload_unused_data_timeout"), 0.0f),
|
std::max(g_settings->getFloat("client_unload_unused_data_timeout"), 0.0f),
|
||||||
g_settings->getS32("client_mapblock_limit"),
|
mapblock_limit, &deleted_blocks);
|
||||||
&deleted_blocks);
|
|
||||||
|
|
||||||
/*
|
// Send info to server
|
||||||
Send info to server
|
|
||||||
NOTE: This loop is intentionally iterated the way it is.
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::vector<v3s16>::iterator i = deleted_blocks.begin();
|
auto i = deleted_blocks.begin();
|
||||||
std::vector<v3s16> sendlist;
|
std::vector<v3s16> sendlist;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(sendlist.size() == 255 || i == deleted_blocks.end()) {
|
if(sendlist.size() == 255 || i == deleted_blocks.end()) {
|
||||||
|
@ -644,9 +663,11 @@ void Client::step(float dtime)
|
||||||
if (num_processed_meshes > 0)
|
if (num_processed_meshes > 0)
|
||||||
g_profiler->graphAdd("num_processed_meshes", num_processed_meshes);
|
g_profiler->graphAdd("num_processed_meshes", num_processed_meshes);
|
||||||
|
|
||||||
auto shadow_renderer = RenderingEngine::get_shadow_renderer();
|
if (force_update_shadows && !g_settings->getFlag("performance_tradeoffs")) {
|
||||||
if (shadow_renderer && force_update_shadows)
|
auto shadow = RenderingEngine::get_shadow_renderer();
|
||||||
shadow_renderer->setForceUpdateShadowMap();
|
if (shadow)
|
||||||
|
shadow->setForceUpdateShadowMap();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -873,14 +894,6 @@ void Client::deletingPeer(con::IPeer *peer, bool timeout)
|
||||||
m_access_denied_reason = gettext("Connection aborted (protocol error?).");
|
m_access_denied_reason = gettext("Connection aborted (protocol error?).");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
u16 command
|
|
||||||
u16 number of files requested
|
|
||||||
for each file {
|
|
||||||
u16 length of name
|
|
||||||
string name
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void Client::request_media(const std::vector<std::string> &file_requests)
|
void Client::request_media(const std::vector<std::string> &file_requests)
|
||||||
{
|
{
|
||||||
std::ostringstream os(std::ios_base::binary);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
@ -1031,8 +1044,8 @@ void Client::Send(NetworkPacket* pkt)
|
||||||
// Will fill up 12 + 12 + 4 + 4 + 4 + 1 + 1 + 1 + 4 + 4 bytes
|
// Will fill up 12 + 12 + 4 + 4 + 4 + 1 + 1 + 1 + 4 + 4 bytes
|
||||||
void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt, bool camera_inverted)
|
void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt, bool camera_inverted)
|
||||||
{
|
{
|
||||||
v3f pf = myplayer->getPosition() * 100;
|
v3s32 position = v3s32::from(myplayer->getPosition() * 100);
|
||||||
v3f sf = myplayer->getSpeed() * 100;
|
v3s32 speed = v3s32::from(myplayer->getSpeed() * 100);
|
||||||
s32 pitch = myplayer->getPitch() * 100;
|
s32 pitch = myplayer->getPitch() * 100;
|
||||||
s32 yaw = myplayer->getYaw() * 100;
|
s32 yaw = myplayer->getYaw() * 100;
|
||||||
u32 keyPressed = myplayer->control.getKeysPressed();
|
u32 keyPressed = myplayer->control.getKeysPressed();
|
||||||
|
@ -1043,9 +1056,6 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *
|
||||||
f32 movement_speed = myplayer->control.movement_speed;
|
f32 movement_speed = myplayer->control.movement_speed;
|
||||||
f32 movement_dir = myplayer->control.movement_direction;
|
f32 movement_dir = myplayer->control.movement_direction;
|
||||||
|
|
||||||
v3s32 position(pf.X, pf.Y, pf.Z);
|
|
||||||
v3s32 speed(sf.X, sf.Y, sf.Z);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Format:
|
Format:
|
||||||
[0] v3s32 position*100
|
[0] v3s32 position*100
|
||||||
|
@ -1742,12 +1752,7 @@ void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool
|
||||||
|
|
||||||
void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool urgent)
|
void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool urgent)
|
||||||
{
|
{
|
||||||
{
|
infostream << "Client::addUpdateMeshTaskForNode(): " << nodepos << std::endl;
|
||||||
v3s16 p = nodepos;
|
|
||||||
infostream<<"Client::addUpdateMeshTaskForNode(): "
|
|
||||||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
|
||||||
<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
v3s16 blockpos = getNodeBlockPos(nodepos);
|
v3s16 blockpos = getNodeBlockPos(nodepos);
|
||||||
v3s16 blockpos_relative = blockpos * MAP_BLOCKSIZE;
|
v3s16 blockpos_relative = blockpos * MAP_BLOCKSIZE;
|
||||||
|
|
|
@ -217,6 +217,7 @@ public:
|
||||||
void handleCommand_MediaPush(NetworkPacket *pkt);
|
void handleCommand_MediaPush(NetworkPacket *pkt);
|
||||||
void handleCommand_MinimapModes(NetworkPacket *pkt);
|
void handleCommand_MinimapModes(NetworkPacket *pkt);
|
||||||
void handleCommand_SetLighting(NetworkPacket *pkt);
|
void handleCommand_SetLighting(NetworkPacket *pkt);
|
||||||
|
void handleCommand_Camera(NetworkPacket* pkt);
|
||||||
|
|
||||||
void ProcessData(NetworkPacket *pkt);
|
void ProcessData(NetworkPacket *pkt);
|
||||||
|
|
||||||
|
@ -485,23 +486,18 @@ private:
|
||||||
u8 m_server_ser_ver;
|
u8 m_server_ser_ver;
|
||||||
|
|
||||||
// Used version of the protocol with server
|
// Used version of the protocol with server
|
||||||
// Values smaller than 25 only mean they are smaller than 25,
|
|
||||||
// and aren't accurate. We simply just don't know, because
|
|
||||||
// the server didn't send the version back then.
|
|
||||||
// If 0, server init hasn't been received yet.
|
// If 0, server init hasn't been received yet.
|
||||||
u16 m_proto_ver = 0;
|
u16 m_proto_ver = 0;
|
||||||
|
|
||||||
bool m_update_wielded_item = false;
|
bool m_update_wielded_item = false;
|
||||||
Inventory *m_inventory_from_server = nullptr;
|
Inventory *m_inventory_from_server = nullptr;
|
||||||
float m_inventory_from_server_age = 0.0f;
|
float m_inventory_from_server_age = 0.0f;
|
||||||
|
s32 m_mapblock_limit_logged = 0;
|
||||||
PacketCounter m_packetcounter;
|
PacketCounter m_packetcounter;
|
||||||
// Block mesh animation parameters
|
// Block mesh animation parameters
|
||||||
float m_animation_time = 0.0f;
|
float m_animation_time = 0.0f;
|
||||||
int m_crack_level = -1;
|
int m_crack_level = -1;
|
||||||
v3s16 m_crack_pos;
|
v3s16 m_crack_pos;
|
||||||
// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
|
|
||||||
//s32 m_daynight_i;
|
|
||||||
//u32 m_daynight_ratio;
|
|
||||||
std::queue<std::wstring> m_out_chat_queue;
|
std::queue<std::wstring> m_out_chat_queue;
|
||||||
u32 m_last_chat_message_sent;
|
u32 m_last_chat_message_sent;
|
||||||
float m_chat_message_allowance = 5.0f;
|
float m_chat_message_allowance = 5.0f;
|
||||||
|
@ -537,11 +533,6 @@ private:
|
||||||
// Pending downloads of dynamic media (key: token)
|
// Pending downloads of dynamic media (key: token)
|
||||||
std::vector<std::pair<u32, std::shared_ptr<SingleMediaDownloader>>> m_pending_media_downloads;
|
std::vector<std::pair<u32, std::shared_ptr<SingleMediaDownloader>>> m_pending_media_downloads;
|
||||||
|
|
||||||
// time_of_day speed approximation for old protocol
|
|
||||||
bool m_time_of_day_set = false;
|
|
||||||
float m_last_time_of_day_f = -1.0f;
|
|
||||||
float m_time_of_day_update_timer = 0.0f;
|
|
||||||
|
|
||||||
// An interval for generally sending object positions and stuff
|
// An interval for generally sending object positions and stuff
|
||||||
float m_recommended_send_interval = 0.1f;
|
float m_recommended_send_interval = 0.1f;
|
||||||
|
|
||||||
|
|
|
@ -441,8 +441,8 @@ void ClientEnvironment::getSelectedActiveObjects(
|
||||||
GenericCAO* gcao = dynamic_cast<GenericCAO*>(obj);
|
GenericCAO* gcao = dynamic_cast<GenericCAO*>(obj);
|
||||||
if (gcao != nullptr && gcao->getProperties().rotate_selectionbox) {
|
if (gcao != nullptr && gcao->getProperties().rotate_selectionbox) {
|
||||||
gcao->getSceneNode()->updateAbsolutePosition();
|
gcao->getSceneNode()->updateAbsolutePosition();
|
||||||
const v3f deg = obj->getSceneNode()->getAbsoluteTransformation().getRotationDegrees();
|
const v3f rad = obj->getSceneNode()->getAbsoluteTransformation().getRotationRadians();
|
||||||
collision = boxLineCollision(selection_box, deg,
|
collision = boxLineCollision(selection_box, rad,
|
||||||
rel_pos, line_vector, ¤t_intersection, ¤t_normal, ¤t_raw_normal);
|
rel_pos, line_vector, ¤t_intersection, ¤t_normal, ¤t_raw_normal);
|
||||||
} else {
|
} else {
|
||||||
collision = boxLineCollision(selection_box, rel_pos, line_vector,
|
collision = boxLineCollision(selection_box, rel_pos, line_vector,
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum ClientEventType : u8
|
||||||
CE_SET_STARS,
|
CE_SET_STARS,
|
||||||
CE_OVERRIDE_DAY_NIGHT_RATIO,
|
CE_OVERRIDE_DAY_NIGHT_RATIO,
|
||||||
CE_CLOUD_PARAMS,
|
CE_CLOUD_PARAMS,
|
||||||
|
CE_UPDATE_CAMERA,
|
||||||
CLIENTEVENT_MAX,
|
CLIENTEVENT_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,11 +67,14 @@ struct ClientEventHudChange
|
||||||
|
|
||||||
struct ClientEvent
|
struct ClientEvent
|
||||||
{
|
{
|
||||||
|
// TODO: should get rid of this ctor
|
||||||
|
ClientEvent() : type(CE_NONE) {}
|
||||||
|
|
||||||
|
ClientEvent(ClientEventType type) : type(type) {}
|
||||||
|
|
||||||
ClientEventType type;
|
ClientEventType type;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
// struct{
|
|
||||||
//} none;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u16 amount;
|
u16 amount;
|
||||||
|
@ -86,8 +90,6 @@ struct ClientEvent
|
||||||
std::string *formspec;
|
std::string *formspec;
|
||||||
std::string *formname;
|
std::string *formname;
|
||||||
} show_formspec;
|
} show_formspec;
|
||||||
// struct{
|
|
||||||
//} textures_updated;
|
|
||||||
ParticleParameters *spawn_particle;
|
ParticleParameters *spawn_particle;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,6 +52,13 @@ Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
|
||||||
|
|
||||||
updateBox();
|
updateBox();
|
||||||
|
|
||||||
|
// Neither EAC_BOX (the default) nor EAC_FRUSTUM_BOX will correctly cull
|
||||||
|
// the clouds.
|
||||||
|
// And yes, the bounding box is correct. You can check using the #if 0'd
|
||||||
|
// code in render() and see for yourself.
|
||||||
|
// So I give up and let's disable culling.
|
||||||
|
setAutomaticCulling(scene::EAC_OFF);
|
||||||
|
|
||||||
m_meshbuffer.reset(new scene::SMeshBuffer());
|
m_meshbuffer.reset(new scene::SMeshBuffer());
|
||||||
m_meshbuffer->setHardwareMappingHint(scene::EHM_DYNAMIC);
|
m_meshbuffer->setHardwareMappingHint(scene::EHM_DYNAMIC);
|
||||||
}
|
}
|
||||||
|
@ -366,6 +373,19 @@ void Clouds::render()
|
||||||
if (SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT)
|
if (SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
video::SMaterial tmp;
|
||||||
|
tmp.Thickness = 1.f;
|
||||||
|
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||||
|
driver->setMaterial(tmp);
|
||||||
|
aabb3f tmpbox = m_box;
|
||||||
|
tmpbox.MinEdge.X = tmpbox.MinEdge.Z = -1000 * BS;
|
||||||
|
tmpbox.MaxEdge.X = tmpbox.MaxEdge.Z = 1000 * BS;
|
||||||
|
driver->draw3DBox(tmpbox, video::SColor(255, 255, 0x4d, 0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
updateMesh();
|
updateMesh();
|
||||||
|
|
||||||
// Update position
|
// Update position
|
||||||
|
@ -425,14 +445,14 @@ void Clouds::update(const v3f &camera_p, const video::SColorf &color_diffuse)
|
||||||
|
|
||||||
// is the camera inside the cloud mesh?
|
// is the camera inside the cloud mesh?
|
||||||
m_camera_pos = camera_p;
|
m_camera_pos = camera_p;
|
||||||
m_camera_inside_cloud = false; // default
|
m_camera_inside_cloud = false;
|
||||||
if (is3D()) {
|
if (is3D()) {
|
||||||
float camera_height = camera_p.Y - BS * m_camera_offset.Y;
|
float camera_height = camera_p.Y - BS * m_camera_offset.Y;
|
||||||
if (camera_height >= m_box.MinEdge.Y &&
|
if (camera_height >= m_box.MinEdge.Y &&
|
||||||
camera_height <= m_box.MaxEdge.Y) {
|
camera_height <= m_box.MaxEdge.Y) {
|
||||||
v2f camera_in_noise;
|
v2f camera_in_noise;
|
||||||
camera_in_noise.X = floor((camera_p.X - m_origin.X) / cloud_size + 0.5);
|
camera_in_noise.X = floorf((camera_p.X - m_origin.X) / cloud_size + 0.5f);
|
||||||
camera_in_noise.Y = floor((camera_p.Z - m_origin.Y) / cloud_size + 0.5);
|
camera_in_noise.Y = floorf((camera_p.Z - m_origin.Y) / cloud_size + 0.5f);
|
||||||
bool filled = gridFilled(camera_in_noise.X, camera_in_noise.Y);
|
bool filled = gridFilled(camera_in_noise.X, camera_in_noise.Y);
|
||||||
m_camera_inside_cloud = filled;
|
m_camera_inside_cloud = filled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,8 +134,11 @@ private:
|
||||||
{
|
{
|
||||||
float height_bs = m_params.height * BS;
|
float height_bs = m_params.height * BS;
|
||||||
float thickness_bs = m_params.thickness * BS;
|
float thickness_bs = m_params.thickness * BS;
|
||||||
m_box = aabb3f(-BS * 1000000.0f, height_bs, -BS * 1000000.0f,
|
float far_bs = 1000000.0f * BS;
|
||||||
BS * 1000000.0f, height_bs + thickness_bs, BS * 1000000.0f);
|
m_box = aabb3f(-far_bs, height_bs, -far_bs,
|
||||||
|
far_bs, height_bs + thickness_bs, far_bs);
|
||||||
|
m_box.MinEdge -= v3f::from(m_camera_offset) * BS;
|
||||||
|
m_box.MaxEdge -= v3f::from(m_camera_offset) * BS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateMesh();
|
void updateMesh();
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "client/sound.h"
|
#include "client/sound.h"
|
||||||
#include "client/texturesource.h"
|
#include "client/texturesource.h"
|
||||||
#include "client/mapblock_mesh.h"
|
#include "client/mapblock_mesh.h"
|
||||||
|
#include "client/content_mapblock.h"
|
||||||
|
#include "client/meshgen/collector.h"
|
||||||
#include "util/basic_macros.h"
|
#include "util/basic_macros.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
|
@ -180,6 +182,55 @@ static void setColorParam(scene::ISceneNode *node, video::SColor color)
|
||||||
node->getMaterial(i).ColorParam = color;
|
node->getMaterial(i).ColorParam = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static scene::SMesh *generateNodeMesh(Client *client, MapNode n,
|
||||||
|
std::vector<MeshAnimationInfo> &animation)
|
||||||
|
{
|
||||||
|
auto *ndef = client->ndef();
|
||||||
|
auto *shdsrc = client->getShaderSource();
|
||||||
|
|
||||||
|
MeshCollector collector(v3f(0), v3f());
|
||||||
|
{
|
||||||
|
MeshMakeData mmd(ndef, 1, MeshGrid{1});
|
||||||
|
n.setParam1(0xff);
|
||||||
|
mmd.fillSingleNode(n);
|
||||||
|
MapblockMeshGenerator(&mmd, &collector).generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mesh = make_irr<scene::SMesh>();
|
||||||
|
animation.clear();
|
||||||
|
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
|
||||||
|
for (PreMeshBuffer &p : collector.prebuffers[layer]) {
|
||||||
|
// reset the pre-computed light data stored in the vertex color,
|
||||||
|
// since we do that ourselves via updateLight().
|
||||||
|
for (auto &v : p.vertices)
|
||||||
|
v.Color.set(0xFFFFFFFF);
|
||||||
|
// but still apply the tile color
|
||||||
|
p.applyTileColor();
|
||||||
|
|
||||||
|
if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
|
||||||
|
const FrameSpec &frame = (*p.layer.frames)[0];
|
||||||
|
p.layer.texture = frame.texture;
|
||||||
|
|
||||||
|
animation.emplace_back(MeshAnimationInfo{mesh->getMeshBufferCount(), 0, p.layer});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buf = make_irr<scene::SMeshBuffer>();
|
||||||
|
buf->append(&p.vertices[0], p.vertices.size(),
|
||||||
|
&p.indices[0], p.indices.size());
|
||||||
|
|
||||||
|
// Set up material
|
||||||
|
auto &mat = buf->Material;
|
||||||
|
u32 shader_id = shdsrc->getShader("object_shader", p.layer.material_type, NDT_NORMAL);
|
||||||
|
mat.MaterialType = shdsrc->getShaderInfo(shader_id).material;
|
||||||
|
p.layer.applyMaterialOptions(mat, layer);
|
||||||
|
|
||||||
|
mesh->addMeshBuffer(buf.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh->recalculateBoundingBox();
|
||||||
|
return mesh.release();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TestCAO
|
TestCAO
|
||||||
*/
|
*/
|
||||||
|
@ -572,6 +623,8 @@ void GenericCAO::removeFromScene(bool permanent)
|
||||||
m_spritenode = nullptr;
|
m_spritenode = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_meshnode_animation.clear();
|
||||||
|
|
||||||
if (m_matrixnode) {
|
if (m_matrixnode) {
|
||||||
m_matrixnode->remove();
|
m_matrixnode->remove();
|
||||||
m_matrixnode->drop();
|
m_matrixnode->drop();
|
||||||
|
@ -602,8 +655,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
|
|
||||||
infostream << "GenericCAO::addToScene(): " << m_prop.visual << std::endl;
|
infostream << "GenericCAO::addToScene(): " << m_prop.visual << std::endl;
|
||||||
|
|
||||||
m_material_type_param = 0.5f; // May cut off alpha < 128 depending on m_material_type
|
if (m_prop.visual != "node" && m_prop.visual != "wielditem" && m_prop.visual != "item")
|
||||||
|
|
||||||
{
|
{
|
||||||
IShaderSource *shader_source = m_client->getShaderSource();
|
IShaderSource *shader_source = m_client->getShaderSource();
|
||||||
MaterialType material_type;
|
MaterialType material_type;
|
||||||
|
@ -617,15 +669,17 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
|
|
||||||
u32 shader_id = shader_source->getShader("object_shader", material_type, NDT_NORMAL);
|
u32 shader_id = shader_source->getShader("object_shader", material_type, NDT_NORMAL);
|
||||||
m_material_type = shader_source->getShaderInfo(shader_id).material;
|
m_material_type = shader_source->getShaderInfo(shader_id).material;
|
||||||
|
} else {
|
||||||
|
// Not used, so make sure it's not valid
|
||||||
|
m_material_type = EMT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto grabMatrixNode = [this] {
|
m_matrixnode = m_smgr->addDummyTransformationSceneNode();
|
||||||
m_matrixnode = m_smgr->addDummyTransformationSceneNode();
|
m_matrixnode->grab();
|
||||||
m_matrixnode->grab();
|
|
||||||
};
|
|
||||||
|
|
||||||
auto setMaterial = [this] (video::SMaterial &mat) {
|
auto setMaterial = [this] (video::SMaterial &mat) {
|
||||||
mat.MaterialType = m_material_type;
|
if (m_material_type != EMT_INVALID)
|
||||||
|
mat.MaterialType = m_material_type;
|
||||||
mat.FogEnable = true;
|
mat.FogEnable = true;
|
||||||
mat.forEachTexture([] (auto &tex) {
|
mat.forEachTexture([] (auto &tex) {
|
||||||
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
||||||
|
@ -637,28 +691,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
node->forEachMaterial(setMaterial);
|
node->forEachMaterial(setMaterial);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (m_prop.visual == "sprite") {
|
if (m_prop.visual == "upright_sprite") {
|
||||||
grabMatrixNode();
|
|
||||||
m_spritenode = m_smgr->addBillboardSceneNode(
|
|
||||||
m_matrixnode, v2f(1, 1), v3f(0,0,0), -1);
|
|
||||||
m_spritenode->grab();
|
|
||||||
video::ITexture *tex = tsrc->getTextureForMesh("no_texture.png");
|
|
||||||
m_spritenode->forEachMaterial([tex] (auto &mat) {
|
|
||||||
mat.setTexture(0, tex);
|
|
||||||
});
|
|
||||||
|
|
||||||
setSceneNodeMaterials(m_spritenode);
|
|
||||||
|
|
||||||
m_spritenode->setSize(v2f(m_prop.visual_size.X,
|
|
||||||
m_prop.visual_size.Y) * BS);
|
|
||||||
{
|
|
||||||
const float txs = 1.0 / 1;
|
|
||||||
const float tys = 1.0 / 1;
|
|
||||||
setBillboardTextureMatrix(m_spritenode,
|
|
||||||
txs, tys, 0, 0);
|
|
||||||
}
|
|
||||||
} else if (m_prop.visual == "upright_sprite") {
|
|
||||||
grabMatrixNode();
|
|
||||||
auto mesh = make_irr<scene::SMesh>();
|
auto mesh = make_irr<scene::SMesh>();
|
||||||
f32 dx = BS * m_prop.visual_size.X / 2;
|
f32 dx = BS * m_prop.visual_size.X / 2;
|
||||||
f32 dy = BS * m_prop.visual_size.Y / 2;
|
f32 dy = BS * m_prop.visual_size.Y / 2;
|
||||||
|
@ -700,7 +733,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
m_meshnode = m_smgr->addMeshSceneNode(mesh.get(), m_matrixnode);
|
m_meshnode = m_smgr->addMeshSceneNode(mesh.get(), m_matrixnode);
|
||||||
m_meshnode->grab();
|
m_meshnode->grab();
|
||||||
} else if (m_prop.visual == "cube") {
|
} else if (m_prop.visual == "cube") {
|
||||||
grabMatrixNode();
|
|
||||||
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
|
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
|
||||||
m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
|
m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
|
||||||
m_meshnode->grab();
|
m_meshnode->grab();
|
||||||
|
@ -714,7 +746,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
mat.BackfaceCulling = m_prop.backface_culling;
|
mat.BackfaceCulling = m_prop.backface_culling;
|
||||||
});
|
});
|
||||||
} else if (m_prop.visual == "mesh") {
|
} else if (m_prop.visual == "mesh") {
|
||||||
grabMatrixNode();
|
|
||||||
scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
|
scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
if (!checkMeshNormals(mesh)) {
|
if (!checkMeshNormals(mesh)) {
|
||||||
|
@ -741,7 +772,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
} else
|
} else
|
||||||
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
|
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
|
||||||
} else if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
|
} else if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
|
||||||
grabMatrixNode();
|
|
||||||
ItemStack item;
|
ItemStack item;
|
||||||
if (m_prop.wield_item.empty()) {
|
if (m_prop.wield_item.empty()) {
|
||||||
// Old format, only textures are specified.
|
// Old format, only textures are specified.
|
||||||
|
@ -761,9 +791,35 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
(m_prop.visual == "wielditem"));
|
(m_prop.visual == "wielditem"));
|
||||||
|
|
||||||
m_wield_meshnode->setScale(m_prop.visual_size / 2.0f);
|
m_wield_meshnode->setScale(m_prop.visual_size / 2.0f);
|
||||||
|
} else if (m_prop.visual == "node") {
|
||||||
|
auto *mesh = generateNodeMesh(m_client, m_prop.node, m_meshnode_animation);
|
||||||
|
assert(mesh);
|
||||||
|
|
||||||
|
m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
|
||||||
|
m_meshnode->setSharedMaterials(true);
|
||||||
|
m_meshnode->grab();
|
||||||
|
mesh->drop();
|
||||||
|
|
||||||
|
m_meshnode->setScale(m_prop.visual_size);
|
||||||
|
|
||||||
|
setSceneNodeMaterials(m_meshnode);
|
||||||
} else {
|
} else {
|
||||||
infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual
|
m_spritenode = m_smgr->addBillboardSceneNode(m_matrixnode);
|
||||||
<<"\" not supported"<<std::endl;
|
m_spritenode->grab();
|
||||||
|
|
||||||
|
setSceneNodeMaterials(m_spritenode);
|
||||||
|
|
||||||
|
m_spritenode->setSize(v2f(m_prop.visual_size.X,
|
||||||
|
m_prop.visual_size.Y) * BS);
|
||||||
|
setBillboardTextureMatrix(m_spritenode, 1, 1, 0, 0);
|
||||||
|
|
||||||
|
// This also serves as fallback for unknown visual types
|
||||||
|
if (m_prop.visual != "sprite") {
|
||||||
|
infostream << "GenericCAO::addToScene(): \"" << m_prop.visual
|
||||||
|
<< "\" not supported" << std::endl;
|
||||||
|
m_spritenode->getMaterial(0).setTexture(0,
|
||||||
|
tsrc->getTextureForMesh("unknown_object.png"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set VBO hint */
|
/* Set VBO hint */
|
||||||
|
@ -789,8 +845,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
updateTextures(m_current_texture_modifier);
|
updateTextures(m_current_texture_modifier);
|
||||||
|
|
||||||
if (scene::ISceneNode *node = getSceneNode()) {
|
if (scene::ISceneNode *node = getSceneNode()) {
|
||||||
if (m_matrixnode)
|
node->setParent(m_matrixnode);
|
||||||
node->setParent(m_matrixnode);
|
|
||||||
|
|
||||||
if (auto shadow = RenderingEngine::get_shadow_renderer())
|
if (auto shadow = RenderingEngine::get_shadow_renderer())
|
||||||
shadow->addNodeToShadowList(node);
|
shadow->addNodeToShadowList(node);
|
||||||
|
@ -861,8 +916,7 @@ void GenericCAO::updateLight(u32 day_night_ratio)
|
||||||
if (!pos_ok)
|
if (!pos_ok)
|
||||||
light_at_pos = LIGHT_SUN;
|
light_at_pos = LIGHT_SUN;
|
||||||
|
|
||||||
// Initialize with full alpha, otherwise entity won't be visible
|
video::SColor light;
|
||||||
video::SColor light{0xFFFFFFFF};
|
|
||||||
|
|
||||||
// Encode light into color, adding a small boost
|
// Encode light into color, adding a small boost
|
||||||
// based on the entity glow.
|
// based on the entity glow.
|
||||||
|
@ -965,6 +1019,7 @@ void GenericCAO::updateNodePos()
|
||||||
scene::ISceneNode *node = getSceneNode();
|
scene::ISceneNode *node = getSceneNode();
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
|
assert(m_matrixnode);
|
||||||
v3s16 camera_offset = m_env->getCameraOffset();
|
v3s16 camera_offset = m_env->getCameraOffset();
|
||||||
v3f pos = pos_translator.val_current -
|
v3f pos = pos_translator.val_current -
|
||||||
intToFloat(camera_offset, BS);
|
intToFloat(camera_offset, BS);
|
||||||
|
@ -1153,7 +1208,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
|
||||||
m_anim_frame = 0;
|
m_anim_frame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTexturePos();
|
updateTextureAnim();
|
||||||
|
|
||||||
if(m_reset_textures_timer >= 0)
|
if(m_reset_textures_timer >= 0)
|
||||||
{
|
{
|
||||||
|
@ -1214,7 +1269,7 @@ static void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u
|
||||||
buf->setDirty(scene::EBT_VERTEX);
|
buf->setDirty(scene::EBT_VERTEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericCAO::updateTexturePos()
|
void GenericCAO::updateTextureAnim()
|
||||||
{
|
{
|
||||||
if(m_spritenode)
|
if(m_spritenode)
|
||||||
{
|
{
|
||||||
|
@ -1279,6 +1334,23 @@ void GenericCAO::updateTexturePos()
|
||||||
auto mesh = m_meshnode->getMesh();
|
auto mesh = m_meshnode->getMesh();
|
||||||
setMeshBufferTextureCoords(mesh->getMeshBuffer(0), t, 4);
|
setMeshBufferTextureCoords(mesh->getMeshBuffer(0), t, 4);
|
||||||
setMeshBufferTextureCoords(mesh->getMeshBuffer(1), t, 4);
|
setMeshBufferTextureCoords(mesh->getMeshBuffer(1), t, 4);
|
||||||
|
} else if (m_prop.visual == "node") {
|
||||||
|
// same calculation as MapBlockMesh::animate() with a global timer
|
||||||
|
const float time = m_client->getAnimationTime();
|
||||||
|
for (auto &it : m_meshnode_animation) {
|
||||||
|
const TileLayer &tile = it.tile;
|
||||||
|
int frameno = (int)(time * 1000 / tile.animation_frame_length_ms)
|
||||||
|
% tile.animation_frame_count;
|
||||||
|
|
||||||
|
if (frameno == it.frame)
|
||||||
|
continue;
|
||||||
|
it.frame = frameno;
|
||||||
|
|
||||||
|
auto *buf = m_meshnode->getMesh()->getMeshBuffer(it.i);
|
||||||
|
|
||||||
|
const FrameSpec &frame = (*tile.frames)[frameno];
|
||||||
|
buf->getMaterial().setTexture(0, frame.texture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1304,7 +1376,6 @@ void GenericCAO::updateTextures(std::string mod)
|
||||||
|
|
||||||
video::SMaterial &material = m_spritenode->getMaterial(0);
|
video::SMaterial &material = m_spritenode->getMaterial(0);
|
||||||
material.MaterialType = m_material_type;
|
material.MaterialType = m_material_type;
|
||||||
material.MaterialTypeParam = m_material_type_param;
|
|
||||||
material.setTexture(0, tsrc->getTextureForMesh(texturestring));
|
material.setTexture(0, tsrc->getTextureForMesh(texturestring));
|
||||||
|
|
||||||
material.forEachTexture([=] (auto &tex) {
|
material.forEachTexture([=] (auto &tex) {
|
||||||
|
@ -1333,7 +1404,6 @@ void GenericCAO::updateTextures(std::string mod)
|
||||||
// Set material flags and texture
|
// Set material flags and texture
|
||||||
video::SMaterial &material = m_animated_meshnode->getMaterial(i);
|
video::SMaterial &material = m_animated_meshnode->getMaterial(i);
|
||||||
material.MaterialType = m_material_type;
|
material.MaterialType = m_material_type;
|
||||||
material.MaterialTypeParam = m_material_type_param;
|
|
||||||
material.TextureLayers[0].Texture = texture;
|
material.TextureLayers[0].Texture = texture;
|
||||||
material.BackfaceCulling = m_prop.backface_culling;
|
material.BackfaceCulling = m_prop.backface_culling;
|
||||||
|
|
||||||
|
@ -1365,7 +1435,6 @@ void GenericCAO::updateTextures(std::string mod)
|
||||||
// Set material flags and texture
|
// Set material flags and texture
|
||||||
video::SMaterial &material = m_meshnode->getMaterial(i);
|
video::SMaterial &material = m_meshnode->getMaterial(i);
|
||||||
material.MaterialType = m_material_type;
|
material.MaterialType = m_material_type;
|
||||||
material.MaterialTypeParam = m_material_type_param;
|
|
||||||
material.setTexture(0, tsrc->getTextureForMesh(texturestring));
|
material.setTexture(0, tsrc->getTextureForMesh(texturestring));
|
||||||
material.getTextureMatrix(0).makeIdentity();
|
material.getTextureMatrix(0).makeIdentity();
|
||||||
|
|
||||||
|
@ -1532,7 +1601,7 @@ bool GenericCAO::visualExpiryRequired(const ObjectProperties &new_) const
|
||||||
/* Visuals do not need to be expired for:
|
/* Visuals do not need to be expired for:
|
||||||
* - nametag props: handled by updateNametag()
|
* - nametag props: handled by updateNametag()
|
||||||
* - textures: handled by updateTextures()
|
* - textures: handled by updateTextures()
|
||||||
* - sprite props: handled by updateTexturePos()
|
* - sprite props: handled by updateTextureAnim()
|
||||||
* - glow: handled by updateLight()
|
* - glow: handled by updateLight()
|
||||||
* - any other properties that do not change appearance
|
* - any other properties that do not change appearance
|
||||||
*/
|
*/
|
||||||
|
@ -1542,9 +1611,10 @@ bool GenericCAO::visualExpiryRequired(const ObjectProperties &new_) const
|
||||||
// Ordered to compare primitive types before std::vectors
|
// Ordered to compare primitive types before std::vectors
|
||||||
return old.backface_culling != new_.backface_culling ||
|
return old.backface_culling != new_.backface_culling ||
|
||||||
old.is_visible != new_.is_visible ||
|
old.is_visible != new_.is_visible ||
|
||||||
old.mesh != new_.mesh ||
|
|
||||||
old.shaded != new_.shaded ||
|
old.shaded != new_.shaded ||
|
||||||
old.use_texture_alpha != new_.use_texture_alpha ||
|
old.use_texture_alpha != new_.use_texture_alpha ||
|
||||||
|
old.node != new_.node ||
|
||||||
|
old.mesh != new_.mesh ||
|
||||||
old.visual != new_.visual ||
|
old.visual != new_.visual ||
|
||||||
old.visual_size != new_.visual_size ||
|
old.visual_size != new_.visual_size ||
|
||||||
old.wield_item != new_.wield_item ||
|
old.wield_item != new_.wield_item ||
|
||||||
|
@ -1655,7 +1725,7 @@ void GenericCAO::processMessage(const std::string &data)
|
||||||
m_anim_framelength = framelength;
|
m_anim_framelength = framelength;
|
||||||
m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch;
|
m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch;
|
||||||
|
|
||||||
updateTexturePos();
|
updateTextureAnim();
|
||||||
} else if (cmd == AO_CMD_SET_PHYSICS_OVERRIDE) {
|
} else if (cmd == AO_CMD_SET_PHYSICS_OVERRIDE) {
|
||||||
float override_speed = readF32(is);
|
float override_speed = readF32(is);
|
||||||
float override_jump = readF32(is);
|
float override_jump = readF32(is);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "clientobject.h"
|
#include "clientobject.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "itemgroup.h"
|
#include "itemgroup.h"
|
||||||
|
#include "client/tile.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -27,7 +28,7 @@ struct Nametag;
|
||||||
struct MinimapMarker;
|
struct MinimapMarker;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SmoothTranslator
|
SmoothTranslator and other helpers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -60,9 +61,21 @@ struct SmoothTranslatorWrappedv3f : SmoothTranslator<v3f>
|
||||||
void translate(f32 dtime);
|
void translate(f32 dtime);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MeshAnimationInfo {
|
||||||
|
u32 i; /// index of mesh buffer
|
||||||
|
int frame; /// last animation frame
|
||||||
|
TileLayer tile;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
GenericCAO
|
||||||
|
*/
|
||||||
|
|
||||||
class GenericCAO : public ClientActiveObject
|
class GenericCAO : public ClientActiveObject
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
static constexpr auto EMT_INVALID = video::EMT_FORCE_32BIT;
|
||||||
|
|
||||||
// Only set at initialization
|
// Only set at initialization
|
||||||
std::string m_name = "";
|
std::string m_name = "";
|
||||||
bool m_is_player = false;
|
bool m_is_player = false;
|
||||||
|
@ -73,6 +86,8 @@ private:
|
||||||
scene::ISceneManager *m_smgr = nullptr;
|
scene::ISceneManager *m_smgr = nullptr;
|
||||||
Client *m_client = nullptr;
|
Client *m_client = nullptr;
|
||||||
aabb3f m_selection_box = aabb3f(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.);
|
aabb3f m_selection_box = aabb3f(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.);
|
||||||
|
|
||||||
|
// Visuals
|
||||||
scene::IMeshSceneNode *m_meshnode = nullptr;
|
scene::IMeshSceneNode *m_meshnode = nullptr;
|
||||||
scene::IAnimatedMeshSceneNode *m_animated_meshnode = nullptr;
|
scene::IAnimatedMeshSceneNode *m_animated_meshnode = nullptr;
|
||||||
WieldMeshSceneNode *m_wield_meshnode = nullptr;
|
WieldMeshSceneNode *m_wield_meshnode = nullptr;
|
||||||
|
@ -80,6 +95,15 @@ private:
|
||||||
scene::IDummyTransformationSceneNode *m_matrixnode = nullptr;
|
scene::IDummyTransformationSceneNode *m_matrixnode = nullptr;
|
||||||
Nametag *m_nametag = nullptr;
|
Nametag *m_nametag = nullptr;
|
||||||
MinimapMarker *m_marker = nullptr;
|
MinimapMarker *m_marker = nullptr;
|
||||||
|
bool m_visuals_expired = false;
|
||||||
|
video::SColor m_last_light = video::SColor(0xFFFFFFFF);
|
||||||
|
bool m_is_visible = false;
|
||||||
|
std::vector<MeshAnimationInfo> m_meshnode_animation;
|
||||||
|
|
||||||
|
// Material
|
||||||
|
video::E_MATERIAL_TYPE m_material_type = EMT_INVALID;
|
||||||
|
|
||||||
|
// Movement
|
||||||
v3f m_position = v3f(0.0f, 10.0f * BS, 0);
|
v3f m_position = v3f(0.0f, 10.0f * BS, 0);
|
||||||
v3f m_velocity;
|
v3f m_velocity;
|
||||||
v3f m_acceleration;
|
v3f m_acceleration;
|
||||||
|
@ -87,18 +111,25 @@ private:
|
||||||
u16 m_hp = 1;
|
u16 m_hp = 1;
|
||||||
SmoothTranslator<v3f> pos_translator;
|
SmoothTranslator<v3f> pos_translator;
|
||||||
SmoothTranslatorWrappedv3f rot_translator;
|
SmoothTranslatorWrappedv3f rot_translator;
|
||||||
// Spritesheet/animation stuff
|
|
||||||
|
// Spritesheet stuff
|
||||||
v2f m_tx_size = v2f(1,1);
|
v2f m_tx_size = v2f(1,1);
|
||||||
v2s16 m_tx_basepos;
|
v2s16 m_tx_basepos;
|
||||||
bool m_initial_tx_basepos_set = false;
|
bool m_initial_tx_basepos_set = false;
|
||||||
bool m_tx_select_horiz_by_yawpitch = false;
|
bool m_tx_select_horiz_by_yawpitch = false;
|
||||||
|
bool m_animation_loop = true;
|
||||||
v2f m_animation_range;
|
v2f m_animation_range;
|
||||||
float m_animation_speed = 15.0f;
|
float m_animation_speed = 15.0f;
|
||||||
float m_animation_blend = 0.0f;
|
float m_animation_blend = 0.0f;
|
||||||
bool m_animation_loop = true;
|
int m_anim_frame = 0;
|
||||||
|
int m_anim_num_frames = 1;
|
||||||
|
float m_anim_framelength = 0.2f;
|
||||||
|
float m_anim_timer = 0.0f;
|
||||||
|
|
||||||
// stores position and rotation for each bone name
|
// stores position and rotation for each bone name
|
||||||
BoneOverrideMap m_bone_override;
|
BoneOverrideMap m_bone_override;
|
||||||
|
|
||||||
|
// Attachments
|
||||||
object_t m_attachment_parent_id = 0;
|
object_t m_attachment_parent_id = 0;
|
||||||
std::unordered_set<object_t> m_attachment_child_ids;
|
std::unordered_set<object_t> m_attachment_child_ids;
|
||||||
std::string m_attachment_bone = "";
|
std::string m_attachment_bone = "";
|
||||||
|
@ -107,23 +138,13 @@ private:
|
||||||
bool m_attached_to_local = false;
|
bool m_attached_to_local = false;
|
||||||
bool m_force_visible = false;
|
bool m_force_visible = false;
|
||||||
|
|
||||||
int m_anim_frame = 0;
|
|
||||||
int m_anim_num_frames = 1;
|
|
||||||
float m_anim_framelength = 0.2f;
|
|
||||||
float m_anim_timer = 0.0f;
|
|
||||||
ItemGroupList m_armor_groups;
|
ItemGroupList m_armor_groups;
|
||||||
float m_reset_textures_timer = -1.0f;
|
float m_reset_textures_timer = -1.0f;
|
||||||
// stores texture modifier before punch update
|
// stores texture modifier before punch update
|
||||||
std::string m_previous_texture_modifier = "";
|
std::string m_previous_texture_modifier = "";
|
||||||
// last applied texture modifier
|
// last applied texture modifier
|
||||||
std::string m_current_texture_modifier = "";
|
std::string m_current_texture_modifier = "";
|
||||||
bool m_visuals_expired = false;
|
|
||||||
float m_step_distance_counter = 0.0f;
|
float m_step_distance_counter = 0.0f;
|
||||||
video::SColor m_last_light = video::SColor(0xFFFFFFFF);
|
|
||||||
bool m_is_visible = false;
|
|
||||||
// Material
|
|
||||||
video::E_MATERIAL_TYPE m_material_type;
|
|
||||||
f32 m_material_type_param;
|
|
||||||
|
|
||||||
bool visualExpiryRequired(const ObjectProperties &newprops) const;
|
bool visualExpiryRequired(const ObjectProperties &newprops) const;
|
||||||
|
|
||||||
|
@ -255,7 +276,7 @@ public:
|
||||||
|
|
||||||
void step(float dtime, ClientEnvironment *env) override;
|
void step(float dtime, ClientEnvironment *env) override;
|
||||||
|
|
||||||
void updateTexturePos();
|
void updateTextureAnim();
|
||||||
|
|
||||||
// ffs this HAS TO BE a string copy! See #5739 if you think otherwise
|
// ffs this HAS TO BE a string copy! See #5739 if you think otherwise
|
||||||
// Reason: updateTextures(m_previous_texture_modifier);
|
// Reason: updateTextures(m_previous_texture_modifier);
|
||||||
|
|
|
@ -121,7 +121,7 @@ void MapblockMeshGenerator::drawQuad(const TileSpec &tile, v3f *coords, const v3
|
||||||
v2f(1.0, vertical_tiling), v2f(0.0, vertical_tiling)};
|
v2f(1.0, vertical_tiling), v2f(0.0, vertical_tiling)};
|
||||||
video::S3DVertex vertices[4];
|
video::S3DVertex vertices[4];
|
||||||
bool shade_face = !cur_node.f->light_source && (normal != v3s16(0, 0, 0));
|
bool shade_face = !cur_node.f->light_source && (normal != v3s16(0, 0, 0));
|
||||||
v3f normal2(normal.X, normal.Y, normal.Z);
|
v3f normal2 = v3f::from(normal);
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
vertices[j].Pos = coords[j] + cur_node.origin;
|
vertices[j].Pos = coords[j] + cur_node.origin;
|
||||||
vertices[j].Normal = normal2;
|
vertices[j].Normal = normal2;
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
|
|
||||||
void put(MtEvent *e) override
|
void put(MtEvent *e) override
|
||||||
{
|
{
|
||||||
std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(e->getType());
|
auto i = m_dest.find(e->getType());
|
||||||
if (i != m_dest.end()) {
|
if (i != m_dest.end()) {
|
||||||
std::list<FuncSpec> &funcs = i->second.funcs;
|
std::list<FuncSpec> &funcs = i->second.funcs;
|
||||||
for (FuncSpec &func : funcs) {
|
for (FuncSpec &func : funcs) {
|
||||||
|
@ -44,7 +44,7 @@ public:
|
||||||
}
|
}
|
||||||
void reg(MtEvent::Type type, event_receive_func f, void *data) override
|
void reg(MtEvent::Type type, event_receive_func f, void *data) override
|
||||||
{
|
{
|
||||||
std::map<MtEvent::Type, Dest>::iterator i = m_dest.find(type);
|
auto i = m_dest.find(type);
|
||||||
if (i != m_dest.end()) {
|
if (i != m_dest.end()) {
|
||||||
i->second.funcs.emplace_back(f, data);
|
i->second.funcs.emplace_back(f, data);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -278,7 +278,7 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
|
||||||
};
|
};
|
||||||
|
|
||||||
auto it = m_media_faces.find(media_name);
|
auto it = m_media_faces.find(media_name);
|
||||||
if (it != m_media_faces.end()) {
|
if (spec.mode != _FM_Fallback && it != m_media_faces.end()) {
|
||||||
auto *face = it->second.get();
|
auto *face = it->second.get();
|
||||||
if (auto *font = createFont(face))
|
if (auto *font = createFont(face))
|
||||||
return font;
|
return font;
|
||||||
|
|
|
@ -564,6 +564,7 @@ protected:
|
||||||
void updatePauseState();
|
void updatePauseState();
|
||||||
void step(f32 dtime);
|
void step(f32 dtime);
|
||||||
void processClientEvents(CameraOrientation *cam);
|
void processClientEvents(CameraOrientation *cam);
|
||||||
|
void updateCameraMode(); // call after changing it
|
||||||
void updateCameraOffset();
|
void updateCameraOffset();
|
||||||
void updateCamera(f32 dtime);
|
void updateCamera(f32 dtime);
|
||||||
void updateSound(f32 dtime);
|
void updateSound(f32 dtime);
|
||||||
|
@ -665,6 +666,7 @@ private:
|
||||||
void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
|
void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
|
||||||
CameraOrientation *cam);
|
CameraOrientation *cam);
|
||||||
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
|
||||||
|
void handleClientEvent_UpdateCamera(ClientEvent *event, CameraOrientation *cam);
|
||||||
|
|
||||||
void updateChat(f32 dtime);
|
void updateChat(f32 dtime);
|
||||||
|
|
||||||
|
@ -754,7 +756,6 @@ private:
|
||||||
f32 m_repeat_dig_time;
|
f32 m_repeat_dig_time;
|
||||||
f32 m_cache_cam_smoothing;
|
f32 m_cache_cam_smoothing;
|
||||||
|
|
||||||
bool m_enable_relative_mode = false;
|
|
||||||
bool m_invert_mouse;
|
bool m_invert_mouse;
|
||||||
bool m_enable_hotbar_mouse_wheel;
|
bool m_enable_hotbar_mouse_wheel;
|
||||||
bool m_invert_hotbar_mouse_wheel;
|
bool m_invert_hotbar_mouse_wheel;
|
||||||
|
@ -770,9 +771,10 @@ private:
|
||||||
bool m_is_paused = false;
|
bool m_is_paused = false;
|
||||||
|
|
||||||
bool m_touch_simulate_aux1 = false;
|
bool m_touch_simulate_aux1 = false;
|
||||||
bool m_touch_use_crosshair;
|
inline bool isTouchShootlineUsed()
|
||||||
inline bool isTouchCrosshairDisabled() {
|
{
|
||||||
return !m_touch_use_crosshair && camera->getCameraMode() == CAMERA_MODE_FIRST;
|
return g_touchcontrols && g_touchcontrols->isShootlineAvailable() &&
|
||||||
|
camera->getCameraMode() == CAMERA_MODE_FIRST;
|
||||||
}
|
}
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
bool m_android_chat_open;
|
bool m_android_chat_open;
|
||||||
|
@ -821,8 +823,6 @@ Game::Game() :
|
||||||
&settingChangedCallback, this);
|
&settingChangedCallback, this);
|
||||||
g_settings->registerChangedCallback("pause_on_lost_focus",
|
g_settings->registerChangedCallback("pause_on_lost_focus",
|
||||||
&settingChangedCallback, this);
|
&settingChangedCallback, this);
|
||||||
g_settings->registerChangedCallback("touch_use_crosshair",
|
|
||||||
&settingChangedCallback, this);
|
|
||||||
|
|
||||||
readSettings();
|
readSettings();
|
||||||
}
|
}
|
||||||
|
@ -899,15 +899,6 @@ bool Game::startup(bool *kill,
|
||||||
|
|
||||||
m_first_loop_after_window_activation = true;
|
m_first_loop_after_window_activation = true;
|
||||||
|
|
||||||
// In principle we could always enable relative mouse mode, but it causes weird
|
|
||||||
// bugs on some setups (e.g. #14932), so we enable it only when it's required.
|
|
||||||
// That is: on Wayland or Android, because it does not support mouse repositioning
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
m_enable_relative_mode = true;
|
|
||||||
#else
|
|
||||||
m_enable_relative_mode = device->isUsingWayland();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_client_translations->clear();
|
g_client_translations->clear();
|
||||||
|
|
||||||
// address can change if simple_singleplayer_mode
|
// address can change if simple_singleplayer_mode
|
||||||
|
@ -968,7 +959,7 @@ void Game::run()
|
||||||
// Calculate dtime =
|
// Calculate dtime =
|
||||||
// m_rendering_engine->run() from this iteration
|
// m_rendering_engine->run() from this iteration
|
||||||
// + Sleep time until the wanted FPS are reached
|
// + Sleep time until the wanted FPS are reached
|
||||||
draw_times.limit(device, &dtime, g_menumgr.pausesGame());
|
draw_times.limit(device, &dtime);
|
||||||
|
|
||||||
framemarker.start();
|
framemarker.start();
|
||||||
|
|
||||||
|
@ -1378,10 +1369,8 @@ bool Game::initGui()
|
||||||
gui_chat_console = make_irr<GUIChatConsole>(guienv, guienv->getRootGUIElement(),
|
gui_chat_console = make_irr<GUIChatConsole>(guienv, guienv->getRootGUIElement(),
|
||||||
-1, chat_backend, client, &g_menumgr);
|
-1, chat_backend, client, &g_menumgr);
|
||||||
|
|
||||||
if (shouldShowTouchControls()) {
|
if (shouldShowTouchControls())
|
||||||
g_touchcontrols = new TouchControls(device, texture_src);
|
g_touchcontrols = new TouchControls(device, texture_src);
|
||||||
g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1921,6 +1910,9 @@ void Game::processKeyInput()
|
||||||
toggleFog();
|
toggleFog();
|
||||||
} else if (wasKeyDown(KeyType::TOGGLE_UPDATE_CAMERA)) {
|
} else if (wasKeyDown(KeyType::TOGGLE_UPDATE_CAMERA)) {
|
||||||
toggleUpdateCamera();
|
toggleUpdateCamera();
|
||||||
|
} else if (wasKeyPressed(KeyType::CAMERA_MODE)) {
|
||||||
|
camera->toggleCameraMode();
|
||||||
|
updateCameraMode();
|
||||||
} else if (wasKeyPressed(KeyType::TOGGLE_DEBUG)) {
|
} else if (wasKeyPressed(KeyType::TOGGLE_DEBUG)) {
|
||||||
toggleDebug();
|
toggleDebug();
|
||||||
} else if (wasKeyPressed(KeyType::TOGGLE_PROFILER)) {
|
} else if (wasKeyPressed(KeyType::TOGGLE_PROFILER)) {
|
||||||
|
@ -2359,10 +2351,8 @@ void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
|
||||||
Since Minetest has its own code to synthesize mouse events from touch events,
|
Since Minetest has its own code to synthesize mouse events from touch events,
|
||||||
this results in duplicated input. To avoid that, we don't enable relative
|
this results in duplicated input. To avoid that, we don't enable relative
|
||||||
mouse mode if we're in touchscreen mode. */
|
mouse mode if we're in touchscreen mode. */
|
||||||
if (cur_control) {
|
if (cur_control)
|
||||||
cur_control->setRelativeMode(m_enable_relative_mode &&
|
cur_control->setRelativeMode(!g_touchcontrols && !isMenuActive());
|
||||||
!g_touchcontrols && !isMenuActive());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((device->isWindowActive() && device->isWindowFocused()
|
if ((device->isWindowActive() && device->isWindowFocused()
|
||||||
&& !isMenuActive()) || input->isRandom()) {
|
&& !isMenuActive()) || input->isRandom()) {
|
||||||
|
@ -2433,7 +2423,7 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
|
||||||
cam->camera_pitch += input->joystick.getAxisWithoutDead(JA_FRUSTUM_VERTICAL) * c;
|
cam->camera_pitch += input->joystick.getAxisWithoutDead(JA_FRUSTUM_VERTICAL) * c;
|
||||||
}
|
}
|
||||||
|
|
||||||
cam->camera_pitch = rangelim(cam->camera_pitch, -89.5, 89.5);
|
cam->camera_pitch = rangelim(cam->camera_pitch, -90, 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2504,7 +2494,7 @@ inline void Game::step(f32 dtime)
|
||||||
ZoneScoped;
|
ZoneScoped;
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
float fps_max = (!device->isWindowFocused() || g_menumgr.pausesGame()) ?
|
float fps_max = !device->isWindowFocused() && simple_singleplayer_mode ?
|
||||||
g_settings->getFloat("fps_max_unfocused") :
|
g_settings->getFloat("fps_max_unfocused") :
|
||||||
g_settings->getFloat("fps_max");
|
g_settings->getFloat("fps_max");
|
||||||
fps_max = std::max(fps_max, 1.0f);
|
fps_max = std::max(fps_max, 1.0f);
|
||||||
|
@ -2575,6 +2565,7 @@ const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
|
||||||
{&Game::handleClientEvent_SetStars},
|
{&Game::handleClientEvent_SetStars},
|
||||||
{&Game::handleClientEvent_OverrideDayNigthRatio},
|
{&Game::handleClientEvent_OverrideDayNigthRatio},
|
||||||
{&Game::handleClientEvent_CloudParams},
|
{&Game::handleClientEvent_CloudParams},
|
||||||
|
{&Game::handleClientEvent_UpdateCamera},
|
||||||
};
|
};
|
||||||
|
|
||||||
void Game::handleClientEvent_None(ClientEvent *event, CameraOrientation *cam)
|
void Game::handleClientEvent_None(ClientEvent *event, CameraOrientation *cam)
|
||||||
|
@ -2879,6 +2870,13 @@ void Game::handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *
|
||||||
clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
|
clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::handleClientEvent_UpdateCamera(ClientEvent *event, CameraOrientation *cam)
|
||||||
|
{
|
||||||
|
// no parameters to update here, this just makes sure the camera is in the
|
||||||
|
// state it should be after something was changed.
|
||||||
|
updateCameraMode();
|
||||||
|
}
|
||||||
|
|
||||||
void Game::processClientEvents(CameraOrientation *cam)
|
void Game::processClientEvents(CameraOrientation *cam)
|
||||||
{
|
{
|
||||||
while (client->hasClientEvents()) {
|
while (client->hasClientEvents()) {
|
||||||
|
@ -2935,12 +2933,7 @@ void Game::updateCamera(f32 dtime)
|
||||||
ClientEnvironment &env = client->getEnv();
|
ClientEnvironment &env = client->getEnv();
|
||||||
LocalPlayer *player = env.getLocalPlayer();
|
LocalPlayer *player = env.getLocalPlayer();
|
||||||
|
|
||||||
/*
|
// For interaction purposes, get info about the held item
|
||||||
For interaction purposes, get info about the held item
|
|
||||||
- What item is it?
|
|
||||||
- Is it a usable item?
|
|
||||||
- Can it point to liquids?
|
|
||||||
*/
|
|
||||||
ItemStack playeritem;
|
ItemStack playeritem;
|
||||||
{
|
{
|
||||||
ItemStack selected, hand;
|
ItemStack selected, hand;
|
||||||
|
@ -2950,23 +2943,6 @@ void Game::updateCamera(f32 dtime)
|
||||||
ToolCapabilities playeritem_toolcap =
|
ToolCapabilities playeritem_toolcap =
|
||||||
playeritem.getToolCapabilities(itemdef_manager);
|
playeritem.getToolCapabilities(itemdef_manager);
|
||||||
|
|
||||||
if (wasKeyPressed(KeyType::CAMERA_MODE)) {
|
|
||||||
GenericCAO *playercao = player->getCAO();
|
|
||||||
|
|
||||||
// If playercao not loaded, don't change camera
|
|
||||||
if (!playercao)
|
|
||||||
return;
|
|
||||||
|
|
||||||
camera->toggleCameraMode();
|
|
||||||
|
|
||||||
if (g_touchcontrols)
|
|
||||||
g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled());
|
|
||||||
|
|
||||||
// Make the player visible depending on camera mode.
|
|
||||||
playercao->updateMeshCulling();
|
|
||||||
playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
|
|
||||||
}
|
|
||||||
|
|
||||||
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
||||||
float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
|
float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
|
||||||
|
|
||||||
|
@ -2981,6 +2957,22 @@ void Game::updateCamera(f32 dtime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::updateCameraMode()
|
||||||
|
{
|
||||||
|
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
||||||
|
|
||||||
|
// Obey server choice
|
||||||
|
if (player->allowed_camera_mode != CAMERA_MODE_ANY)
|
||||||
|
camera->setCameraMode(player->allowed_camera_mode);
|
||||||
|
|
||||||
|
GenericCAO *playercao = player->getCAO();
|
||||||
|
if (playercao) {
|
||||||
|
// Make the player visible depending on camera mode.
|
||||||
|
playercao->updateMeshCulling();
|
||||||
|
playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Game::updateCameraOffset()
|
void Game::updateCameraOffset()
|
||||||
{
|
{
|
||||||
ClientEnvironment &env = client->getEnv();
|
ClientEnvironment &env = client->getEnv();
|
||||||
|
@ -2997,8 +2989,13 @@ void Game::updateCameraOffset()
|
||||||
|
|
||||||
if (!m_flags.disable_camera_update) {
|
if (!m_flags.disable_camera_update) {
|
||||||
auto *shadow = RenderingEngine::get_shadow_renderer();
|
auto *shadow = RenderingEngine::get_shadow_renderer();
|
||||||
if (shadow)
|
if (shadow) {
|
||||||
shadow->getDirectionalLight().updateCameraOffset(camera);
|
shadow->getDirectionalLight().updateCameraOffset(camera);
|
||||||
|
// FIXME: I bet we can be smarter about this and don't need to redraw
|
||||||
|
// the shadow map at all, but this is for someone else to figure out.
|
||||||
|
if (!g_settings->getFlag("performance_tradeoffs"))
|
||||||
|
shadow->setForceUpdateShadowMap();
|
||||||
|
}
|
||||||
|
|
||||||
env.getClientMap().updateCamera(camera->getPosition(),
|
env.getClientMap().updateCamera(camera->getPosition(),
|
||||||
camera->getDirection(), camera->getFovMax(), camera_offset,
|
camera->getDirection(), camera->getFovMax(), camera_offset,
|
||||||
|
@ -3057,6 +3054,9 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
|
||||||
core::line3d<f32> shootline;
|
core::line3d<f32> shootline;
|
||||||
|
|
||||||
switch (camera->getCameraMode()) {
|
switch (camera->getCameraMode()) {
|
||||||
|
case CAMERA_MODE_ANY:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
case CAMERA_MODE_FIRST:
|
case CAMERA_MODE_FIRST:
|
||||||
// Shoot from camera position, with bobbing
|
// Shoot from camera position, with bobbing
|
||||||
shootline.start = camera->getPosition();
|
shootline.start = camera->getPosition();
|
||||||
|
@ -3073,7 +3073,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
|
||||||
}
|
}
|
||||||
shootline.end = shootline.start + camera_direction * BS * d;
|
shootline.end = shootline.start + camera_direction * BS * d;
|
||||||
|
|
||||||
if (g_touchcontrols && isTouchCrosshairDisabled()) {
|
if (isTouchShootlineUsed()) {
|
||||||
shootline = g_touchcontrols->getShootline();
|
shootline = g_touchcontrols->getShootline();
|
||||||
// Scale shootline to the acual distance the player can reach
|
// Scale shootline to the acual distance the player can reach
|
||||||
shootline.end = shootline.start +
|
shootline.end = shootline.start +
|
||||||
|
@ -3232,9 +3232,10 @@ PointedThing Game::updatePointedThing(
|
||||||
hud->setSelectionPos(pos, camera_offset);
|
hud->setSelectionPos(pos, camera_offset);
|
||||||
GenericCAO* gcao = dynamic_cast<GenericCAO*>(runData.selected_object);
|
GenericCAO* gcao = dynamic_cast<GenericCAO*>(runData.selected_object);
|
||||||
if (gcao != nullptr && gcao->getProperties().rotate_selectionbox)
|
if (gcao != nullptr && gcao->getProperties().rotate_selectionbox)
|
||||||
hud->setSelectionRotation(gcao->getSceneNode()->getAbsoluteTransformation().getRotationDegrees());
|
hud->setSelectionRotationRadians(gcao->getSceneNode()
|
||||||
|
->getAbsoluteTransformation().getRotationRadians());
|
||||||
else
|
else
|
||||||
hud->setSelectionRotation(v3f());
|
hud->setSelectionRotationRadians(v3f());
|
||||||
}
|
}
|
||||||
hud->setSelectedFaceNormal(result.raw_intersection_normal);
|
hud->setSelectedFaceNormal(result.raw_intersection_normal);
|
||||||
} else if (result.type == POINTEDTHING_NODE) {
|
} else if (result.type == POINTEDTHING_NODE) {
|
||||||
|
@ -3244,17 +3245,15 @@ PointedThing Game::updatePointedThing(
|
||||||
n.getSelectionBoxes(nodedef, &boxes,
|
n.getSelectionBoxes(nodedef, &boxes,
|
||||||
n.getNeighbors(result.node_undersurface, &map));
|
n.getNeighbors(result.node_undersurface, &map));
|
||||||
|
|
||||||
f32 d = 0.002 * BS;
|
f32 d = 0.002f * BS;
|
||||||
for (std::vector<aabb3f>::const_iterator i = boxes.begin();
|
for (aabb3f box : boxes) {
|
||||||
i != boxes.end(); ++i) {
|
|
||||||
aabb3f box = *i;
|
|
||||||
box.MinEdge -= v3f(d, d, d);
|
box.MinEdge -= v3f(d, d, d);
|
||||||
box.MaxEdge += v3f(d, d, d);
|
box.MaxEdge += v3f(d, d, d);
|
||||||
selectionboxes->push_back(box);
|
selectionboxes->push_back(box);
|
||||||
}
|
}
|
||||||
hud->setSelectionPos(intToFloat(result.node_undersurface, BS),
|
hud->setSelectionPos(intToFloat(result.node_undersurface, BS),
|
||||||
camera_offset);
|
camera_offset);
|
||||||
hud->setSelectionRotation(v3f());
|
hud->setSelectionRotationRadians(v3f());
|
||||||
hud->setSelectedFaceNormal(result.intersection_normal);
|
hud->setSelectedFaceNormal(result.intersection_normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3449,9 +3448,8 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
|
||||||
u8 predicted_param2 = dir.Y < 0 ? 1 : 0;
|
u8 predicted_param2 = dir.Y < 0 ? 1 : 0;
|
||||||
if (selected_def.wallmounted_rotate_vertical) {
|
if (selected_def.wallmounted_rotate_vertical) {
|
||||||
bool rotate90 = false;
|
bool rotate90 = false;
|
||||||
v3f fnodepos = v3f(neighborpos.X, neighborpos.Y, neighborpos.Z);
|
|
||||||
v3f ppos = client->getEnv().getLocalPlayer()->getPosition() / BS;
|
v3f ppos = client->getEnv().getLocalPlayer()->getPosition() / BS;
|
||||||
v3f pdir = fnodepos - ppos;
|
v3f pdir = v3f::from(neighborpos) - ppos;
|
||||||
switch (predicted_f.drawtype) {
|
switch (predicted_f.drawtype) {
|
||||||
case NDT_TORCHLIKE: {
|
case NDT_TORCHLIKE: {
|
||||||
rotate90 = !((pdir.X < 0 && pdir.Z > 0) ||
|
rotate90 = !((pdir.X < 0 && pdir.Z > 0) ||
|
||||||
|
@ -4046,7 +4044,7 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats)
|
||||||
(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
|
(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
|
||||||
(this->camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
|
(this->camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
|
||||||
|
|
||||||
if (g_touchcontrols && isTouchCrosshairDisabled())
|
if (isTouchShootlineUsed())
|
||||||
draw_crosshair = false;
|
draw_crosshair = false;
|
||||||
|
|
||||||
this->m_rendering_engine->draw_scene(sky_color, this->m_game_ui->m_flags.show_hud,
|
this->m_rendering_engine->draw_scene(sky_color, this->m_game_ui->m_flags.show_hud,
|
||||||
|
@ -4126,10 +4124,6 @@ void Game::readSettings()
|
||||||
m_invert_hotbar_mouse_wheel = g_settings->getBool("invert_hotbar_mouse_wheel");
|
m_invert_hotbar_mouse_wheel = g_settings->getBool("invert_hotbar_mouse_wheel");
|
||||||
|
|
||||||
m_does_lost_focus_pause_game = g_settings->getBool("pause_on_lost_focus");
|
m_does_lost_focus_pause_game = g_settings->getBool("pause_on_lost_focus");
|
||||||
|
|
||||||
m_touch_use_crosshair = g_settings->getBool("touch_use_crosshair");
|
|
||||||
if (g_touchcontrols)
|
|
||||||
g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
|
@ -283,9 +283,7 @@ void GameFormSpec::showPauseMenuFormSpec(const std::string &formspec, const std:
|
||||||
&m_input->joystick, fs_src, txt_dst, "",
|
&m_input->joystick, fs_src, txt_dst, "",
|
||||||
m_client->getSoundManager());
|
m_client->getSoundManager());
|
||||||
|
|
||||||
// FIXME: can't enable this for now because "fps_max_unfocused" also applies
|
m_formspec->doPause = true;
|
||||||
// when the game is paused, making the settings menu much less enjoyable.
|
|
||||||
// m_formspec->doPause = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameFormSpec::showNodeFormspec(const std::string &formspec, const v3s16 &nodepos)
|
void GameFormSpec::showNodeFormspec(const std::string &formspec, const v3s16 &nodepos)
|
||||||
|
@ -376,18 +374,18 @@ void GameFormSpec::showPauseMenu()
|
||||||
<< strgettext("Continue") << "]";
|
<< strgettext("Continue") << "]";
|
||||||
|
|
||||||
if (!simple_singleplayer_mode) {
|
if (!simple_singleplayer_mode) {
|
||||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_change_password;"
|
os << "button[4," << (ypos++) << ";3,0.5;btn_change_password;"
|
||||||
<< strgettext("Change Password") << "]";
|
<< strgettext("Change Password") << "]";
|
||||||
} else {
|
} else {
|
||||||
os << "field[4.95,0;5,1.5;;" << strgettext("Game paused") << ";]";
|
os << "field[4.95,0;5,1.5;;" << strgettext("Game paused") << ";]";
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_settings;"
|
os << "button[4," << (ypos++) << ";3,0.5;btn_settings;"
|
||||||
<< strgettext("Settings") << "]";
|
<< strgettext("Settings") << "]";
|
||||||
|
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
#if USE_SOUND
|
#if USE_SOUND
|
||||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
|
os << "button[4," << (ypos++) << ";3,0.5;btn_sound;"
|
||||||
<< strgettext("Sound Volume") << "]";
|
<< strgettext("Sound Volume") << "]";
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -880,7 +880,7 @@ void Hud::drawSelectionMesh()
|
||||||
core::matrix4 translate;
|
core::matrix4 translate;
|
||||||
translate.setTranslation(m_selection_pos_with_offset);
|
translate.setTranslation(m_selection_pos_with_offset);
|
||||||
core::matrix4 rotation;
|
core::matrix4 rotation;
|
||||||
rotation.setRotationDegrees(m_selection_rotation);
|
rotation.setRotationRadians(m_selection_rotation_radians);
|
||||||
driver->setTransform(video::ETS_WORLD, translate * rotation);
|
driver->setTransform(video::ETS_WORLD, translate * rotation);
|
||||||
|
|
||||||
if (m_mode == HIGHLIGHT_BOX) {
|
if (m_mode == HIGHLIGHT_BOX) {
|
||||||
|
@ -965,8 +965,8 @@ void Hud::drawBlockBounds()
|
||||||
v3f pmax = v3f(x, y, 1 + radius) * MAP_BLOCKSIZE * BS;
|
v3f pmax = v3f(x, y, 1 + radius) * MAP_BLOCKSIZE * BS;
|
||||||
|
|
||||||
driver->draw3DLine(
|
driver->draw3DLine(
|
||||||
base_corner + v3f(pmin.X, pmin.Y, pmin.Z),
|
base_corner + pmin,
|
||||||
base_corner + v3f(pmax.X, pmax.Y, pmax.Z),
|
base_corner + pmax,
|
||||||
choose_color(block_pos.X, block_pos.Y)
|
choose_color(block_pos.X, block_pos.Y)
|
||||||
);
|
);
|
||||||
driver->draw3DLine(
|
driver->draw3DLine(
|
||||||
|
|
|
@ -74,9 +74,15 @@ public:
|
||||||
|
|
||||||
v3f getSelectionPos() const { return m_selection_pos; }
|
v3f getSelectionPos() const { return m_selection_pos; }
|
||||||
|
|
||||||
void setSelectionRotation(v3f rotation) { m_selection_rotation = rotation; }
|
void setSelectionRotationRadians(v3f rotation)
|
||||||
|
{
|
||||||
|
m_selection_rotation_radians = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
v3f getSelectionRotation() const { return m_selection_rotation; }
|
v3f getSelectionRotationRadians() const
|
||||||
|
{
|
||||||
|
return m_selection_rotation_radians;
|
||||||
|
}
|
||||||
|
|
||||||
void setSelectionMeshColor(const video::SColor &color)
|
void setSelectionMeshColor(const video::SColor &color)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +135,7 @@ private:
|
||||||
std::vector<aabb3f> m_halo_boxes;
|
std::vector<aabb3f> m_halo_boxes;
|
||||||
v3f m_selection_pos;
|
v3f m_selection_pos;
|
||||||
v3f m_selection_pos_with_offset;
|
v3f m_selection_pos_with_offset;
|
||||||
v3f m_selection_rotation;
|
v3f m_selection_rotation_radians;
|
||||||
|
|
||||||
scene::IMesh *m_selection_mesh = nullptr;
|
scene::IMesh *m_selection_mesh = nullptr;
|
||||||
video::SColor m_selection_mesh_color;
|
video::SColor m_selection_mesh_color;
|
||||||
|
|
|
@ -285,13 +285,13 @@ void imageScaleNNAA(video::IImage *src, const core::rect<s32> &srcrect, video::I
|
||||||
maxsx = minsx + sw / dim.Width;
|
maxsx = minsx + sw / dim.Width;
|
||||||
maxsx = rangelim(maxsx, 0, sox + sw);
|
maxsx = rangelim(maxsx, 0, sox + sw);
|
||||||
if (minsx > maxsx)
|
if (minsx > maxsx)
|
||||||
SWAP(double, minsx, maxsx);
|
std::swap(minsx, maxsx);
|
||||||
minsy = soy + (dy * sh / dim.Height);
|
minsy = soy + (dy * sh / dim.Height);
|
||||||
minsy = rangelim(minsy, 0, soy + sh);
|
minsy = rangelim(minsy, 0, soy + sh);
|
||||||
maxsy = minsy + sh / dim.Height;
|
maxsy = minsy + sh / dim.Height;
|
||||||
maxsy = rangelim(maxsy, 0, soy + sh);
|
maxsy = rangelim(maxsy, 0, soy + sh);
|
||||||
if (minsy > maxsy)
|
if (minsy > maxsy)
|
||||||
SWAP(double, minsy, maxsy);
|
std::swap(minsy, maxsy);
|
||||||
|
|
||||||
// Total area, and integral of r, g, b values over that area,
|
// Total area, and integral of r, g, b values over that area,
|
||||||
// initialized to zero, to be summed up in next loops.
|
// initialized to zero, to be summed up in next loops.
|
||||||
|
|
|
@ -426,20 +426,6 @@ void getNodeTile(MapNode mn, const v3s16 &p, const v3s16 &dir, MeshMakeData *dat
|
||||||
tile.rotation = tile.world_aligned ? TileRotation::None : dir_to_tile[facedir][dir_i].rotation;
|
tile.rotation = tile.world_aligned ? TileRotation::None : dir_to_tile[facedir][dir_i].rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyTileColor(PreMeshBuffer &pmb)
|
|
||||||
{
|
|
||||||
video::SColor tc = pmb.layer.color;
|
|
||||||
if (tc == video::SColor(0xFFFFFFFF))
|
|
||||||
return;
|
|
||||||
for (video::S3DVertex &vertex : pmb.vertices) {
|
|
||||||
video::SColor *c = &vertex.Color;
|
|
||||||
c->set(c->getAlpha(),
|
|
||||||
c->getRed() * tc.getRed() / 255,
|
|
||||||
c->getGreen() * tc.getGreen() / 255,
|
|
||||||
c->getBlue() * tc.getBlue() / 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MapBlockBspTree
|
MapBlockBspTree
|
||||||
*/
|
*/
|
||||||
|
@ -668,7 +654,7 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data):
|
||||||
{
|
{
|
||||||
PreMeshBuffer &p = collector.prebuffers[layer][i];
|
PreMeshBuffer &p = collector.prebuffers[layer][i];
|
||||||
|
|
||||||
applyTileColor(p);
|
p.applyTileColor();
|
||||||
|
|
||||||
// Generate animation data
|
// Generate animation data
|
||||||
// - Cracks
|
// - Cracks
|
||||||
|
@ -701,28 +687,16 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data):
|
||||||
|
|
||||||
// Create material
|
// Create material
|
||||||
video::SMaterial material;
|
video::SMaterial material;
|
||||||
material.BackfaceCulling = true;
|
|
||||||
material.FogEnable = true;
|
material.FogEnable = true;
|
||||||
material.setTexture(0, p.layer.texture);
|
|
||||||
material.forEachTexture([] (auto &tex) {
|
material.forEachTexture([] (auto &tex) {
|
||||||
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
||||||
tex.MagFilter = video::ETMAGF_NEAREST;
|
tex.MagFilter = video::ETMAGF_NEAREST;
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
* The second layer is for overlays, but uses the same vertex positions
|
|
||||||
* as the first, which quickly leads to z-fighting.
|
|
||||||
* To fix this we can offset the polygons in the direction of the camera.
|
|
||||||
* This only affects the depth buffer and leads to no visual gaps in geometry.
|
|
||||||
*/
|
|
||||||
if (layer == 1) {
|
|
||||||
material.PolygonOffsetSlopeScale = -1;
|
|
||||||
material.PolygonOffsetDepthBias = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
material.MaterialType = m_shdrsrc->getShaderInfo(
|
material.MaterialType = m_shdrsrc->getShaderInfo(
|
||||||
p.layer.shader_id).material;
|
p.layer.shader_id).material;
|
||||||
p.layer.applyMaterialOptionsWithShaders(material);
|
p.layer.applyMaterialOptions(material, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
|
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
|
|
|
@ -145,8 +145,7 @@ QueuedMeshUpdate *MeshUpdateQueue::pop()
|
||||||
MutexAutoLock lock(m_mutex);
|
MutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
bool must_be_urgent = !m_urgents.empty();
|
bool must_be_urgent = !m_urgents.empty();
|
||||||
for (std::vector<QueuedMeshUpdate*>::iterator i = m_queue.begin();
|
for (auto i = m_queue.begin(); i != m_queue.end(); ++i) {
|
||||||
i != m_queue.end(); ++i) {
|
|
||||||
QueuedMeshUpdate *q = *i;
|
QueuedMeshUpdate *q = *i;
|
||||||
if (must_be_urgent && m_urgents.count(q->p) == 0)
|
if (must_be_urgent && m_urgents.count(q->p) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -264,8 +263,8 @@ void MeshUpdateManager::updateBlock(Map *map, v3s16 p, bool ack_block_to_server,
|
||||||
g_settings->getBool("smooth_lighting")
|
g_settings->getBool("smooth_lighting")
|
||||||
&& !g_settings->getFlag("performance_tradeoffs");
|
&& !g_settings->getFlag("performance_tradeoffs");
|
||||||
if (!m_queue_in.addBlock(map, p, ack_block_to_server, urgent)) {
|
if (!m_queue_in.addBlock(map, p, ack_block_to_server, urgent)) {
|
||||||
warningstream << "Update requested for non-existent block at ("
|
warningstream << "Update requested for non-existent block at "
|
||||||
<< p.X << ", " << p.Y << ", " << p.Z << ")" << std::endl;
|
<< p << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (update_neighbors) {
|
if (update_neighbors) {
|
||||||
|
|
|
@ -18,6 +18,21 @@ struct PreMeshBuffer
|
||||||
|
|
||||||
PreMeshBuffer() = default;
|
PreMeshBuffer() = default;
|
||||||
explicit PreMeshBuffer(const TileLayer &layer) : layer(layer) {}
|
explicit PreMeshBuffer(const TileLayer &layer) : layer(layer) {}
|
||||||
|
|
||||||
|
/// @brief Colorizes vertices as indicated by tile layer
|
||||||
|
void applyTileColor()
|
||||||
|
{
|
||||||
|
video::SColor tc = layer.color;
|
||||||
|
if (tc == video::SColor(0xFFFFFFFF))
|
||||||
|
return;
|
||||||
|
for (auto &vertex : vertices) {
|
||||||
|
video::SColor *c = &vertex.Color;
|
||||||
|
c->set(c->getAlpha(),
|
||||||
|
c->getRed() * tc.getRed() / 255U,
|
||||||
|
c->getGreen() * tc.getGreen() / 255U,
|
||||||
|
c->getBlue() * tc.getBlue() / 255U);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshCollector
|
struct MeshCollector
|
||||||
|
|
|
@ -78,15 +78,13 @@ void MinimapUpdateThread::doUpdate()
|
||||||
while (popBlockUpdate(&update)) {
|
while (popBlockUpdate(&update)) {
|
||||||
if (update.data) {
|
if (update.data) {
|
||||||
// Swap two values in the map using single lookup
|
// Swap two values in the map using single lookup
|
||||||
std::pair<std::map<v3s16, MinimapMapblock*>::iterator, bool>
|
auto result = m_blocks_cache.insert(std::make_pair(update.pos, update.data));
|
||||||
result = m_blocks_cache.insert(std::make_pair(update.pos, update.data));
|
|
||||||
if (!result.second) {
|
if (!result.second) {
|
||||||
delete result.first->second;
|
delete result.first->second;
|
||||||
result.first->second = update.data;
|
result.first->second = update.data;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::map<v3s16, MinimapMapblock *>::iterator it;
|
auto it = m_blocks_cache.find(update.pos);
|
||||||
it = m_blocks_cache.find(update.pos);
|
|
||||||
if (it != m_blocks_cache.end()) {
|
if (it != m_blocks_cache.end()) {
|
||||||
delete it->second;
|
delete it->second;
|
||||||
m_blocks_cache.erase(it);
|
m_blocks_cache.erase(it);
|
||||||
|
@ -124,8 +122,7 @@ void MinimapUpdateThread::getMap(v3s16 pos, s16 size, s16 height)
|
||||||
for (blockpos.Z = blockpos_min.Z; blockpos.Z <= blockpos_max.Z; ++blockpos.Z)
|
for (blockpos.Z = blockpos_min.Z; blockpos.Z <= blockpos_max.Z; ++blockpos.Z)
|
||||||
for (blockpos.Y = blockpos_min.Y; blockpos.Y <= blockpos_max.Y; ++blockpos.Y)
|
for (blockpos.Y = blockpos_min.Y; blockpos.Y <= blockpos_max.Y; ++blockpos.Y)
|
||||||
for (blockpos.X = blockpos_min.X; blockpos.X <= blockpos_max.X; ++blockpos.X) {
|
for (blockpos.X = blockpos_min.X; blockpos.X <= blockpos_max.X; ++blockpos.X) {
|
||||||
std::map<v3s16, MinimapMapblock *>::const_iterator pblock =
|
auto pblock = m_blocks_cache.find(blockpos);
|
||||||
m_blocks_cache.find(blockpos);
|
|
||||||
if (pblock == m_blocks_cache.end())
|
if (pblock == m_blocks_cache.end())
|
||||||
continue;
|
continue;
|
||||||
const MinimapMapblock &block = *pblock->second;
|
const MinimapMapblock &block = *pblock->second;
|
||||||
|
@ -647,8 +644,7 @@ void Minimap::drawMinimap(core::rect<s32> rect)
|
||||||
f32 sin_angle = std::sin(m_angle * core::DEGTORAD);
|
f32 sin_angle = std::sin(m_angle * core::DEGTORAD);
|
||||||
f32 cos_angle = std::cos(m_angle * core::DEGTORAD);
|
f32 cos_angle = std::cos(m_angle * core::DEGTORAD);
|
||||||
s32 marker_size2 = 0.025 * (float)rect.getWidth();;
|
s32 marker_size2 = 0.025 * (float)rect.getWidth();;
|
||||||
for (std::list<v2f>::const_iterator
|
for (auto i = m_active_markers.begin();
|
||||||
i = m_active_markers.begin();
|
|
||||||
i != m_active_markers.end(); ++i) {
|
i != m_active_markers.end(); ++i) {
|
||||||
v2f posf = *i;
|
v2f posf = *i;
|
||||||
if (data->minimap_shape_round) {
|
if (data->minimap_shape_round) {
|
||||||
|
|
|
@ -193,7 +193,7 @@ void Particle::updateVertices(ClientEnvironment *env, video::SColor color)
|
||||||
video::S3DVertex *vertices = m_buffer->getVertices(m_index);
|
video::S3DVertex *vertices = m_buffer->getVertices(m_index);
|
||||||
|
|
||||||
if (m_texture.tex != nullptr)
|
if (m_texture.tex != nullptr)
|
||||||
scale = m_texture.tex -> scale.blend(m_time / (m_expiration+0.1));
|
scale = m_texture.tex -> scale.blend(m_time / (m_expiration+0.1f));
|
||||||
else
|
else
|
||||||
scale = v2f(1.f, 1.f);
|
scale = v2f(1.f, 1.f);
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ void Particle::updateVertices(ClientEnvironment *env, video::SColor color)
|
||||||
v2u32 framesize;
|
v2u32 framesize;
|
||||||
texcoord = m_p.animation.getTextureCoords(texsize, m_animation_frame);
|
texcoord = m_p.animation.getTextureCoords(texsize, m_animation_frame);
|
||||||
m_p.animation.determineParams(texsize, NULL, NULL, &framesize);
|
m_p.animation.determineParams(texsize, NULL, NULL, &framesize);
|
||||||
framesize_f = v2f(framesize.X / (float) texsize.X, framesize.Y / (float) texsize.Y);
|
framesize_f = v2f::from(framesize) / v2f::from(texsize);
|
||||||
|
|
||||||
tx0 = m_texpos.X + texcoord.X;
|
tx0 = m_texpos.X + texcoord.X;
|
||||||
tx1 = m_texpos.X + texcoord.X + framesize_f.X * m_texsize.X;
|
tx1 = m_texpos.X + texcoord.X + framesize_f.X * m_texsize.X;
|
||||||
|
|
|
@ -34,9 +34,9 @@ void FpsControl::reset()
|
||||||
last_time = porting::getTimeUs();
|
last_time = porting::getTimeUs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FpsControl::limit(IrrlichtDevice *device, f32 *dtime, bool assume_paused)
|
void FpsControl::limit(IrrlichtDevice *device, f32 *dtime)
|
||||||
{
|
{
|
||||||
const float fps_limit = (device->isWindowFocused() && !assume_paused)
|
const float fps_limit = device->isWindowFocused()
|
||||||
? g_settings->getFloat("fps_max")
|
? g_settings->getFloat("fps_max")
|
||||||
: g_settings->getFloat("fps_max_unfocused");
|
: g_settings->getFloat("fps_max_unfocused");
|
||||||
const u64 frametime_min = 1000000.0f / std::max(fps_limit, 1.0f);
|
const u64 frametime_min = 1000000.0f / std::max(fps_limit, 1.0f);
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct FpsControl {
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void limit(IrrlichtDevice *device, f32 *dtime, bool assume_paused = false);
|
void limit(IrrlichtDevice *device, f32 *dtime);
|
||||||
|
|
||||||
u32 getBusyMs() const { return busy_time / 1000; }
|
u32 getBusyMs() const { return busy_time / 1000; }
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
|
||||||
// adjusted frustum boundaries
|
// adjusted frustum boundaries
|
||||||
float sfNear = future_frustum.zNear;
|
float sfNear = future_frustum.zNear;
|
||||||
float sfFar = adjustDist(future_frustum.zFar, cam->getFovY());
|
float sfFar = adjustDist(future_frustum.zFar, cam->getFovY());
|
||||||
|
assert(sfFar - sfNear > 0);
|
||||||
|
|
||||||
// adjusted camera positions
|
// adjusted camera positions
|
||||||
v3f cam_pos_world = cam->getPosition();
|
v3f cam_pos_world = cam->getPosition();
|
||||||
|
@ -74,7 +75,6 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
|
||||||
future_frustum.ViewMat.buildCameraLookAtMatrixLH(eye, center_scene, v3f(0.0f, 1.0f, 0.0f));
|
future_frustum.ViewMat.buildCameraLookAtMatrixLH(eye, center_scene, v3f(0.0f, 1.0f, 0.0f));
|
||||||
future_frustum.ProjOrthMat.buildProjectionMatrixOrthoLH(radius, radius,
|
future_frustum.ProjOrthMat.buildProjectionMatrixOrthoLH(radius, radius,
|
||||||
0.0f, length, false);
|
0.0f, length, false);
|
||||||
future_frustum.camera_offset = cam->getOffset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectionalLight::DirectionalLight(const u32 shadowMapResolution,
|
DirectionalLight::DirectionalLight(const u32 shadowMapResolution,
|
||||||
|
@ -86,6 +86,8 @@ DirectionalLight::DirectionalLight(const u32 shadowMapResolution,
|
||||||
|
|
||||||
void DirectionalLight::updateCameraOffset(const Camera *cam)
|
void DirectionalLight::updateCameraOffset(const Camera *cam)
|
||||||
{
|
{
|
||||||
|
if (future_frustum.zFar == 0.0f) // not initialized
|
||||||
|
return;
|
||||||
createSplitMatrices(cam);
|
createSplitMatrices(cam);
|
||||||
should_update_map_shadow = true;
|
should_update_map_shadow = true;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
|
@ -22,7 +22,6 @@ struct shadowFrustum
|
||||||
core::matrix4 ViewMat;
|
core::matrix4 ViewMat;
|
||||||
v3f position;
|
v3f position;
|
||||||
v3f player;
|
v3f player;
|
||||||
v3s16 camera_offset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirectionalLight
|
class DirectionalLight
|
||||||
|
@ -85,6 +84,7 @@ public:
|
||||||
return mapRes;
|
return mapRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If true, shadow map needs to be invalidated due to frustum change
|
||||||
bool should_update_map_shadow{true};
|
bool should_update_map_shadow{true};
|
||||||
|
|
||||||
void commitFrustum();
|
void commitFrustum();
|
||||||
|
|
|
@ -177,14 +177,15 @@ void ShadowRenderer::removeNodeFromShadowList(scene::ISceneNode *node)
|
||||||
node->forEachMaterial([] (auto &mat) {
|
node->forEachMaterial([] (auto &mat) {
|
||||||
mat.setTexture(TEXTURE_LAYER_SHADOW, nullptr);
|
mat.setTexture(TEXTURE_LAYER_SHADOW, nullptr);
|
||||||
});
|
});
|
||||||
for (auto it = m_shadow_node_array.begin(); it != m_shadow_node_array.end();) {
|
|
||||||
if (it->node == node) {
|
auto it = std::find(m_shadow_node_array.begin(), m_shadow_node_array.end(), node);
|
||||||
it = m_shadow_node_array.erase(it);
|
if (it == m_shadow_node_array.end()) {
|
||||||
break;
|
infostream << "removeNodeFromShadowList: " << node << " not found" << std::endl;
|
||||||
} else {
|
return;
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// swap with last, then remove
|
||||||
|
*it = m_shadow_node_array.back();
|
||||||
|
m_shadow_node_array.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowRenderer::updateSMTextures()
|
void ShadowRenderer::updateSMTextures()
|
||||||
|
@ -254,17 +255,14 @@ void ShadowRenderer::updateSMTextures()
|
||||||
if (!m_shadow_node_array.empty()) {
|
if (!m_shadow_node_array.empty()) {
|
||||||
bool reset_sm_texture = false;
|
bool reset_sm_texture = false;
|
||||||
|
|
||||||
// detect if SM should be regenerated
|
// clear texture if requested
|
||||||
for (DirectionalLight &light : m_light_list) {
|
for (DirectionalLight &light : m_light_list) {
|
||||||
if (light.should_update_map_shadow)
|
reset_sm_texture |= light.should_update_map_shadow;
|
||||||
m_force_update_shadow_map = true;
|
|
||||||
light.should_update_map_shadow = false;
|
light.should_update_map_shadow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_force_update_shadow_map) {
|
if (reset_sm_texture || m_force_update_shadow_map)
|
||||||
m_current_frame = 0;
|
m_current_frame = 0;
|
||||||
reset_sm_texture = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
video::ITexture* shadowMapTargetTexture = shadowMapClientMapFuture;
|
video::ITexture* shadowMapTargetTexture = shadowMapClientMapFuture;
|
||||||
if (shadowMapTargetTexture == nullptr)
|
if (shadowMapTargetTexture == nullptr)
|
||||||
|
@ -273,7 +271,7 @@ void ShadowRenderer::updateSMTextures()
|
||||||
// Update SM incrementally:
|
// Update SM incrementally:
|
||||||
for (DirectionalLight &light : m_light_list) {
|
for (DirectionalLight &light : m_light_list) {
|
||||||
// Static shader values.
|
// Static shader values.
|
||||||
for (auto cb : {m_shadow_depth_cb, m_shadow_depth_entity_cb, m_shadow_depth_trans_cb})
|
for (auto cb : {m_shadow_depth_cb, m_shadow_depth_entity_cb, m_shadow_depth_trans_cb}) {
|
||||||
if (cb) {
|
if (cb) {
|
||||||
cb->MapRes = (f32)m_shadow_map_texture_size;
|
cb->MapRes = (f32)m_shadow_map_texture_size;
|
||||||
cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
|
cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
|
||||||
|
@ -281,12 +279,9 @@ void ShadowRenderer::updateSMTextures()
|
||||||
cb->PerspectiveBiasZ = getPerspectiveBiasZ();
|
cb->PerspectiveBiasZ = getPerspectiveBiasZ();
|
||||||
cb->CameraPos = light.getFuturePlayerPos();
|
cb->CameraPos = light.getFuturePlayerPos();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set the Render Target
|
// Note that force_update means we're drawing everything one go.
|
||||||
// right now we can only render in usual RTT, not
|
|
||||||
// Depth texture is available in irrlicth maybe we
|
|
||||||
// should put some gl* fn here
|
|
||||||
|
|
||||||
|
|
||||||
if (m_current_frame < m_map_shadow_update_frames || m_force_update_shadow_map) {
|
if (m_current_frame < m_map_shadow_update_frames || m_force_update_shadow_map) {
|
||||||
m_driver->setRenderTarget(shadowMapTargetTexture, reset_sm_texture, true,
|
m_driver->setRenderTarget(shadowMapTargetTexture, reset_sm_texture, true,
|
||||||
|
|
|
@ -28,7 +28,8 @@ struct NodeToApply
|
||||||
E_SHADOW_MODE m = E_SHADOW_MODE::ESM_BOTH) :
|
E_SHADOW_MODE m = E_SHADOW_MODE::ESM_BOTH) :
|
||||||
node(n),
|
node(n),
|
||||||
shadowMode(m){};
|
shadowMode(m){};
|
||||||
bool operator<(const NodeToApply &other) const { return node < other.node; };
|
|
||||||
|
bool operator==(scene::ISceneNode *n) const { return node == n; }
|
||||||
|
|
||||||
scene::ISceneNode *node;
|
scene::ISceneNode *node;
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ public:
|
||||||
void removeNodeFromShadowList(scene::ISceneNode *node);
|
void removeNodeFromShadowList(scene::ISceneNode *node);
|
||||||
|
|
||||||
void update(video::ITexture *outputTarget = nullptr);
|
void update(video::ITexture *outputTarget = nullptr);
|
||||||
|
/// Force shadow map to be re-drawn in one go next frame
|
||||||
void setForceUpdateShadowMap() { m_force_update_shadow_map = true; }
|
void setForceUpdateShadowMap() { m_force_update_shadow_map = true; }
|
||||||
void drawDebug();
|
void drawDebug();
|
||||||
|
|
||||||
|
|
|
@ -4,41 +4,10 @@
|
||||||
|
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
|
||||||
// Sets everything else except the texture in the material
|
void TileLayer::applyMaterialOptions(video::SMaterial &material, int layer) const
|
||||||
void TileLayer::applyMaterialOptions(video::SMaterial &material) const
|
|
||||||
{
|
{
|
||||||
switch (material_type) {
|
material.setTexture(0, texture);
|
||||||
case TILE_MATERIAL_OPAQUE:
|
|
||||||
case TILE_MATERIAL_LIQUID_OPAQUE:
|
|
||||||
case TILE_MATERIAL_WAVING_LIQUID_OPAQUE:
|
|
||||||
material.MaterialType = video::EMT_SOLID;
|
|
||||||
break;
|
|
||||||
case TILE_MATERIAL_BASIC:
|
|
||||||
case TILE_MATERIAL_WAVING_LEAVES:
|
|
||||||
case TILE_MATERIAL_WAVING_PLANTS:
|
|
||||||
case TILE_MATERIAL_WAVING_LIQUID_BASIC:
|
|
||||||
material.MaterialTypeParam = 0.5;
|
|
||||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
|
||||||
break;
|
|
||||||
case TILE_MATERIAL_ALPHA:
|
|
||||||
case TILE_MATERIAL_LIQUID_TRANSPARENT:
|
|
||||||
case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
|
|
||||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0;
|
|
||||||
if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) {
|
|
||||||
material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
|
|
||||||
}
|
|
||||||
if (!(material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL)) {
|
|
||||||
material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileLayer::applyMaterialOptionsWithShaders(video::SMaterial &material) const
|
|
||||||
{
|
|
||||||
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0;
|
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) != 0;
|
||||||
if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) {
|
if (!(material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)) {
|
||||||
material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
|
material.TextureLayers[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
|
||||||
|
@ -48,4 +17,15 @@ void TileLayer::applyMaterialOptionsWithShaders(video::SMaterial &material) cons
|
||||||
material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
material.TextureLayers[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
||||||
material.TextureLayers[1].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
material.TextureLayers[1].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The second layer is for overlays, but uses the same vertex positions
|
||||||
|
* as the first, which easily leads to Z-fighting.
|
||||||
|
* To fix this we can offset the polygons in the direction of the camera.
|
||||||
|
* This only affects the depth buffer and leads to no visual gaps in geometry.
|
||||||
|
*/
|
||||||
|
if (layer == 1) {
|
||||||
|
material.PolygonOffsetSlopeScale = -1;
|
||||||
|
material.PolygonOffsetDepthBias = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <SMaterial.h>
|
#include <SMaterial.h>
|
||||||
|
|
||||||
enum MaterialType{
|
enum MaterialType : u8 {
|
||||||
TILE_MATERIAL_BASIC,
|
TILE_MATERIAL_BASIC,
|
||||||
TILE_MATERIAL_ALPHA,
|
TILE_MATERIAL_ALPHA,
|
||||||
TILE_MATERIAL_LIQUID_TRANSPARENT,
|
TILE_MATERIAL_LIQUID_TRANSPARENT,
|
||||||
|
@ -84,9 +84,13 @@ struct TileLayer
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyMaterialOptions(video::SMaterial &material) const;
|
/**
|
||||||
|
* Set some material parameters accordingly.
|
||||||
void applyMaterialOptionsWithShaders(video::SMaterial &material) const;
|
* @note does not set `MaterialType`
|
||||||
|
* @param material material to mody
|
||||||
|
* @param layer index of this layer in the `TileSpec`
|
||||||
|
*/
|
||||||
|
void applyMaterialOptions(video::SMaterial &material, int layer) const;
|
||||||
|
|
||||||
/// @return is this layer semi-transparent?
|
/// @return is this layer semi-transparent?
|
||||||
bool isTransparent() const
|
bool isTransparent() const
|
||||||
|
@ -98,8 +102,9 @@ struct TileLayer
|
||||||
case TILE_MATERIAL_LIQUID_TRANSPARENT:
|
case TILE_MATERIAL_LIQUID_TRANSPARENT:
|
||||||
case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
|
case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ordered for size, please do not reorder
|
// Ordered for size, please do not reorder
|
||||||
|
@ -113,13 +118,14 @@ struct TileLayer
|
||||||
u16 animation_frame_length_ms = 0;
|
u16 animation_frame_length_ms = 0;
|
||||||
u16 animation_frame_count = 1;
|
u16 animation_frame_count = 1;
|
||||||
|
|
||||||
u8 material_type = TILE_MATERIAL_BASIC;
|
MaterialType material_type = TILE_MATERIAL_BASIC;
|
||||||
u8 material_flags =
|
u8 material_flags =
|
||||||
//0 // <- DEBUG, Use the one below
|
//0 // <- DEBUG, Use the one below
|
||||||
MATERIAL_FLAG_BACKFACE_CULLING |
|
MATERIAL_FLAG_BACKFACE_CULLING |
|
||||||
MATERIAL_FLAG_TILEABLE_HORIZONTAL|
|
MATERIAL_FLAG_TILEABLE_HORIZONTAL|
|
||||||
MATERIAL_FLAG_TILEABLE_VERTICAL;
|
MATERIAL_FLAG_TILEABLE_VERTICAL;
|
||||||
|
|
||||||
|
/// @note not owned by this struct
|
||||||
std::vector<FrameSpec> *frames = nullptr;
|
std::vector<FrameSpec> *frames = nullptr;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -154,8 +154,7 @@ public:
|
||||||
|
|
||||||
int maxdim = MYMAX(dim.Width, dim.Height);
|
int maxdim = MYMAX(dim.Width, dim.Height);
|
||||||
|
|
||||||
std::map<int, scene::IMesh*>::iterator
|
auto it = m_extrusion_meshes.lower_bound(maxdim);
|
||||||
it = m_extrusion_meshes.lower_bound(maxdim);
|
|
||||||
|
|
||||||
if (it == m_extrusion_meshes.end()) {
|
if (it == m_extrusion_meshes.end()) {
|
||||||
// no viable resolution found; use largest one
|
// no viable resolution found; use largest one
|
||||||
|
@ -204,7 +203,6 @@ WieldMeshSceneNode::WieldMeshSceneNode(scene::ISceneManager *mgr, s32 id):
|
||||||
// Create the child scene node
|
// Create the child scene node
|
||||||
scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube();
|
scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube();
|
||||||
m_meshnode = SceneManager->addMeshSceneNode(dummymesh, this, -1);
|
m_meshnode = SceneManager->addMeshSceneNode(dummymesh, this, -1);
|
||||||
m_meshnode->setReadOnlyMaterials(false);
|
|
||||||
m_meshnode->setVisible(false);
|
m_meshnode->setVisible(false);
|
||||||
dummymesh->drop(); // m_meshnode grabbed it
|
dummymesh->drop(); // m_meshnode grabbed it
|
||||||
|
|
||||||
|
@ -327,13 +325,8 @@ static scene::SMesh *createGenericNodeMesh(Client *client, MapNode n,
|
||||||
buf->append(&p.vertices[0], p.vertices.size(),
|
buf->append(&p.vertices[0], p.vertices.size(),
|
||||||
&p.indices[0], p.indices.size());
|
&p.indices[0], p.indices.size());
|
||||||
|
|
||||||
// Set up material
|
// note: material type is left unset, overriden later
|
||||||
buf->Material.setTexture(0, p.layer.texture);
|
p.layer.applyMaterialOptions(buf->Material, layer);
|
||||||
if (layer == 1) {
|
|
||||||
buf->Material.PolygonOffsetSlopeScale = -1;
|
|
||||||
buf->Material.PolygonOffsetDepthBias = -1;
|
|
||||||
}
|
|
||||||
p.layer.applyMaterialOptions(buf->Material);
|
|
||||||
|
|
||||||
mesh->addMeshBuffer(buf.get());
|
mesh->addMeshBuffer(buf.get());
|
||||||
colors->emplace_back(p.layer.has_color, p.layer.color);
|
colors->emplace_back(p.layer.has_color, p.layer.color);
|
||||||
|
@ -433,7 +426,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
|
||||||
u32 material_count = m_meshnode->getMaterialCount();
|
u32 material_count = m_meshnode->getMaterialCount();
|
||||||
for (u32 i = 0; i < material_count; ++i) {
|
for (u32 i = 0; i < material_count; ++i) {
|
||||||
video::SMaterial &material = m_meshnode->getMaterial(i);
|
video::SMaterial &material = m_meshnode->getMaterial(i);
|
||||||
// FIXME: overriding this breaks different alpha modes the mesh may have
|
// FIXME: we should take different alpha modes of the mesh into account here
|
||||||
material.MaterialType = m_material_type;
|
material.MaterialType = m_material_type;
|
||||||
material.MaterialTypeParam = 0.5f;
|
material.MaterialTypeParam = 0.5f;
|
||||||
material.forEachTexture([this] (auto &tex) {
|
material.forEachTexture([this] (auto &tex) {
|
||||||
|
|
|
@ -72,6 +72,14 @@ inline v3f truncate(const v3f vec, const f32 factor)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline v3f rangelimv(const v3f vec, const f32 low, const f32 high)
|
||||||
|
{
|
||||||
|
return v3f(
|
||||||
|
rangelim(vec.X, low, high),
|
||||||
|
rangelim(vec.Y, low, high),
|
||||||
|
rangelim(vec.Z, low, high)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function:
|
// Helper function:
|
||||||
|
@ -101,6 +109,8 @@ CollisionAxis axisAlignedCollision(
|
||||||
|
|
||||||
if (speed.Y) {
|
if (speed.Y) {
|
||||||
distance = relbox.MaxEdge.Y - relbox.MinEdge.Y;
|
distance = relbox.MaxEdge.Y - relbox.MinEdge.Y;
|
||||||
|
// FIXME: The dtime calculation is inaccurate without acceleration information.
|
||||||
|
// Exact formula: `dtime = (-vel ± sqrt(vel² + 2 * acc * distance)) / acc`
|
||||||
*dtime = distance / std::abs(speed.Y);
|
*dtime = distance / std::abs(speed.Y);
|
||||||
time = std::max(*dtime, 0.0f);
|
time = std::max(*dtime, 0.0f);
|
||||||
|
|
||||||
|
@ -214,16 +224,50 @@ static bool add_area_node_boxes(const v3s16 min, const v3s16 max, IGameDef *game
|
||||||
thread_local std::vector<aabb3f> nodeboxes;
|
thread_local std::vector<aabb3f> nodeboxes;
|
||||||
Map *map = &env->getMap();
|
Map *map = &env->getMap();
|
||||||
|
|
||||||
|
const bool air_walkable = nodedef->get(CONTENT_AIR).walkable;
|
||||||
|
|
||||||
|
v3s16 last_bp(S16_MAX);
|
||||||
|
MapBlock *last_block = nullptr;
|
||||||
|
|
||||||
|
// Note: as the area used here is usually small, iterating entire blocks
|
||||||
|
// would actually be slower by factor of 10.
|
||||||
|
|
||||||
v3s16 p;
|
v3s16 p;
|
||||||
for (p.Z = min.Z; p.Z <= max.Z; p.Z++)
|
for (p.Z = min.Z; p.Z <= max.Z; p.Z++)
|
||||||
for (p.Y = min.Y; p.Y <= max.Y; p.Y++)
|
for (p.Y = min.Y; p.Y <= max.Y; p.Y++)
|
||||||
for (p.X = min.X; p.X <= max.X; p.X++) {
|
for (p.X = min.X; p.X <= max.X; p.X++) {
|
||||||
bool is_position_valid;
|
v3s16 bp, relp;
|
||||||
MapNode n = map->getNode(p, &is_position_valid);
|
getNodeBlockPosWithOffset(p, bp, relp);
|
||||||
|
if (bp != last_bp) {
|
||||||
|
last_block = map->getBlockNoCreateNoEx(bp);
|
||||||
|
last_bp = bp;
|
||||||
|
}
|
||||||
|
MapBlock *const block = last_block;
|
||||||
|
|
||||||
if (is_position_valid && n.getContent() != CONTENT_IGNORE) {
|
if (!block) {
|
||||||
// Object collides into walkable nodes
|
// Since we iterate with node precision we can only safely skip
|
||||||
|
// ahead in the "innermost" axis of the MapBlock (X).
|
||||||
|
// This still worth it as it reduces the number of nodes to look at
|
||||||
|
// and entries in `cinfo`.
|
||||||
|
v3s16 rowend(bp.X * MAP_BLOCKSIZE + MAP_BLOCKSIZE - 1, p.Y, p.Z);
|
||||||
|
aabb3f box = getNodeBox(p, BS);
|
||||||
|
box.addInternalBox(getNodeBox(rowend, BS));
|
||||||
|
// Collide with unloaded block
|
||||||
|
cinfo.emplace_back(true, 0, p, box);
|
||||||
|
p.X = rowend.X;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!air_walkable && block->isAir()) {
|
||||||
|
// Skip ahead if air, like above
|
||||||
|
any_position_valid = true;
|
||||||
|
p.X = bp.X * MAP_BLOCKSIZE + MAP_BLOCKSIZE - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MapNode n = block->getNodeNoCheck(relp);
|
||||||
|
|
||||||
|
if (n.getContent() != CONTENT_IGNORE) {
|
||||||
any_position_valid = true;
|
any_position_valid = true;
|
||||||
const ContentFeatures &f = nodedef->get(n);
|
const ContentFeatures &f = nodedef->get(n);
|
||||||
|
|
||||||
|
@ -238,7 +282,6 @@ static bool add_area_node_boxes(const v3s16 min, const v3s16 max, IGameDef *game
|
||||||
nodeboxes.clear();
|
nodeboxes.clear();
|
||||||
n.getCollisionBoxes(nodedef, &nodeboxes, neighbors);
|
n.getCollisionBoxes(nodedef, &nodeboxes, neighbors);
|
||||||
|
|
||||||
// Calculate float position only once
|
|
||||||
v3f posf = intToFloat(p, BS);
|
v3f posf = intToFloat(p, BS);
|
||||||
for (auto box : nodeboxes) {
|
for (auto box : nodeboxes) {
|
||||||
box.MinEdge += posf;
|
box.MinEdge += posf;
|
||||||
|
@ -246,12 +289,12 @@ static bool add_area_node_boxes(const v3s16 min, const v3s16 max, IGameDef *game
|
||||||
cinfo.emplace_back(false, n_bouncy_value, p, box);
|
cinfo.emplace_back(false, n_bouncy_value, p, box);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Collide with unloaded nodes (position invalid) and loaded
|
// Collide with loaded CONTENT_IGNORE nodes
|
||||||
// CONTENT_IGNORE nodes (position valid)
|
|
||||||
aabb3f box = getNodeBox(p, BS);
|
aabb3f box = getNodeBox(p, BS);
|
||||||
cinfo.emplace_back(true, 0, p, box);
|
cinfo.emplace_back(true, 0, p, box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return any_position_valid;
|
return any_position_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +378,10 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
|
|
||||||
collisionMoveResult result;
|
collisionMoveResult result;
|
||||||
|
|
||||||
|
// Assume no collisions when no velocity and no acceleration
|
||||||
|
if (*speed_f == v3f() && accel_f == v3f())
|
||||||
|
return result;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate new velocity
|
Calculate new velocity
|
||||||
*/
|
*/
|
||||||
|
@ -350,30 +397,19 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
time_notification_done = false;
|
time_notification_done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
v3f dpos_f = (*speed_f + accel_f * 0.5f * dtime) * dtime;
|
// Average speed
|
||||||
v3f newpos_f = *pos_f + dpos_f;
|
v3f aspeed_f = *speed_f + accel_f * 0.5f * dtime;
|
||||||
*speed_f += accel_f * dtime;
|
|
||||||
|
|
||||||
// If the object is static, there are no collisions
|
|
||||||
if (dpos_f == v3f())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// Limit speed for avoiding hangs
|
// Limit speed for avoiding hangs
|
||||||
speed_f->Y = rangelim(speed_f->Y, -5000, 5000);
|
aspeed_f = truncate(rangelimv(aspeed_f, -5000.0f, 5000.0f), 10000.0f);
|
||||||
speed_f->X = rangelim(speed_f->X, -5000, 5000);
|
|
||||||
speed_f->Z = rangelim(speed_f->Z, -5000, 5000);
|
|
||||||
|
|
||||||
*speed_f = truncate(*speed_f, 10000.0f);
|
// Collect node boxes in movement range
|
||||||
|
|
||||||
/*
|
|
||||||
Collect node boxes in movement range
|
|
||||||
*/
|
|
||||||
|
|
||||||
// cached allocation
|
// cached allocation
|
||||||
thread_local std::vector<NearbyCollisionInfo> cinfo;
|
thread_local std::vector<NearbyCollisionInfo> cinfo;
|
||||||
cinfo.clear();
|
cinfo.clear();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// Movement if no collisions
|
||||||
|
v3f newpos_f = *pos_f + aspeed_f * dtime;
|
||||||
v3f minpos_f(
|
v3f minpos_f(
|
||||||
MYMIN(pos_f->X, newpos_f.X),
|
MYMIN(pos_f->X, newpos_f.X),
|
||||||
MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5
|
MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5
|
||||||
|
@ -399,24 +435,14 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Collect object boxes in movement range
|
||||||
Collect object boxes in movement range
|
|
||||||
*/
|
|
||||||
if (collide_with_objects) {
|
if (collide_with_objects) {
|
||||||
add_object_boxes(env, box_0, dtime, *pos_f, *speed_f, self, cinfo);
|
add_object_boxes(env, box_0, dtime, *pos_f, aspeed_f, self, cinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Collision detection
|
||||||
Collision detection
|
|
||||||
*/
|
|
||||||
|
|
||||||
f32 d = 0.0f;
|
f32 d = 0.0f;
|
||||||
|
for (int loopcount = 0;; loopcount++) {
|
||||||
int loopcount = 0;
|
|
||||||
|
|
||||||
while(dtime > BS * 1e-10f) {
|
|
||||||
// Avoid infinite loop
|
|
||||||
loopcount++;
|
|
||||||
if (loopcount >= 100) {
|
if (loopcount >= 100) {
|
||||||
warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infinite loop" << std::endl;
|
warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infinite loop" << std::endl;
|
||||||
g_collision_problems_encountered = true;
|
g_collision_problems_encountered = true;
|
||||||
|
@ -431,9 +457,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
f32 nearest_dtime = dtime;
|
f32 nearest_dtime = dtime;
|
||||||
int nearest_boxindex = -1;
|
int nearest_boxindex = -1;
|
||||||
|
|
||||||
/*
|
// Go through every nodebox, find nearest collision
|
||||||
Go through every nodebox, find nearest collision
|
|
||||||
*/
|
|
||||||
for (u32 boxindex = 0; boxindex < cinfo.size(); boxindex++) {
|
for (u32 boxindex = 0; boxindex < cinfo.size(); boxindex++) {
|
||||||
const NearbyCollisionInfo &box_info = cinfo[boxindex];
|
const NearbyCollisionInfo &box_info = cinfo[boxindex];
|
||||||
// Ignore if already stepped up this nodebox.
|
// Ignore if already stepped up this nodebox.
|
||||||
|
@ -443,8 +467,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
// Find nearest collision of the two boxes (raytracing-like)
|
// Find nearest collision of the two boxes (raytracing-like)
|
||||||
f32 dtime_tmp = nearest_dtime;
|
f32 dtime_tmp = nearest_dtime;
|
||||||
CollisionAxis collided = axisAlignedCollision(box_info.box,
|
CollisionAxis collided = axisAlignedCollision(box_info.box,
|
||||||
movingbox, *speed_f, &dtime_tmp);
|
movingbox, aspeed_f, &dtime_tmp);
|
||||||
|
|
||||||
if (collided == -1 || dtime_tmp >= nearest_dtime)
|
if (collided == -1 || dtime_tmp >= nearest_dtime)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -455,95 +478,119 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
|
|
||||||
if (nearest_collided == COLLISION_AXIS_NONE) {
|
if (nearest_collided == COLLISION_AXIS_NONE) {
|
||||||
// No collision with any collision box.
|
// No collision with any collision box.
|
||||||
*pos_f += truncate(*speed_f * dtime, 100.0f);
|
*pos_f += aspeed_f * dtime;
|
||||||
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
|
// Final speed:
|
||||||
} else {
|
*speed_f += accel_f * dtime;
|
||||||
// Otherwise, a collision occurred.
|
// Limit speed for avoiding hangs
|
||||||
NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex];
|
*speed_f = truncate(rangelimv(*speed_f, -5000.0f, 5000.0f), 10000.0f);
|
||||||
const aabb3f& cbox = nearest_info.box;
|
break;
|
||||||
|
}
|
||||||
|
// Otherwise, a collision occurred.
|
||||||
|
NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex];
|
||||||
|
const aabb3f& cbox = nearest_info.box;
|
||||||
|
|
||||||
//movingbox except moved to the horizontal position it would be after step up
|
//movingbox except moved to the horizontal position it would be after step up
|
||||||
|
bool step_up = false;
|
||||||
|
if (nearest_collided != COLLISION_AXIS_Y) {
|
||||||
aabb3f stepbox = movingbox;
|
aabb3f stepbox = movingbox;
|
||||||
stepbox.MinEdge.X += speed_f->X * dtime;
|
// Look slightly ahead for checking the height when stepping
|
||||||
stepbox.MinEdge.Z += speed_f->Z * dtime;
|
// to ensure we also check above the node we collided with
|
||||||
stepbox.MaxEdge.X += speed_f->X * dtime;
|
// otherwise, might allow glitches such as a stack of stairs
|
||||||
stepbox.MaxEdge.Z += speed_f->Z * dtime;
|
float extra_dtime = nearest_dtime + 0.1f * fabsf(dtime - nearest_dtime);
|
||||||
|
stepbox.MinEdge.X += aspeed_f.X * extra_dtime;
|
||||||
|
stepbox.MinEdge.Z += aspeed_f.Z * extra_dtime;
|
||||||
|
stepbox.MaxEdge.X += aspeed_f.X * extra_dtime;
|
||||||
|
stepbox.MaxEdge.Z += aspeed_f.Z * extra_dtime;
|
||||||
// Check for stairs.
|
// Check for stairs.
|
||||||
bool step_up = (nearest_collided != COLLISION_AXIS_Y) && // must not be Y direction
|
step_up = (movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
|
||||||
(movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
|
(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
|
||||||
(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
|
(!wouldCollideWithCeiling(cinfo, stepbox,
|
||||||
(!wouldCollideWithCeiling(cinfo, stepbox,
|
cbox.MaxEdge.Y - movingbox.MinEdge.Y,
|
||||||
cbox.MaxEdge.Y - movingbox.MinEdge.Y,
|
d));
|
||||||
d));
|
}
|
||||||
|
|
||||||
// Get bounce multiplier
|
// Get bounce multiplier
|
||||||
float bounce = -(float)nearest_info.bouncy / 100.0f;
|
float bounce = -(float)nearest_info.bouncy / 100.0f;
|
||||||
|
|
||||||
// Move to the point of collision and reduce dtime by nearest_dtime
|
// Move to the point of collision and reduce dtime by nearest_dtime
|
||||||
if (nearest_dtime < 0) {
|
if (nearest_dtime < 0) {
|
||||||
// Handle negative nearest_dtime
|
// Handle negative nearest_dtime
|
||||||
if (!step_up) {
|
// This largely means an "instant" collision, e.g., with the floor.
|
||||||
if (nearest_collided == COLLISION_AXIS_X)
|
// We use aspeed and nearest_dtime to be consistent with above and resolve this collision
|
||||||
pos_f->X += speed_f->X * nearest_dtime;
|
if (!step_up) {
|
||||||
if (nearest_collided == COLLISION_AXIS_Y)
|
if (nearest_collided == COLLISION_AXIS_X)
|
||||||
pos_f->Y += speed_f->Y * nearest_dtime;
|
pos_f->X += aspeed_f.X * nearest_dtime;
|
||||||
if (nearest_collided == COLLISION_AXIS_Z)
|
if (nearest_collided == COLLISION_AXIS_Y)
|
||||||
pos_f->Z += speed_f->Z * nearest_dtime;
|
pos_f->Y += aspeed_f.Y * nearest_dtime;
|
||||||
}
|
if (nearest_collided == COLLISION_AXIS_Z)
|
||||||
} else {
|
pos_f->Z += aspeed_f.Z * nearest_dtime;
|
||||||
*pos_f += truncate(*speed_f * nearest_dtime, 100.0f);
|
|
||||||
dtime -= nearest_dtime;
|
|
||||||
}
|
}
|
||||||
|
} else if (nearest_dtime > 0) {
|
||||||
|
// updated average speed for the sub-interval up to nearest_dtime
|
||||||
|
aspeed_f = *speed_f + accel_f * 0.5f * nearest_dtime;
|
||||||
|
*pos_f += aspeed_f * nearest_dtime;
|
||||||
|
// Speed at (approximated) collision:
|
||||||
|
*speed_f += accel_f * nearest_dtime;
|
||||||
|
// Limit speed for avoiding hangs
|
||||||
|
*speed_f = truncate(rangelimv(*speed_f, -5000.0f, 5000.0f), 10000.0f);
|
||||||
|
dtime -= nearest_dtime;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_collision = true;
|
v3f old_speed_f = *speed_f;
|
||||||
if (nearest_info.is_unloaded)
|
|
||||||
is_collision = false;
|
|
||||||
|
|
||||||
|
// Set the speed component that caused the collision to zero
|
||||||
|
if (step_up) {
|
||||||
|
// Special case: Handle stairs
|
||||||
|
nearest_info.is_step_up = true;
|
||||||
|
} else if (nearest_collided == COLLISION_AXIS_X) {
|
||||||
|
if (bounce < -1e-4 && fabsf(speed_f->X) > BS * 3) {
|
||||||
|
speed_f->X *= bounce;
|
||||||
|
} else {
|
||||||
|
speed_f->X = 0;
|
||||||
|
accel_f.X = 0; // avoid colliding in the next interations
|
||||||
|
}
|
||||||
|
} else if (nearest_collided == COLLISION_AXIS_Y) {
|
||||||
|
if (bounce < -1e-4 && fabsf(speed_f->Y) > BS * 3) {
|
||||||
|
speed_f->Y *= bounce;
|
||||||
|
} else {
|
||||||
|
if (speed_f->Y < 0.0f) {
|
||||||
|
// FIXME: This code is necessary until `axisAlignedCollision` takes acceleration
|
||||||
|
// into consideration for the time calculation. Otherwise, the colliding faces
|
||||||
|
// never line up, especially at high step (dtime) intervals.
|
||||||
|
result.touching_ground = true;
|
||||||
|
result.standing_on_object = nearest_info.isObject();
|
||||||
|
}
|
||||||
|
speed_f->Y = 0;
|
||||||
|
accel_f.Y = 0; // avoid colliding in the next interations
|
||||||
|
}
|
||||||
|
} else { /* nearest_collided == COLLISION_AXIS_Z */
|
||||||
|
if (bounce < -1e-4 && fabsf(speed_f->Z) > BS * 3) {
|
||||||
|
speed_f->Z *= bounce;
|
||||||
|
} else {
|
||||||
|
speed_f->Z = 0;
|
||||||
|
accel_f.Z = 0; // avoid colliding in the next interations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nearest_info.is_unloaded && !step_up) {
|
||||||
CollisionInfo info;
|
CollisionInfo info;
|
||||||
if (nearest_info.isObject())
|
info.axis = nearest_collided;
|
||||||
info.type = COLLISION_OBJECT;
|
info.type = nearest_info.isObject() ? COLLISION_OBJECT : COLLISION_NODE;
|
||||||
else
|
|
||||||
info.type = COLLISION_NODE;
|
|
||||||
|
|
||||||
info.node_p = nearest_info.position;
|
info.node_p = nearest_info.position;
|
||||||
info.object = nearest_info.obj;
|
info.object = nearest_info.obj;
|
||||||
info.new_pos = *pos_f;
|
info.new_pos = *pos_f;
|
||||||
info.old_speed = *speed_f;
|
info.old_speed = old_speed_f;
|
||||||
|
|
||||||
// Set the speed component that caused the collision to zero
|
|
||||||
if (step_up) {
|
|
||||||
// Special case: Handle stairs
|
|
||||||
nearest_info.is_step_up = true;
|
|
||||||
is_collision = false;
|
|
||||||
} else if (nearest_collided == COLLISION_AXIS_X) {
|
|
||||||
if (fabs(speed_f->X) > BS * 3)
|
|
||||||
speed_f->X *= bounce;
|
|
||||||
else
|
|
||||||
speed_f->X = 0;
|
|
||||||
result.collides = true;
|
|
||||||
} else if (nearest_collided == COLLISION_AXIS_Y) {
|
|
||||||
if(fabs(speed_f->Y) > BS * 3)
|
|
||||||
speed_f->Y *= bounce;
|
|
||||||
else
|
|
||||||
speed_f->Y = 0;
|
|
||||||
result.collides = true;
|
|
||||||
} else if (nearest_collided == COLLISION_AXIS_Z) {
|
|
||||||
if (fabs(speed_f->Z) > BS * 3)
|
|
||||||
speed_f->Z *= bounce;
|
|
||||||
else
|
|
||||||
speed_f->Z = 0;
|
|
||||||
result.collides = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.new_speed = *speed_f;
|
info.new_speed = *speed_f;
|
||||||
if (info.new_speed.getDistanceFrom(info.old_speed) < 0.1f * BS)
|
result.collisions.push_back(info);
|
||||||
is_collision = false;
|
|
||||||
|
|
||||||
if (is_collision) {
|
|
||||||
info.axis = nearest_collided;
|
|
||||||
result.collisions.push_back(std::move(info));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dtime < BS * 1e-10f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Speed for finding the next collision
|
||||||
|
aspeed_f = *speed_f + accel_f * 0.5f * dtime;
|
||||||
|
// Limit speed for avoiding hangs
|
||||||
|
aspeed_f = truncate(rangelimv(aspeed_f, -5000.0f, 5000.0f), 10000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -573,14 +620,15 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
||||||
box.MaxEdge += *pos_f;
|
box.MaxEdge += *pos_f;
|
||||||
}
|
}
|
||||||
if (std::fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.05f) {
|
if (std::fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.05f) {
|
||||||
|
// This is code is technically only required if `box_info.is_step_up == true`.
|
||||||
|
// However, players rely on this check/condition to climb stairs faster. See PR #10587.
|
||||||
result.touching_ground = true;
|
result.touching_ground = true;
|
||||||
|
result.standing_on_object = box_info.isObject();
|
||||||
if (box_info.isObject())
|
|
||||||
result.standing_on_object = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.collides = !result.collisions.empty();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,8 +140,6 @@ void ModConfiguration::addModsFromConfig(
|
||||||
*
|
*
|
||||||
* Alternative candidates for a modname are stored in `candidates`,
|
* Alternative candidates for a modname are stored in `candidates`,
|
||||||
* and used in an error message later.
|
* and used in an error message later.
|
||||||
*
|
|
||||||
* If not enabled, add `load_mod_modname = false` to world.mt
|
|
||||||
*/
|
*/
|
||||||
for (const auto &modPath : modPaths) {
|
for (const auto &modPath : modPaths) {
|
||||||
std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(modPath.second, modPath.first));
|
std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(modPath.second, modPath.first));
|
||||||
|
@ -154,7 +152,7 @@ void ModConfiguration::addModsFromConfig(
|
||||||
candidates[pair->first].emplace_back(mod.virtual_path);
|
candidates[pair->first].emplace_back(mod.virtual_path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conf.setBool("load_mod_" + mod.name, false);
|
conf.remove("load_mod_" + mod.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,13 @@ void Database_Dummy::loadBlock(const v3s16 &pos, std::string *block)
|
||||||
|
|
||||||
bool Database_Dummy::deleteBlock(const v3s16 &pos)
|
bool Database_Dummy::deleteBlock(const v3s16 &pos)
|
||||||
{
|
{
|
||||||
m_database.erase(getBlockAsInteger(pos));
|
return m_database.erase(getBlockAsInteger(pos)) > 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_Dummy::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
void Database_Dummy::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
||||||
{
|
{
|
||||||
dst.reserve(m_database.size());
|
dst.reserve(m_database.size());
|
||||||
for (std::map<s64, std::string>::const_iterator x = m_database.begin();
|
for (auto x = m_database.begin(); x != m_database.end(); ++x) {
|
||||||
x != m_database.end(); ++x) {
|
|
||||||
dst.push_back(getIntegerAsBlock(x->first));
|
dst.push_back(getIntegerAsBlock(x->first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,8 +234,7 @@ void PlayerDatabaseFiles::listPlayers(std::vector<std::string> &res)
|
||||||
{
|
{
|
||||||
std::vector<fs::DirListNode> files = fs::GetDirListing(m_savedir);
|
std::vector<fs::DirListNode> files = fs::GetDirListing(m_savedir);
|
||||||
// list files into players directory
|
// list files into players directory
|
||||||
for (std::vector<fs::DirListNode>::const_iterator it = files.begin(); it !=
|
for (auto it = files.begin(); it != files.end(); ++it) {
|
||||||
files.end(); ++it) {
|
|
||||||
// Ignore directories
|
// Ignore directories
|
||||||
if (it->dir)
|
if (it->dir)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -97,7 +97,7 @@ void Database_PostgreSQL::ping()
|
||||||
|
|
||||||
bool Database_PostgreSQL::initialized() const
|
bool Database_PostgreSQL::initialized() const
|
||||||
{
|
{
|
||||||
return (PQstatus(m_conn) == CONNECTION_OK);
|
return m_conn && PQstatus(m_conn) == CONNECTION_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
PGresult *Database_PostgreSQL::checkResults(PGresult *result, bool clear)
|
PGresult *Database_PostgreSQL::checkResults(PGresult *result, bool clear)
|
||||||
|
|
|
@ -9,20 +9,20 @@
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "util/basic_macros.h"
|
#include "util/basic_macros.h"
|
||||||
|
|
||||||
class Settings;
|
// Template class for PostgreSQL based data storage
|
||||||
|
class Database_PostgreSQL : public Database
|
||||||
class Database_PostgreSQL: public Database
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Database_PostgreSQL(const std::string &connect_string, const char *type);
|
Database_PostgreSQL(const std::string &connect_string, const char *type);
|
||||||
~Database_PostgreSQL();
|
~Database_PostgreSQL();
|
||||||
|
|
||||||
void beginSave();
|
void beginSave() override;
|
||||||
void endSave();
|
void endSave() override;
|
||||||
void rollback();
|
void rollback();
|
||||||
|
|
||||||
bool initialized() const;
|
bool initialized() const override;
|
||||||
|
|
||||||
|
void verifyDatabase() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Conversion helpers
|
// Conversion helpers
|
||||||
|
@ -73,7 +73,6 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void createTableIfNotExists(const std::string &table_name, const std::string &definition);
|
void createTableIfNotExists(const std::string &table_name, const std::string &definition);
|
||||||
void verifyDatabase();
|
|
||||||
|
|
||||||
// Database initialization
|
// Database initialization
|
||||||
void connectToDatabase();
|
void connectToDatabase();
|
||||||
|
@ -99,6 +98,12 @@ private:
|
||||||
int m_pgversion = 0;
|
int m_pgversion = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Not sure why why we have to do this. can't C++ figure it out on its own?
|
||||||
|
#define PARENT_CLASS_FUNCS \
|
||||||
|
void beginSave() { Database_PostgreSQL::beginSave(); } \
|
||||||
|
void endSave() { Database_PostgreSQL::endSave(); } \
|
||||||
|
void verifyDatabase() { Database_PostgreSQL::verifyDatabase(); }
|
||||||
|
|
||||||
class MapDatabasePostgreSQL : private Database_PostgreSQL, public MapDatabase
|
class MapDatabasePostgreSQL : private Database_PostgreSQL, public MapDatabase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -110,8 +115,7 @@ public:
|
||||||
bool deleteBlock(const v3s16 &pos);
|
bool deleteBlock(const v3s16 &pos);
|
||||||
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
||||||
|
|
||||||
void beginSave() { Database_PostgreSQL::beginSave(); }
|
PARENT_CLASS_FUNCS
|
||||||
void endSave() { Database_PostgreSQL::endSave(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
|
@ -129,6 +133,8 @@ public:
|
||||||
bool removePlayer(const std::string &name);
|
bool removePlayer(const std::string &name);
|
||||||
void listPlayers(std::vector<std::string> &res);
|
void listPlayers(std::vector<std::string> &res);
|
||||||
|
|
||||||
|
PARENT_CLASS_FUNCS
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
virtual void initStatements();
|
virtual void initStatements();
|
||||||
|
@ -143,8 +149,6 @@ public:
|
||||||
AuthDatabasePostgreSQL(const std::string &connect_string);
|
AuthDatabasePostgreSQL(const std::string &connect_string);
|
||||||
virtual ~AuthDatabasePostgreSQL() = default;
|
virtual ~AuthDatabasePostgreSQL() = default;
|
||||||
|
|
||||||
virtual void verifyDatabase() { Database_PostgreSQL::verifyDatabase(); }
|
|
||||||
|
|
||||||
virtual bool getAuth(const std::string &name, AuthEntry &res);
|
virtual bool getAuth(const std::string &name, AuthEntry &res);
|
||||||
virtual bool saveAuth(const AuthEntry &authEntry);
|
virtual bool saveAuth(const AuthEntry &authEntry);
|
||||||
virtual bool createAuth(AuthEntry &authEntry);
|
virtual bool createAuth(AuthEntry &authEntry);
|
||||||
|
@ -152,6 +156,8 @@ public:
|
||||||
virtual void listNames(std::vector<std::string> &res);
|
virtual void listNames(std::vector<std::string> &res);
|
||||||
virtual void reload();
|
virtual void reload();
|
||||||
|
|
||||||
|
PARENT_CLASS_FUNCS
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
virtual void initStatements();
|
virtual void initStatements();
|
||||||
|
@ -176,10 +182,11 @@ public:
|
||||||
bool removeModEntries(const std::string &modname);
|
bool removeModEntries(const std::string &modname);
|
||||||
void listMods(std::vector<std::string> *res);
|
void listMods(std::vector<std::string> *res);
|
||||||
|
|
||||||
void beginSave() { Database_PostgreSQL::beginSave(); }
|
PARENT_CLASS_FUNCS
|
||||||
void endSave() { Database_PostgreSQL::endSave(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
virtual void initStatements();
|
virtual void initStatements();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef PARENT_CLASS_FUNCS
|
||||||
|
|
|
@ -2,14 +2,6 @@
|
||||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
/*
|
|
||||||
SQLite format specification:
|
|
||||||
blocks:
|
|
||||||
(PK) INT id
|
|
||||||
BLOB data
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "database-sqlite3.h"
|
#include "database-sqlite3.h"
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
@ -26,23 +18,19 @@ SQLite format specification:
|
||||||
|
|
||||||
// When to print messages when the database is being held locked by another process
|
// When to print messages when the database is being held locked by another process
|
||||||
// Note: I've seen occasional delays of over 250ms while running minetestmapper.
|
// Note: I've seen occasional delays of over 250ms while running minetestmapper.
|
||||||
#define BUSY_INFO_TRESHOLD 100 // Print first informational message after 100ms.
|
enum {
|
||||||
#define BUSY_WARNING_TRESHOLD 250 // Print warning message after 250ms. Lag is increased.
|
BUSY_INFO_TRESHOLD = 100, // Print first informational message.
|
||||||
#define BUSY_ERROR_TRESHOLD 1000 // Print error message after 1000ms. Significant lag.
|
BUSY_WARNING_TRESHOLD = 250, // Print warning message. Significant lag.
|
||||||
#define BUSY_FATAL_TRESHOLD 3000 // Allow SQLITE_BUSY to be returned, which will cause a minetest crash.
|
BUSY_FATAL_TRESHOLD = 3000, // Allow SQLITE_BUSY to be returned back to the caller.
|
||||||
#define BUSY_ERROR_INTERVAL 10000 // Safety net: report again every 10 seconds
|
BUSY_ERROR_INTERVAL = 10000, // Safety net: report again every 10 seconds
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SQLRES(s, r, m) sqlite3_vrfy(s, m, r);
|
||||||
#define SQLRES(s, r, m) \
|
|
||||||
if ((s) != (r)) { \
|
|
||||||
throw DatabaseException(std::string(m) + ": " +\
|
|
||||||
sqlite3_errmsg(m_database)); \
|
|
||||||
}
|
|
||||||
#define SQLOK(s, m) SQLRES(s, SQLITE_OK, m)
|
#define SQLOK(s, m) SQLRES(s, SQLITE_OK, m)
|
||||||
|
|
||||||
#define PREPARE_STATEMENT(name, query) \
|
#define PREPARE_STATEMENT(name, query) \
|
||||||
SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL),\
|
SQLOK(sqlite3_prepare_v2(m_database, query, -1, &m_stmt_##name, NULL), \
|
||||||
"Failed to prepare query '" query "'")
|
std::string("Failed to prepare query \"").append(query).append("\""))
|
||||||
|
|
||||||
#define SQLOK_ERRSTREAM(s, m) \
|
#define SQLOK_ERRSTREAM(s, m) \
|
||||||
if ((s) != SQLITE_OK) { \
|
if ((s) != SQLITE_OK) { \
|
||||||
|
@ -50,52 +38,49 @@ SQLite format specification:
|
||||||
<< sqlite3_errmsg(m_database) << std::endl; \
|
<< sqlite3_errmsg(m_database) << std::endl; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FINALIZE_STATEMENT(statement) SQLOK_ERRSTREAM(sqlite3_finalize(statement), \
|
#define FINALIZE_STATEMENT(name) \
|
||||||
"Failed to finalize " #statement)
|
sqlite3_finalize(m_stmt_##name); /* if this fails who cares */ \
|
||||||
|
m_stmt_##name = nullptr;
|
||||||
|
|
||||||
int Database_SQLite3::busyHandler(void *data, int count)
|
int Database_SQLite3::busyHandler(void *data, int count)
|
||||||
{
|
{
|
||||||
s64 &first_time = reinterpret_cast<s64 *>(data)[0];
|
u64 &first_time = reinterpret_cast<u64*>(data)[0];
|
||||||
s64 &prev_time = reinterpret_cast<s64 *>(data)[1];
|
u64 &prev_time = reinterpret_cast<u64*>(data)[1];
|
||||||
s64 cur_time = porting::getTimeMs();
|
u64 cur_time = porting::getTimeMs();
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
first_time = cur_time;
|
first_time = cur_time;
|
||||||
prev_time = first_time;
|
prev_time = first_time;
|
||||||
} else {
|
|
||||||
while (cur_time < prev_time)
|
|
||||||
cur_time += s64(1)<<32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_time - first_time < BUSY_INFO_TRESHOLD) {
|
const auto total_diff = cur_time - first_time; // time since first call
|
||||||
; // do nothing
|
const auto this_diff = prev_time - first_time; // time since last call
|
||||||
} else if (cur_time - first_time >= BUSY_INFO_TRESHOLD &&
|
|
||||||
prev_time - first_time < BUSY_INFO_TRESHOLD) {
|
if (total_diff < BUSY_INFO_TRESHOLD) {
|
||||||
|
// do nothing
|
||||||
|
} else if (total_diff >= BUSY_INFO_TRESHOLD &&
|
||||||
|
this_diff < BUSY_INFO_TRESHOLD) {
|
||||||
infostream << "SQLite3 database has been locked for "
|
infostream << "SQLite3 database has been locked for "
|
||||||
<< cur_time - first_time << " ms." << std::endl;
|
<< total_diff << " ms." << std::endl;
|
||||||
} else if (cur_time - first_time >= BUSY_WARNING_TRESHOLD &&
|
} else if (total_diff >= BUSY_WARNING_TRESHOLD &&
|
||||||
prev_time - first_time < BUSY_WARNING_TRESHOLD) {
|
this_diff < BUSY_WARNING_TRESHOLD) {
|
||||||
warningstream << "SQLite3 database has been locked for "
|
warningstream << "SQLite3 database has been locked for "
|
||||||
<< cur_time - first_time << " ms." << std::endl;
|
<< total_diff << " ms; this causes lag." << std::endl;
|
||||||
} else if (cur_time - first_time >= BUSY_ERROR_TRESHOLD &&
|
} else if (total_diff >= BUSY_FATAL_TRESHOLD &&
|
||||||
prev_time - first_time < BUSY_ERROR_TRESHOLD) {
|
this_diff < BUSY_FATAL_TRESHOLD) {
|
||||||
errorstream << "SQLite3 database has been locked for "
|
errorstream << "SQLite3 database has been locked for "
|
||||||
<< cur_time - first_time << " ms; this causes lag." << std::endl;
|
<< total_diff << " ms - giving up!" << std::endl;
|
||||||
} else if (cur_time - first_time >= BUSY_FATAL_TRESHOLD &&
|
} else if (total_diff / BUSY_ERROR_INTERVAL !=
|
||||||
prev_time - first_time < BUSY_FATAL_TRESHOLD) {
|
this_diff / BUSY_ERROR_INTERVAL) {
|
||||||
errorstream << "SQLite3 database has been locked for "
|
|
||||||
<< cur_time - first_time << " ms - giving up!" << std::endl;
|
|
||||||
} else if ((cur_time - first_time) / BUSY_ERROR_INTERVAL !=
|
|
||||||
(prev_time - first_time) / BUSY_ERROR_INTERVAL) {
|
|
||||||
// Safety net: keep reporting every BUSY_ERROR_INTERVAL
|
// Safety net: keep reporting every BUSY_ERROR_INTERVAL
|
||||||
errorstream << "SQLite3 database has been locked for "
|
errorstream << "SQLite3 database has been locked for "
|
||||||
<< (cur_time - first_time) / 1000 << " seconds!" << std::endl;
|
<< total_diff / 1000 << " seconds!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_time = cur_time;
|
prev_time = cur_time;
|
||||||
|
|
||||||
// Make sqlite transaction fail if delay exceeds BUSY_FATAL_TRESHOLD
|
// Make sqlite transaction fail if delay exceeds BUSY_FATAL_TRESHOLD
|
||||||
return cur_time - first_time < BUSY_FATAL_TRESHOLD;
|
return total_diff < BUSY_FATAL_TRESHOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,7 +115,7 @@ void Database_SQLite3::openDatabase()
|
||||||
// Open the database connection
|
// Open the database connection
|
||||||
|
|
||||||
if (!fs::CreateAllDirs(m_savedir)) {
|
if (!fs::CreateAllDirs(m_savedir)) {
|
||||||
infostream << "Database_SQLite3: Failed to create directory \""
|
errorstream << "Database_SQLite3: Failed to create directory \""
|
||||||
<< m_savedir << "\"" << std::endl;
|
<< m_savedir << "\"" << std::endl;
|
||||||
throw FileNotGoodException("Failed to create database "
|
throw FileNotGoodException("Failed to create database "
|
||||||
"save directory");
|
"save directory");
|
||||||
|
@ -138,8 +123,11 @@ void Database_SQLite3::openDatabase()
|
||||||
|
|
||||||
bool needs_create = !fs::PathExists(dbp);
|
bool needs_create = !fs::PathExists(dbp);
|
||||||
|
|
||||||
SQLOK(sqlite3_open_v2(dbp.c_str(), &m_database,
|
auto flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
||||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL),
|
#ifdef SQLITE_OPEN_EXRESCODE
|
||||||
|
flags |= SQLITE_OPEN_EXRESCODE;
|
||||||
|
#endif
|
||||||
|
SQLOK(sqlite3_open_v2(dbp.c_str(), &m_database, flags, NULL),
|
||||||
std::string("Failed to open SQLite3 database file ") + dbp);
|
std::string("Failed to open SQLite3 database file ") + dbp);
|
||||||
|
|
||||||
SQLOK(sqlite3_busy_handler(m_database, Database_SQLite3::busyHandler,
|
SQLOK(sqlite3_busy_handler(m_database, Database_SQLite3::busyHandler,
|
||||||
|
@ -152,9 +140,9 @@ void Database_SQLite3::openDatabase()
|
||||||
std::string query_str = std::string("PRAGMA synchronous = ")
|
std::string query_str = std::string("PRAGMA synchronous = ")
|
||||||
+ itos(g_settings->getU16("sqlite_synchronous"));
|
+ itos(g_settings->getU16("sqlite_synchronous"));
|
||||||
SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL),
|
SQLOK(sqlite3_exec(m_database, query_str.c_str(), NULL, NULL, NULL),
|
||||||
"Failed to modify sqlite3 synchronous mode");
|
"Failed to set SQLite3 synchronous mode");
|
||||||
SQLOK(sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", NULL, NULL, NULL),
|
SQLOK(sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", NULL, NULL, NULL),
|
||||||
"Failed to enable sqlite3 foreign key support");
|
"Failed to enable SQLite3 foreign key support");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database_SQLite3::verifyDatabase()
|
void Database_SQLite3::verifyDatabase()
|
||||||
|
@ -171,10 +159,47 @@ void Database_SQLite3::verifyDatabase()
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Database_SQLite3::checkTable(const char *table)
|
||||||
|
{
|
||||||
|
assert(m_database);
|
||||||
|
|
||||||
|
// PRAGMA table_list would be cleaner here but it was only introduced in
|
||||||
|
// sqlite 3.37.0 (2021-11-27).
|
||||||
|
// So let's do this: https://stackoverflow.com/a/83195
|
||||||
|
|
||||||
|
sqlite3_stmt *m_stmt_tmp = nullptr;
|
||||||
|
PREPARE_STATEMENT(tmp, "SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?;");
|
||||||
|
str_to_sqlite(m_stmt_tmp, 1, table);
|
||||||
|
|
||||||
|
bool ret = (sqlite3_step(m_stmt_tmp) == SQLITE_ROW);
|
||||||
|
|
||||||
|
FINALIZE_STATEMENT(tmp)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database_SQLite3::checkColumn(const char *table, const char *column)
|
||||||
|
{
|
||||||
|
assert(m_database);
|
||||||
|
|
||||||
|
sqlite3_stmt *m_stmt_tmp = nullptr;
|
||||||
|
auto query_str = std::string("PRAGMA table_info(").append(table).append(");");
|
||||||
|
PREPARE_STATEMENT(tmp, query_str.c_str());
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
while (sqlite3_step(m_stmt_tmp) == SQLITE_ROW) {
|
||||||
|
ret |= sqlite_to_string_view(m_stmt_tmp, 1) == column;
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FINALIZE_STATEMENT(tmp)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
Database_SQLite3::~Database_SQLite3()
|
Database_SQLite3::~Database_SQLite3()
|
||||||
{
|
{
|
||||||
FINALIZE_STATEMENT(m_stmt_begin)
|
FINALIZE_STATEMENT(begin)
|
||||||
FINALIZE_STATEMENT(m_stmt_end)
|
FINALIZE_STATEMENT(end)
|
||||||
|
|
||||||
SQLOK_ERRSTREAM(sqlite3_close(m_database), "Failed to close database");
|
SQLOK_ERRSTREAM(sqlite3_close(m_database), "Failed to close database");
|
||||||
}
|
}
|
||||||
|
@ -191,40 +216,68 @@ MapDatabaseSQLite3::MapDatabaseSQLite3(const std::string &savedir):
|
||||||
|
|
||||||
MapDatabaseSQLite3::~MapDatabaseSQLite3()
|
MapDatabaseSQLite3::~MapDatabaseSQLite3()
|
||||||
{
|
{
|
||||||
FINALIZE_STATEMENT(m_stmt_read)
|
FINALIZE_STATEMENT(read)
|
||||||
FINALIZE_STATEMENT(m_stmt_write)
|
FINALIZE_STATEMENT(write)
|
||||||
FINALIZE_STATEMENT(m_stmt_list)
|
FINALIZE_STATEMENT(list)
|
||||||
FINALIZE_STATEMENT(m_stmt_delete)
|
FINALIZE_STATEMENT(delete)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MapDatabaseSQLite3::createDatabase()
|
void MapDatabaseSQLite3::createDatabase()
|
||||||
{
|
{
|
||||||
assert(m_database); // Pre-condition
|
assert(m_database);
|
||||||
|
|
||||||
SQLOK(sqlite3_exec(m_database,
|
// Note: before 5.12.0 the format was blocks(pos INT, data BLOB).
|
||||||
|
// This function only runs for newly created databases.
|
||||||
|
|
||||||
|
const char *schema =
|
||||||
"CREATE TABLE IF NOT EXISTS `blocks` (\n"
|
"CREATE TABLE IF NOT EXISTS `blocks` (\n"
|
||||||
" `pos` INT PRIMARY KEY,\n"
|
"`x` INTEGER,"
|
||||||
" `data` BLOB\n"
|
"`y` INTEGER,"
|
||||||
");\n",
|
"`z` INTEGER,"
|
||||||
NULL, NULL, NULL),
|
"`data` BLOB NOT NULL,"
|
||||||
|
// Declaring a primary key automatically creates an index and the
|
||||||
|
// order largely dictates which range operations can be sped up.
|
||||||
|
// see also: <https://www.sqlite.org/optoverview.html#skipscan>
|
||||||
|
// Putting XZ before Y matches our MapSector abstraction.
|
||||||
|
"PRIMARY KEY (`x`, `z`, `y`)"
|
||||||
|
");\n"
|
||||||
|
;
|
||||||
|
SQLOK(sqlite3_exec(m_database, schema, NULL, NULL, NULL),
|
||||||
"Failed to create database table");
|
"Failed to create database table");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapDatabaseSQLite3::initStatements()
|
void MapDatabaseSQLite3::initStatements()
|
||||||
{
|
{
|
||||||
PREPARE_STATEMENT(read, "SELECT `data` FROM `blocks` WHERE `pos` = ? LIMIT 1");
|
assert(checkTable("blocks"));
|
||||||
PREPARE_STATEMENT(write, "REPLACE INTO `blocks` (`pos`, `data`) VALUES (?, ?)");
|
m_new_format = checkColumn("blocks", "z");
|
||||||
PREPARE_STATEMENT(delete, "DELETE FROM `blocks` WHERE `pos` = ?");
|
infostream << "MapDatabaseSQLite3: split column format = "
|
||||||
PREPARE_STATEMENT(list, "SELECT `pos` FROM `blocks`");
|
<< (m_new_format ? "yes" : "no") << std::endl;
|
||||||
|
|
||||||
verbosestream << "ServerMap: SQLite3 database opened." << std::endl;
|
if (m_new_format) {
|
||||||
|
PREPARE_STATEMENT(read, "SELECT `data` FROM `blocks` WHERE `x` = ? AND `y` = ? AND `z` = ? LIMIT 1");
|
||||||
|
PREPARE_STATEMENT(write, "REPLACE INTO `blocks` (`x`, `y`, `z`, `data`) VALUES (?, ?, ?, ?)");
|
||||||
|
PREPARE_STATEMENT(delete, "DELETE FROM `blocks` WHERE `x` = ? AND `y` = ? AND `z` = ?");
|
||||||
|
PREPARE_STATEMENT(list, "SELECT `x`, `y`, `z` FROM `blocks`");
|
||||||
|
} else {
|
||||||
|
PREPARE_STATEMENT(read, "SELECT `data` FROM `blocks` WHERE `pos` = ? LIMIT 1");
|
||||||
|
PREPARE_STATEMENT(write, "REPLACE INTO `blocks` (`pos`, `data`) VALUES (?, ?)");
|
||||||
|
PREPARE_STATEMENT(delete, "DELETE FROM `blocks` WHERE `pos` = ?");
|
||||||
|
PREPARE_STATEMENT(list, "SELECT `pos` FROM `blocks`");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MapDatabaseSQLite3::bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index)
|
inline int MapDatabaseSQLite3::bindPos(sqlite3_stmt *stmt, v3s16 pos, int index)
|
||||||
{
|
{
|
||||||
SQLOK(sqlite3_bind_int64(stmt, index, getBlockAsInteger(pos)),
|
if (m_new_format) {
|
||||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
int_to_sqlite(stmt, index, pos.X);
|
||||||
|
int_to_sqlite(stmt, index + 1, pos.Y);
|
||||||
|
int_to_sqlite(stmt, index + 2, pos.Z);
|
||||||
|
return index + 3;
|
||||||
|
} else {
|
||||||
|
int64_to_sqlite(stmt, index, getBlockAsInteger(pos));
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapDatabaseSQLite3::deleteBlock(const v3s16 &pos)
|
bool MapDatabaseSQLite3::deleteBlock(const v3s16 &pos)
|
||||||
|
@ -237,7 +290,7 @@ bool MapDatabaseSQLite3::deleteBlock(const v3s16 &pos)
|
||||||
sqlite3_reset(m_stmt_delete);
|
sqlite3_reset(m_stmt_delete);
|
||||||
|
|
||||||
if (!good) {
|
if (!good) {
|
||||||
warningstream << "deleteBlock: Block failed to delete "
|
warningstream << "deleteBlock: Failed to delete block "
|
||||||
<< pos << ": " << sqlite3_errmsg(m_database) << std::endl;
|
<< pos << ": " << sqlite3_errmsg(m_database) << std::endl;
|
||||||
}
|
}
|
||||||
return good;
|
return good;
|
||||||
|
@ -247,9 +300,8 @@ bool MapDatabaseSQLite3::saveBlock(const v3s16 &pos, std::string_view data)
|
||||||
{
|
{
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
bindPos(m_stmt_write, pos);
|
int col = bindPos(m_stmt_write, pos);
|
||||||
SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL),
|
blob_to_sqlite(m_stmt_write, col, data);
|
||||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
|
||||||
|
|
||||||
SQLRES(sqlite3_step(m_stmt_write), SQLITE_DONE, "Failed to save block")
|
SQLRES(sqlite3_step(m_stmt_write), SQLITE_DONE, "Failed to save block")
|
||||||
sqlite3_reset(m_stmt_write);
|
sqlite3_reset(m_stmt_write);
|
||||||
|
@ -264,6 +316,7 @@ void MapDatabaseSQLite3::loadBlock(const v3s16 &pos, std::string *block)
|
||||||
bindPos(m_stmt_read, pos);
|
bindPos(m_stmt_read, pos);
|
||||||
|
|
||||||
if (sqlite3_step(m_stmt_read) != SQLITE_ROW) {
|
if (sqlite3_step(m_stmt_read) != SQLITE_ROW) {
|
||||||
|
block->clear();
|
||||||
sqlite3_reset(m_stmt_read);
|
sqlite3_reset(m_stmt_read);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +324,6 @@ void MapDatabaseSQLite3::loadBlock(const v3s16 &pos, std::string *block)
|
||||||
auto data = sqlite_to_blob(m_stmt_read, 0);
|
auto data = sqlite_to_blob(m_stmt_read, 0);
|
||||||
block->assign(data);
|
block->assign(data);
|
||||||
|
|
||||||
sqlite3_step(m_stmt_read);
|
|
||||||
// We should never get more than 1 row, so ok to reset
|
// We should never get more than 1 row, so ok to reset
|
||||||
sqlite3_reset(m_stmt_read);
|
sqlite3_reset(m_stmt_read);
|
||||||
}
|
}
|
||||||
|
@ -280,8 +332,17 @@ void MapDatabaseSQLite3::listAllLoadableBlocks(std::vector<v3s16> &dst)
|
||||||
{
|
{
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
while (sqlite3_step(m_stmt_list) == SQLITE_ROW)
|
v3s16 p;
|
||||||
dst.push_back(getIntegerAsBlock(sqlite3_column_int64(m_stmt_list, 0)));
|
while (sqlite3_step(m_stmt_list) == SQLITE_ROW) {
|
||||||
|
if (m_new_format) {
|
||||||
|
p.X = sqlite_to_int(m_stmt_list, 0);
|
||||||
|
p.Y = sqlite_to_int(m_stmt_list, 1);
|
||||||
|
p.Z = sqlite_to_int(m_stmt_list, 2);
|
||||||
|
} else {
|
||||||
|
p = getIntegerAsBlock(sqlite_to_int64(m_stmt_list, 0));
|
||||||
|
}
|
||||||
|
dst.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3_reset(m_stmt_list);
|
sqlite3_reset(m_stmt_list);
|
||||||
}
|
}
|
||||||
|
@ -298,35 +359,38 @@ PlayerDatabaseSQLite3::PlayerDatabaseSQLite3(const std::string &savedir):
|
||||||
|
|
||||||
PlayerDatabaseSQLite3::~PlayerDatabaseSQLite3()
|
PlayerDatabaseSQLite3::~PlayerDatabaseSQLite3()
|
||||||
{
|
{
|
||||||
FINALIZE_STATEMENT(m_stmt_player_load)
|
FINALIZE_STATEMENT(player_load)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_add)
|
FINALIZE_STATEMENT(player_add)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_update)
|
FINALIZE_STATEMENT(player_update)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_remove)
|
FINALIZE_STATEMENT(player_remove)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_list)
|
FINALIZE_STATEMENT(player_list)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_add_inventory)
|
FINALIZE_STATEMENT(player_add_inventory)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_add_inventory_items)
|
FINALIZE_STATEMENT(player_add_inventory_items)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_remove_inventory)
|
FINALIZE_STATEMENT(player_remove_inventory)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_remove_inventory_items)
|
FINALIZE_STATEMENT(player_remove_inventory_items)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_load_inventory)
|
FINALIZE_STATEMENT(player_load_inventory)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_load_inventory_items)
|
FINALIZE_STATEMENT(player_load_inventory_items)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_metadata_load)
|
FINALIZE_STATEMENT(player_metadata_load)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_metadata_add)
|
FINALIZE_STATEMENT(player_metadata_add)
|
||||||
FINALIZE_STATEMENT(m_stmt_player_metadata_remove)
|
FINALIZE_STATEMENT(player_metadata_remove)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void PlayerDatabaseSQLite3::createDatabase()
|
void PlayerDatabaseSQLite3::createDatabase()
|
||||||
{
|
{
|
||||||
assert(m_database); // Pre-condition
|
assert(m_database);
|
||||||
|
|
||||||
|
// When designing the schema remember that SQLite only has 5 basic data types
|
||||||
|
// and ignores length-limited types like "VARCHAR(32)".
|
||||||
|
|
||||||
SQLOK(sqlite3_exec(m_database,
|
SQLOK(sqlite3_exec(m_database,
|
||||||
"CREATE TABLE IF NOT EXISTS `player` ("
|
"CREATE TABLE IF NOT EXISTS `player` ("
|
||||||
"`name` VARCHAR(50) NOT NULL,"
|
"`name` TEXT NOT NULL,"
|
||||||
"`pitch` NUMERIC(11, 4) NOT NULL,"
|
"`pitch` NUMERIC NOT NULL,"
|
||||||
"`yaw` NUMERIC(11, 4) NOT NULL,"
|
"`yaw` NUMERIC NOT NULL,"
|
||||||
"`posX` NUMERIC(11, 4) NOT NULL,"
|
"`posX` NUMERIC NOT NULL,"
|
||||||
"`posY` NUMERIC(11, 4) NOT NULL,"
|
"`posY` NUMERIC NOT NULL,"
|
||||||
"`posZ` NUMERIC(11, 4) NOT NULL,"
|
"`posZ` NUMERIC NOT NULL,"
|
||||||
"`hp` INT NOT NULL,"
|
"`hp` INT NOT NULL,"
|
||||||
"`breath` INT NOT NULL,"
|
"`breath` INT NOT NULL,"
|
||||||
"`creation_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,"
|
"`creation_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,"
|
||||||
|
@ -337,9 +401,9 @@ void PlayerDatabaseSQLite3::createDatabase()
|
||||||
|
|
||||||
SQLOK(sqlite3_exec(m_database,
|
SQLOK(sqlite3_exec(m_database,
|
||||||
"CREATE TABLE IF NOT EXISTS `player_metadata` ("
|
"CREATE TABLE IF NOT EXISTS `player_metadata` ("
|
||||||
" `player` VARCHAR(50) NOT NULL,"
|
" `player` TEXT NOT NULL,"
|
||||||
" `metadata` VARCHAR(256) NOT NULL,"
|
" `metadata` TEXT NOT NULL,"
|
||||||
" `value` TEXT,"
|
" `value` TEXT NOT NULL,"
|
||||||
" PRIMARY KEY(`player`, `metadata`),"
|
" PRIMARY KEY(`player`, `metadata`),"
|
||||||
" FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );",
|
" FOREIGN KEY (`player`) REFERENCES player (`name`) ON DELETE CASCADE );",
|
||||||
NULL, NULL, NULL),
|
NULL, NULL, NULL),
|
||||||
|
@ -347,7 +411,7 @@ void PlayerDatabaseSQLite3::createDatabase()
|
||||||
|
|
||||||
SQLOK(sqlite3_exec(m_database,
|
SQLOK(sqlite3_exec(m_database,
|
||||||
"CREATE TABLE IF NOT EXISTS `player_inventories` ("
|
"CREATE TABLE IF NOT EXISTS `player_inventories` ("
|
||||||
" `player` VARCHAR(50) NOT NULL,"
|
" `player` TEXT NOT NULL,"
|
||||||
" `inv_id` INT NOT NULL,"
|
" `inv_id` INT NOT NULL,"
|
||||||
" `inv_width` INT NOT NULL,"
|
" `inv_width` INT NOT NULL,"
|
||||||
" `inv_name` TEXT NOT NULL DEFAULT '',"
|
" `inv_name` TEXT NOT NULL DEFAULT '',"
|
||||||
|
@ -359,7 +423,7 @@ void PlayerDatabaseSQLite3::createDatabase()
|
||||||
|
|
||||||
SQLOK(sqlite3_exec(m_database,
|
SQLOK(sqlite3_exec(m_database,
|
||||||
"CREATE TABLE `player_inventory_items` ("
|
"CREATE TABLE `player_inventory_items` ("
|
||||||
" `player` VARCHAR(50) NOT NULL,"
|
" `player` TEXT NOT NULL,"
|
||||||
" `inv_id` INT NOT NULL,"
|
" `inv_id` INT NOT NULL,"
|
||||||
" `slot_id` INT NOT NULL,"
|
" `slot_id` INT NOT NULL,"
|
||||||
" `item` TEXT NOT NULL DEFAULT '',"
|
" `item` TEXT NOT NULL DEFAULT '',"
|
||||||
|
@ -401,7 +465,6 @@ void PlayerDatabaseSQLite3::initStatements()
|
||||||
"(`player`, `metadata`, `value`) VALUES (?, ?, ?)")
|
"(`player`, `metadata`, `value`) VALUES (?, ?, ?)")
|
||||||
PREPARE_STATEMENT(player_metadata_remove, "DELETE FROM `player_metadata` "
|
PREPARE_STATEMENT(player_metadata_remove, "DELETE FROM `player_metadata` "
|
||||||
"WHERE `player` = ?")
|
"WHERE `player` = ?")
|
||||||
verbosestream << "ServerEnvironment: SQLite3 database opened (players)." << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerDatabaseSQLite3::playerDataExists(const std::string &name)
|
bool PlayerDatabaseSQLite3::playerDataExists(const std::string &name)
|
||||||
|
@ -588,27 +651,27 @@ AuthDatabaseSQLite3::AuthDatabaseSQLite3(const std::string &savedir) :
|
||||||
|
|
||||||
AuthDatabaseSQLite3::~AuthDatabaseSQLite3()
|
AuthDatabaseSQLite3::~AuthDatabaseSQLite3()
|
||||||
{
|
{
|
||||||
FINALIZE_STATEMENT(m_stmt_read)
|
FINALIZE_STATEMENT(read)
|
||||||
FINALIZE_STATEMENT(m_stmt_write)
|
FINALIZE_STATEMENT(write)
|
||||||
FINALIZE_STATEMENT(m_stmt_create)
|
FINALIZE_STATEMENT(create)
|
||||||
FINALIZE_STATEMENT(m_stmt_delete)
|
FINALIZE_STATEMENT(delete)
|
||||||
FINALIZE_STATEMENT(m_stmt_list_names)
|
FINALIZE_STATEMENT(list_names)
|
||||||
FINALIZE_STATEMENT(m_stmt_read_privs)
|
FINALIZE_STATEMENT(read_privs)
|
||||||
FINALIZE_STATEMENT(m_stmt_write_privs)
|
FINALIZE_STATEMENT(write_privs)
|
||||||
FINALIZE_STATEMENT(m_stmt_delete_privs)
|
FINALIZE_STATEMENT(delete_privs)
|
||||||
FINALIZE_STATEMENT(m_stmt_last_insert_rowid)
|
FINALIZE_STATEMENT(last_insert_rowid)
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthDatabaseSQLite3::createDatabase()
|
void AuthDatabaseSQLite3::createDatabase()
|
||||||
{
|
{
|
||||||
assert(m_database); // Pre-condition
|
assert(m_database);
|
||||||
|
|
||||||
SQLOK(sqlite3_exec(m_database,
|
SQLOK(sqlite3_exec(m_database,
|
||||||
"CREATE TABLE IF NOT EXISTS `auth` ("
|
"CREATE TABLE IF NOT EXISTS `auth` ("
|
||||||
"`id` INTEGER PRIMARY KEY AUTOINCREMENT,"
|
"`id` INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||||
"`name` VARCHAR(32) UNIQUE,"
|
"`name` TEXT UNIQUE NOT NULL,"
|
||||||
"`password` VARCHAR(512),"
|
"`password` TEXT NOT NULL,"
|
||||||
"`last_login` INTEGER"
|
"`last_login` INTEGER NOT NULL DEFAULT 0"
|
||||||
");",
|
");",
|
||||||
NULL, NULL, NULL),
|
NULL, NULL, NULL),
|
||||||
"Failed to create auth table");
|
"Failed to create auth table");
|
||||||
|
@ -616,7 +679,7 @@ void AuthDatabaseSQLite3::createDatabase()
|
||||||
SQLOK(sqlite3_exec(m_database,
|
SQLOK(sqlite3_exec(m_database,
|
||||||
"CREATE TABLE IF NOT EXISTS `user_privileges` ("
|
"CREATE TABLE IF NOT EXISTS `user_privileges` ("
|
||||||
"`id` INTEGER,"
|
"`id` INTEGER,"
|
||||||
"`privilege` VARCHAR(32),"
|
"`privilege` TEXT,"
|
||||||
"PRIMARY KEY (id, privilege)"
|
"PRIMARY KEY (id, privilege)"
|
||||||
"CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON DELETE CASCADE"
|
"CONSTRAINT fk_id FOREIGN KEY (id) REFERENCES auth (id) ON DELETE CASCADE"
|
||||||
");",
|
");",
|
||||||
|
@ -751,18 +814,18 @@ ModStorageDatabaseSQLite3::ModStorageDatabaseSQLite3(const std::string &savedir)
|
||||||
|
|
||||||
ModStorageDatabaseSQLite3::~ModStorageDatabaseSQLite3()
|
ModStorageDatabaseSQLite3::~ModStorageDatabaseSQLite3()
|
||||||
{
|
{
|
||||||
FINALIZE_STATEMENT(m_stmt_remove_all)
|
FINALIZE_STATEMENT(remove_all)
|
||||||
FINALIZE_STATEMENT(m_stmt_remove)
|
FINALIZE_STATEMENT(remove)
|
||||||
FINALIZE_STATEMENT(m_stmt_set)
|
FINALIZE_STATEMENT(set)
|
||||||
FINALIZE_STATEMENT(m_stmt_has)
|
FINALIZE_STATEMENT(has)
|
||||||
FINALIZE_STATEMENT(m_stmt_get)
|
FINALIZE_STATEMENT(get)
|
||||||
FINALIZE_STATEMENT(m_stmt_get_keys)
|
FINALIZE_STATEMENT(get_keys)
|
||||||
FINALIZE_STATEMENT(m_stmt_get_all)
|
FINALIZE_STATEMENT(get_all)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModStorageDatabaseSQLite3::createDatabase()
|
void ModStorageDatabaseSQLite3::createDatabase()
|
||||||
{
|
{
|
||||||
assert(m_database); // Pre-condition
|
assert(m_database);
|
||||||
|
|
||||||
SQLOK(sqlite3_exec(m_database,
|
SQLOK(sqlite3_exec(m_database,
|
||||||
"CREATE TABLE IF NOT EXISTS `entries` (\n"
|
"CREATE TABLE IF NOT EXISTS `entries` (\n"
|
||||||
|
@ -825,8 +888,7 @@ bool ModStorageDatabaseSQLite3::getModEntry(const std::string &modname,
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
str_to_sqlite(m_stmt_get, 1, modname);
|
str_to_sqlite(m_stmt_get, 1, modname);
|
||||||
SQLOK(sqlite3_bind_blob(m_stmt_get, 2, key.data(), key.size(), NULL),
|
blob_to_sqlite(m_stmt_get, 2, key);
|
||||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
|
||||||
bool found = sqlite3_step(m_stmt_get) == SQLITE_ROW;
|
bool found = sqlite3_step(m_stmt_get) == SQLITE_ROW;
|
||||||
if (found) {
|
if (found) {
|
||||||
auto sv = sqlite_to_blob(m_stmt_get, 0);
|
auto sv = sqlite_to_blob(m_stmt_get, 0);
|
||||||
|
@ -845,8 +907,7 @@ bool ModStorageDatabaseSQLite3::hasModEntry(const std::string &modname,
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
str_to_sqlite(m_stmt_has, 1, modname);
|
str_to_sqlite(m_stmt_has, 1, modname);
|
||||||
SQLOK(sqlite3_bind_blob(m_stmt_has, 2, key.data(), key.size(), NULL),
|
blob_to_sqlite(m_stmt_has, 2, key);
|
||||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
|
||||||
bool found = sqlite3_step(m_stmt_has) == SQLITE_ROW;
|
bool found = sqlite3_step(m_stmt_has) == SQLITE_ROW;
|
||||||
if (found)
|
if (found)
|
||||||
sqlite3_step(m_stmt_has);
|
sqlite3_step(m_stmt_has);
|
||||||
|
@ -862,10 +923,8 @@ bool ModStorageDatabaseSQLite3::setModEntry(const std::string &modname,
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
str_to_sqlite(m_stmt_set, 1, modname);
|
str_to_sqlite(m_stmt_set, 1, modname);
|
||||||
SQLOK(sqlite3_bind_blob(m_stmt_set, 2, key.data(), key.size(), NULL),
|
blob_to_sqlite(m_stmt_set, 2, key);
|
||||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
blob_to_sqlite(m_stmt_set, 3, value);
|
||||||
SQLOK(sqlite3_bind_blob(m_stmt_set, 3, value.data(), value.size(), NULL),
|
|
||||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
|
||||||
SQLRES(sqlite3_step(m_stmt_set), SQLITE_DONE, "Failed to set mod entry")
|
SQLRES(sqlite3_step(m_stmt_set), SQLITE_DONE, "Failed to set mod entry")
|
||||||
|
|
||||||
sqlite3_reset(m_stmt_set);
|
sqlite3_reset(m_stmt_set);
|
||||||
|
@ -879,8 +938,7 @@ bool ModStorageDatabaseSQLite3::removeModEntry(const std::string &modname,
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
str_to_sqlite(m_stmt_remove, 1, modname);
|
str_to_sqlite(m_stmt_remove, 1, modname);
|
||||||
SQLOK(sqlite3_bind_blob(m_stmt_remove, 2, key.data(), key.size(), NULL),
|
blob_to_sqlite(m_stmt_remove, 2, key);
|
||||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
|
||||||
sqlite3_vrfy(sqlite3_step(m_stmt_remove), SQLITE_DONE);
|
sqlite3_vrfy(sqlite3_step(m_stmt_remove), SQLITE_DONE);
|
||||||
int changes = sqlite3_changes(m_database);
|
int changes = sqlite3_changes(m_database);
|
||||||
|
|
||||||
|
@ -906,6 +964,7 @@ void ModStorageDatabaseSQLite3::listMods(std::vector<std::string> *res)
|
||||||
{
|
{
|
||||||
verifyDatabase();
|
verifyDatabase();
|
||||||
|
|
||||||
|
// FIXME: please don't do this. this should be sqlite3_step like all others.
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
int status = sqlite3_exec(m_database,
|
int status = sqlite3_exec(m_database,
|
||||||
"SELECT `modname` FROM `entries` GROUP BY `modname`;",
|
"SELECT `modname` FROM `entries` GROUP BY `modname`;",
|
||||||
|
|
|
@ -13,27 +13,41 @@ extern "C" {
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Template class for SQLite3 based data storage
|
||||||
class Database_SQLite3 : public Database
|
class Database_SQLite3 : public Database
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Database_SQLite3();
|
virtual ~Database_SQLite3();
|
||||||
|
|
||||||
void beginSave();
|
void beginSave() override;
|
||||||
void endSave();
|
void endSave() override;
|
||||||
|
|
||||||
|
bool initialized() const override { return m_initialized; }
|
||||||
|
|
||||||
|
/// @note not thread-safe
|
||||||
|
void verifyDatabase() override;
|
||||||
|
|
||||||
bool initialized() const { return m_initialized; }
|
|
||||||
protected:
|
protected:
|
||||||
Database_SQLite3(const std::string &savedir, const std::string &dbname);
|
Database_SQLite3(const std::string &savedir, const std::string &dbname);
|
||||||
|
|
||||||
// Open and initialize the database if needed
|
// Check if a specific table exists
|
||||||
void verifyDatabase();
|
bool checkTable(const char *table);
|
||||||
|
|
||||||
|
// Check if a table has a specific column
|
||||||
|
bool checkColumn(const char *table, const char *column);
|
||||||
|
|
||||||
|
/* Value conversion helpers */
|
||||||
|
|
||||||
// Convertors
|
|
||||||
inline void str_to_sqlite(sqlite3_stmt *s, int iCol, std::string_view str) const
|
inline void str_to_sqlite(sqlite3_stmt *s, int iCol, std::string_view str) const
|
||||||
{
|
{
|
||||||
sqlite3_vrfy(sqlite3_bind_text(s, iCol, str.data(), str.size(), NULL));
|
sqlite3_vrfy(sqlite3_bind_text(s, iCol, str.data(), str.size(), NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void blob_to_sqlite(sqlite3_stmt *s, int iCol, std::string_view str) const
|
||||||
|
{
|
||||||
|
sqlite3_vrfy(sqlite3_bind_blob(s, iCol, str.data(), str.size(), NULL));
|
||||||
|
}
|
||||||
|
|
||||||
inline void int_to_sqlite(sqlite3_stmt *s, int iCol, int val) const
|
inline void int_to_sqlite(sqlite3_stmt *s, int iCol, int val) const
|
||||||
{
|
{
|
||||||
sqlite3_vrfy(sqlite3_bind_int(s, iCol, val));
|
sqlite3_vrfy(sqlite3_bind_int(s, iCol, val));
|
||||||
|
@ -104,12 +118,14 @@ protected:
|
||||||
sqlite_to_float(s, iCol + 2));
|
sqlite_to_float(s, iCol + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query verifiers helpers
|
// Helper for verifying result of sqlite3_step() and such
|
||||||
inline void sqlite3_vrfy(int s, std::string_view m = "", int r = SQLITE_OK) const
|
inline void sqlite3_vrfy(int s, std::string_view m = "", int r = SQLITE_OK) const
|
||||||
{
|
{
|
||||||
if (s != r) {
|
if (s != r) {
|
||||||
std::string msg(m);
|
std::string msg(m);
|
||||||
msg.append(": ").append(sqlite3_errmsg(m_database));
|
if (!msg.empty())
|
||||||
|
msg.append(": ");
|
||||||
|
msg.append(sqlite3_errmsg(m_database));
|
||||||
throw DatabaseException(msg);
|
throw DatabaseException(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,28 +135,37 @@ protected:
|
||||||
sqlite3_vrfy(s, m, r);
|
sqlite3_vrfy(s, m, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the database structure
|
// Called after opening a fresh database file. Should create tables and indices.
|
||||||
virtual void createDatabase() = 0;
|
virtual void createDatabase() = 0;
|
||||||
|
|
||||||
|
// Should prepare the necessary statements.
|
||||||
virtual void initStatements() = 0;
|
virtual void initStatements() = 0;
|
||||||
|
|
||||||
sqlite3 *m_database = nullptr;
|
sqlite3 *m_database = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Open the database
|
// Open the database
|
||||||
void openDatabase();
|
void openDatabase();
|
||||||
|
|
||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
|
|
||||||
std::string m_savedir = "";
|
const std::string m_savedir;
|
||||||
std::string m_dbname = "";
|
const std::string m_dbname;
|
||||||
|
|
||||||
sqlite3_stmt *m_stmt_begin = nullptr;
|
sqlite3_stmt *m_stmt_begin = nullptr;
|
||||||
sqlite3_stmt *m_stmt_end = nullptr;
|
sqlite3_stmt *m_stmt_end = nullptr;
|
||||||
|
|
||||||
s64 m_busy_handler_data[2];
|
u64 m_busy_handler_data[2];
|
||||||
|
|
||||||
static int busyHandler(void *data, int count);
|
static int busyHandler(void *data, int count);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Not sure why why we have to do this. can't C++ figure it out on its own?
|
||||||
|
#define PARENT_CLASS_FUNCS \
|
||||||
|
void beginSave() { Database_SQLite3::beginSave(); } \
|
||||||
|
void endSave() { Database_SQLite3::endSave(); } \
|
||||||
|
void verifyDatabase() { Database_SQLite3::verifyDatabase(); }
|
||||||
|
|
||||||
class MapDatabaseSQLite3 : private Database_SQLite3, public MapDatabase
|
class MapDatabaseSQLite3 : private Database_SQLite3, public MapDatabase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -152,16 +177,19 @@ public:
|
||||||
bool deleteBlock(const v3s16 &pos);
|
bool deleteBlock(const v3s16 &pos);
|
||||||
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
||||||
|
|
||||||
void beginSave() { Database_SQLite3::beginSave(); }
|
PARENT_CLASS_FUNCS
|
||||||
void endSave() { Database_SQLite3::endSave(); }
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
virtual void initStatements();
|
virtual void initStatements();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void bindPos(sqlite3_stmt *stmt, const v3s16 &pos, int index = 1);
|
/// @brief Bind block position into statement at column index
|
||||||
|
/// @return index of next column after position
|
||||||
|
int bindPos(sqlite3_stmt *stmt, v3s16 pos, int index = 1);
|
||||||
|
|
||||||
|
bool m_new_format = false;
|
||||||
|
|
||||||
// Map
|
|
||||||
sqlite3_stmt *m_stmt_read = nullptr;
|
sqlite3_stmt *m_stmt_read = nullptr;
|
||||||
sqlite3_stmt *m_stmt_write = nullptr;
|
sqlite3_stmt *m_stmt_write = nullptr;
|
||||||
sqlite3_stmt *m_stmt_list = nullptr;
|
sqlite3_stmt *m_stmt_list = nullptr;
|
||||||
|
@ -179,6 +207,8 @@ public:
|
||||||
bool removePlayer(const std::string &name);
|
bool removePlayer(const std::string &name);
|
||||||
void listPlayers(std::vector<std::string> &res);
|
void listPlayers(std::vector<std::string> &res);
|
||||||
|
|
||||||
|
PARENT_CLASS_FUNCS
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
virtual void initStatements();
|
virtual void initStatements();
|
||||||
|
@ -216,6 +246,8 @@ public:
|
||||||
virtual void listNames(std::vector<std::string> &res);
|
virtual void listNames(std::vector<std::string> &res);
|
||||||
virtual void reload();
|
virtual void reload();
|
||||||
|
|
||||||
|
PARENT_CLASS_FUNCS
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
virtual void initStatements();
|
virtual void initStatements();
|
||||||
|
@ -251,8 +283,7 @@ public:
|
||||||
virtual bool removeModEntries(const std::string &modname);
|
virtual bool removeModEntries(const std::string &modname);
|
||||||
virtual void listMods(std::vector<std::string> *res);
|
virtual void listMods(std::vector<std::string> *res);
|
||||||
|
|
||||||
virtual void beginSave() { Database_SQLite3::beginSave(); }
|
PARENT_CLASS_FUNCS
|
||||||
virtual void endSave() { Database_SQLite3::endSave(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void createDatabase();
|
virtual void createDatabase();
|
||||||
|
@ -267,3 +298,5 @@ private:
|
||||||
sqlite3_stmt *m_stmt_remove = nullptr;
|
sqlite3_stmt *m_stmt_remove = nullptr;
|
||||||
sqlite3_stmt *m_stmt_remove_all = nullptr;
|
sqlite3_stmt *m_stmt_remove_all = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef PARENT_CLASS_FUNCS
|
||||||
|
|
|
@ -16,7 +16,12 @@ class Database
|
||||||
public:
|
public:
|
||||||
virtual void beginSave() = 0;
|
virtual void beginSave() = 0;
|
||||||
virtual void endSave() = 0;
|
virtual void endSave() = 0;
|
||||||
|
|
||||||
|
/// @return true if database connection is open
|
||||||
virtual bool initialized() const { return true; }
|
virtual bool initialized() const { return true; }
|
||||||
|
|
||||||
|
/// Open and initialize the database if needed
|
||||||
|
virtual void verifyDatabase() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class MapDatabase : public Database
|
class MapDatabase : public Database
|
||||||
|
|
|
@ -112,7 +112,7 @@ void set_default_settings()
|
||||||
settings->setDefault("screenshot_format", "png");
|
settings->setDefault("screenshot_format", "png");
|
||||||
settings->setDefault("screenshot_quality", "0");
|
settings->setDefault("screenshot_quality", "0");
|
||||||
settings->setDefault("client_unload_unused_data_timeout", "600");
|
settings->setDefault("client_unload_unused_data_timeout", "600");
|
||||||
settings->setDefault("client_mapblock_limit", "7500");
|
settings->setDefault("client_mapblock_limit", "7500"); // about 120 MB
|
||||||
settings->setDefault("enable_build_where_you_stand", "false");
|
settings->setDefault("enable_build_where_you_stand", "false");
|
||||||
settings->setDefault("curl_timeout", "20000");
|
settings->setDefault("curl_timeout", "20000");
|
||||||
settings->setDefault("curl_parallel_limit", "8");
|
settings->setDefault("curl_parallel_limit", "8");
|
||||||
|
@ -243,7 +243,7 @@ void set_default_settings()
|
||||||
settings->setDefault("tooltip_show_delay", "400");
|
settings->setDefault("tooltip_show_delay", "400");
|
||||||
settings->setDefault("tooltip_append_itemname", "false");
|
settings->setDefault("tooltip_append_itemname", "false");
|
||||||
settings->setDefault("fps_max", "60");
|
settings->setDefault("fps_max", "60");
|
||||||
settings->setDefault("fps_max_unfocused", "20");
|
settings->setDefault("fps_max_unfocused", "10");
|
||||||
settings->setDefault("viewing_range", "190");
|
settings->setDefault("viewing_range", "190");
|
||||||
settings->setDefault("client_mesh_chunk", "1");
|
settings->setDefault("client_mesh_chunk", "1");
|
||||||
settings->setDefault("screen_w", "1024");
|
settings->setDefault("screen_w", "1024");
|
||||||
|
@ -270,7 +270,6 @@ void set_default_settings()
|
||||||
settings->setDefault("camera_smoothing", "0.0");
|
settings->setDefault("camera_smoothing", "0.0");
|
||||||
settings->setDefault("cinematic_camera_smoothing", "0.7");
|
settings->setDefault("cinematic_camera_smoothing", "0.7");
|
||||||
settings->setDefault("view_bobbing_amount", "1.0");
|
settings->setDefault("view_bobbing_amount", "1.0");
|
||||||
settings->setDefault("fall_bobbing_amount", "0.03");
|
|
||||||
settings->setDefault("enable_3d_clouds", "true");
|
settings->setDefault("enable_3d_clouds", "true");
|
||||||
settings->setDefault("soft_clouds", "false");
|
settings->setDefault("soft_clouds", "false");
|
||||||
settings->setDefault("cloud_radius", "12");
|
settings->setDefault("cloud_radius", "12");
|
||||||
|
@ -422,7 +421,7 @@ void set_default_settings()
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
settings->setDefault("enable_ipv6", "true");
|
settings->setDefault("enable_ipv6", "true");
|
||||||
settings->setDefault("ipv6_server", "false");
|
settings->setDefault("ipv6_server", "true");
|
||||||
settings->setDefault("max_packets_per_iteration", "1024");
|
settings->setDefault("max_packets_per_iteration", "1024");
|
||||||
settings->setDefault("port", "30000");
|
settings->setDefault("port", "30000");
|
||||||
settings->setDefault("strict_protocol_version_checking", "false");
|
settings->setDefault("strict_protocol_version_checking", "false");
|
||||||
|
@ -547,6 +546,7 @@ void set_default_settings()
|
||||||
settings->setDefault("virtual_joystick_triggers_aux1", "false");
|
settings->setDefault("virtual_joystick_triggers_aux1", "false");
|
||||||
settings->setDefault("touch_punch_gesture", "short_tap");
|
settings->setDefault("touch_punch_gesture", "short_tap");
|
||||||
settings->setDefault("clickable_chat_weblinks", "true");
|
settings->setDefault("clickable_chat_weblinks", "true");
|
||||||
|
|
||||||
// Altered settings for Android
|
// Altered settings for Android
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
settings->setDefault("screen_w", "0");
|
settings->setDefault("screen_w", "0");
|
||||||
|
@ -558,9 +558,9 @@ void set_default_settings()
|
||||||
settings->setDefault("max_block_generate_distance", "5");
|
settings->setDefault("max_block_generate_distance", "5");
|
||||||
settings->setDefault("sqlite_synchronous", "1");
|
settings->setDefault("sqlite_synchronous", "1");
|
||||||
settings->setDefault("server_map_save_interval", "15");
|
settings->setDefault("server_map_save_interval", "15");
|
||||||
settings->setDefault("client_mapblock_limit", "1000");
|
settings->setDefault("client_mapblock_limit", "1500");
|
||||||
settings->setDefault("active_block_range", "2");
|
settings->setDefault("active_block_range", "2");
|
||||||
settings->setDefault("viewing_range", "50");
|
settings->setDefault("viewing_range", "70");
|
||||||
settings->setDefault("leaves_style", "simple");
|
settings->setDefault("leaves_style", "simple");
|
||||||
// Note: OpenGL ES 2.0 is not guaranteed to provide depth textures,
|
// Note: OpenGL ES 2.0 is not guaranteed to provide depth textures,
|
||||||
// which we would need for PP.
|
// which we would need for PP.
|
||||||
|
@ -568,6 +568,7 @@ void set_default_settings()
|
||||||
// still set these two settings in case someone wants to enable it
|
// still set these two settings in case someone wants to enable it
|
||||||
settings->setDefault("debanding", "false");
|
settings->setDefault("debanding", "false");
|
||||||
settings->setDefault("post_processing_texture_bits", "8");
|
settings->setDefault("post_processing_texture_bits", "8");
|
||||||
|
// We don't have working certificate verification...
|
||||||
settings->setDefault("curl_verify_cert", "false");
|
settings->setDefault("curl_verify_cert", "false");
|
||||||
|
|
||||||
// Apply settings according to screen size
|
// Apply settings according to screen size
|
||||||
|
|
|
@ -106,9 +106,9 @@ EmergeManager::EmergeManager(Server *server, MetricsBackend *mb)
|
||||||
m_qlimit_generate = nthreads + 1;
|
m_qlimit_generate = nthreads + 1;
|
||||||
|
|
||||||
// don't trust user input for something very important like this
|
// don't trust user input for something very important like this
|
||||||
m_qlimit_total = rangelim(m_qlimit_total, 1, 1000000);
|
m_qlimit_diskonly = rangelim(m_qlimit_diskonly, 2, 1000000);
|
||||||
m_qlimit_diskonly = rangelim(m_qlimit_diskonly, 1, 1000000);
|
|
||||||
m_qlimit_generate = rangelim(m_qlimit_generate, 1, 1000000);
|
m_qlimit_generate = rangelim(m_qlimit_generate, 1, 1000000);
|
||||||
|
m_qlimit_total = std::max(m_qlimit_diskonly, m_qlimit_generate);
|
||||||
|
|
||||||
for (s16 i = 0; i < nthreads; i++)
|
for (s16 i = 0; i < nthreads; i++)
|
||||||
m_threads.push_back(new EmergeThread(server, i));
|
m_threads.push_back(new EmergeThread(server, i));
|
||||||
|
@ -375,8 +375,7 @@ bool EmergeManager::pushBlockEmergeData(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::map<v3s16, BlockEmergeData>::iterator, bool> findres;
|
auto findres = m_blocks_enqueued.insert(std::make_pair(pos, BlockEmergeData()));
|
||||||
findres = m_blocks_enqueued.insert(std::make_pair(pos, BlockEmergeData()));
|
|
||||||
|
|
||||||
BlockEmergeData &bedata = findres.first->second;
|
BlockEmergeData &bedata = findres.first->second;
|
||||||
*entry_already_exists = !findres.second;
|
*entry_already_exists = !findres.second;
|
||||||
|
@ -707,6 +706,8 @@ void *EmergeThread::run()
|
||||||
{
|
{
|
||||||
ScopeProfiler sp(g_profiler, "EmergeThread: load block - async (sum)");
|
ScopeProfiler sp(g_profiler, "EmergeThread: load block - async (sum)");
|
||||||
MutexAutoLock dblock(m_db.mutex);
|
MutexAutoLock dblock(m_db.mutex);
|
||||||
|
// Note: this can throw an exception, but there isn't really
|
||||||
|
// a good, safe way to handle it.
|
||||||
m_db.loadBlock(pos, databuf);
|
m_db.loadBlock(pos, databuf);
|
||||||
}
|
}
|
||||||
// actually load it, then decide again
|
// actually load it, then decide again
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue