@ -29,3 +29,4 @@ AlignAfterOpenBracket: DontAlign
|
||||
ContinuationIndentWidth: 16
|
||||
ConstructorInitializerIndentWidth: 16
|
||||
BreakConstructorInitializers: AfterColon
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
|
4
.dockerignore
Normal file
@ -0,0 +1,4 @@
|
||||
./cmake-build-*
|
||||
./build/*
|
||||
./cache/*
|
||||
Dockerfile
|
4
.github/CONTRIBUTING.md
vendored
@ -70,7 +70,9 @@ Feature requests are welcome but take a moment to see if your idea follows the r
|
||||
|
||||
## Translations
|
||||
|
||||
Translations of Minetest are performed using Weblate. You can access the project page with a list of current languages [here](https://hosted.weblate.org/projects/minetest/minetest/).
|
||||
The core translations of Minetest are performed using Weblate. You can access the project page with a list of current languages [here](https://hosted.weblate.org/projects/minetest/minetest/).
|
||||
|
||||
Builtin (the component which contains things like server messages, chat command descriptions, privilege descriptions) is translated separately; it needs to be translated by editing a `.tr` text file. See [Translation](https://dev.minetest.net/Translation) for more information.
|
||||
|
||||
## Donations
|
||||
|
||||
|
19
.github/workflows/build.yml
vendored
@ -13,6 +13,8 @@ on:
|
||||
- 'util/buildbot/**'
|
||||
- 'util/ci/**'
|
||||
- '.github/workflows/**.yml'
|
||||
- 'Dockerfile'
|
||||
- '.dockerignore'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'lib/**.[ch]'
|
||||
@ -24,6 +26,8 @@ on:
|
||||
- 'util/buildbot/**'
|
||||
- 'util/ci/**'
|
||||
- '.github/workflows/**.yml'
|
||||
- 'Dockerfile'
|
||||
- '.dockerignore'
|
||||
|
||||
jobs:
|
||||
# This is our minor gcc compiler
|
||||
@ -76,7 +80,7 @@ jobs:
|
||||
- name: Install deps
|
||||
run: |
|
||||
source ./util/ci/common.sh
|
||||
install_linux_deps clang-3.9
|
||||
install_linux_deps clang-3.9 gdb
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -85,10 +89,14 @@ jobs:
|
||||
CC: clang-3.9
|
||||
CXX: clang++-3.9
|
||||
|
||||
- name: Test
|
||||
- name: Unittest
|
||||
run: |
|
||||
./bin/minetest --run-unittests
|
||||
|
||||
- name: Integration test
|
||||
run: |
|
||||
./util/test_multiplayer.sh
|
||||
|
||||
# This is the current clang version
|
||||
clang_9:
|
||||
runs-on: ubuntu-18.04
|
||||
@ -124,7 +132,7 @@ jobs:
|
||||
- name: Install deps
|
||||
run: |
|
||||
source ./util/ci/common.sh
|
||||
install_linux_deps clang-9
|
||||
install_linux_deps --old-irr clang-9
|
||||
|
||||
- name: Build prometheus-cpp
|
||||
run: |
|
||||
@ -212,7 +220,10 @@ jobs:
|
||||
|
||||
msvc:
|
||||
name: VS 2019 ${{ matrix.config.arch }}-${{ matrix.type }}
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2019
|
||||
#### Disabled due to Irrlicht switch
|
||||
if: false
|
||||
#### Disabled due to Irrlicht switch
|
||||
env:
|
||||
VCPKG_VERSION: 0bf3923f9fab4001c00f0f429682a0853b5749e0
|
||||
# 2020.11
|
||||
|
27
.github/workflows/cpp_lint.yml
vendored
@ -24,20 +24,21 @@ on:
|
||||
- '.github/workflows/**.yml'
|
||||
|
||||
jobs:
|
||||
clang_format:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install clang-format
|
||||
run: |
|
||||
sudo apt-get install clang-format-9 -qyy
|
||||
|
||||
- name: Run clang-format
|
||||
run: |
|
||||
source ./util/ci/lint.sh
|
||||
perform_lint
|
||||
env:
|
||||
CLANG_FORMAT: clang-format-9
|
||||
# clang_format:
|
||||
# runs-on: ubuntu-18.04
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Install clang-format
|
||||
# run: |
|
||||
# sudo apt-get install clang-format-9 -qyy
|
||||
#
|
||||
# - name: Run clang-format
|
||||
# run: |
|
||||
# source ./util/ci/clang-format.sh
|
||||
# check_format
|
||||
# env:
|
||||
# CLANG_FORMAT: clang-format-9
|
||||
|
||||
clang_tidy:
|
||||
runs-on: ubuntu-18.04
|
||||
|
3
.gitignore
vendored
@ -86,8 +86,7 @@ src/test_config.h
|
||||
src/cmake_config.h
|
||||
src/cmake_config_githash.h
|
||||
src/unittest/test_world/world.mt
|
||||
src/lua/build/
|
||||
locale/
|
||||
/locale/
|
||||
.directory
|
||||
*.cbp
|
||||
*.layout
|
||||
|
@ -9,16 +9,24 @@ stages:
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
IRRLICHT_TAG: "1.9.0mt1"
|
||||
MINETEST_GAME_REPO: "https://github.com/minetest/minetest_game.git"
|
||||
CONTAINER_IMAGE: registry.gitlab.com/$CI_PROJECT_PATH
|
||||
|
||||
.build_template:
|
||||
stage: build
|
||||
before_script:
|
||||
- apt-get update
|
||||
- apt-get -y install build-essential git cmake libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libleveldb-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
script:
|
||||
- git clone https://github.com/minetest/irrlicht -b $IRRLICHT_TAG
|
||||
- cd irrlicht
|
||||
- cmake . -DBUILD_SHARED_LIBS=OFF
|
||||
- make -j2
|
||||
- cd ..
|
||||
- mkdir cmakebuild
|
||||
- mkdir -p artifact/minetest/usr/
|
||||
- cd cmakebuild
|
||||
- cmake -DCMAKE_INSTALL_PREFIX=../artifact/minetest/usr/ -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE -DENABLE_SYSTEM_JSONCPP=TRUE -DBUILD_SERVER=TRUE ..
|
||||
- cmake -DIRRLICHT_LIBRARY=$PWD/../irrlicht/lib/Linux/libIrrlichtMt.a -DIRRLICHT_INCLUDE_DIR=$PWD/../irrlicht/include -DCMAKE_INSTALL_PREFIX=../artifact/minetest/usr/ -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE -DBUILD_SERVER=TRUE ..
|
||||
- make -j2
|
||||
- make install
|
||||
artifacts:
|
||||
@ -30,7 +38,7 @@ variables:
|
||||
.debpkg_template:
|
||||
stage: package
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get update
|
||||
- apt-get install -y git
|
||||
- mkdir -p build/deb/minetest/DEBIAN/
|
||||
- cp misc/debpkg-control build/deb/minetest/DEBIAN/control
|
||||
@ -39,6 +47,7 @@ variables:
|
||||
- git clone $MINETEST_GAME_REPO build/deb/minetest/usr/share/minetest/games/minetest_game
|
||||
- rm -rf build/deb/minetest/usr/share/minetest/games/minetest/.git
|
||||
- sed -i 's/DATEPLACEHOLDER/'$(date +%y.%m.%d)'/g' build/deb/minetest/DEBIAN/control
|
||||
- sed -i 's/JPEG_PLACEHOLDER/'$JPEG_PKG'/g' build/deb/minetest/DEBIAN/control
|
||||
- sed -i 's/LEVELDB_PLACEHOLDER/'$LEVELDB_PKG'/g' build/deb/minetest/DEBIAN/control
|
||||
- cd build/deb/ && dpkg-deb -b minetest/ && mv minetest.deb ../../
|
||||
artifacts:
|
||||
@ -49,7 +58,7 @@ variables:
|
||||
.debpkg_install:
|
||||
stage: deploy
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get update
|
||||
script:
|
||||
- apt-get install -y ./*.deb
|
||||
- minetest --version
|
||||
@ -63,9 +72,6 @@ variables:
|
||||
build:debian-9:
|
||||
extends: .build_template
|
||||
image: debian:9
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:debian-9:
|
||||
extends: .debpkg_template
|
||||
@ -74,6 +80,7 @@ package:debian-9:
|
||||
- build:debian-9
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
JPEG_PKG: libjpeg62-turbo
|
||||
|
||||
deploy:debian-9:
|
||||
extends: .debpkg_install
|
||||
@ -86,9 +93,6 @@ deploy:debian-9:
|
||||
build:debian-10:
|
||||
extends: .build_template
|
||||
image: debian:10
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:debian-10:
|
||||
extends: .debpkg_template
|
||||
@ -97,6 +101,7 @@ package:debian-10:
|
||||
- build:debian-10
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1d
|
||||
JPEG_PKG: libjpeg62-turbo
|
||||
|
||||
deploy:debian-10:
|
||||
extends: .debpkg_install
|
||||
@ -113,9 +118,6 @@ deploy:debian-10:
|
||||
build:ubuntu-16.04:
|
||||
extends: .build_template
|
||||
image: ubuntu:xenial
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:ubuntu-16.04:
|
||||
extends: .debpkg_template
|
||||
@ -124,6 +126,7 @@ package:ubuntu-16.04:
|
||||
- build:ubuntu-16.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
JPEG_PKG: libjpeg-turbo8
|
||||
|
||||
deploy:ubuntu-16.04:
|
||||
extends: .debpkg_install
|
||||
@ -136,9 +139,6 @@ deploy:ubuntu-16.04:
|
||||
build:ubuntu-18.04:
|
||||
extends: .build_template
|
||||
image: ubuntu:bionic
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:ubuntu-18.04:
|
||||
extends: .debpkg_template
|
||||
@ -147,6 +147,7 @@ package:ubuntu-18.04:
|
||||
- build:ubuntu-18.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
JPEG_PKG: libjpeg-turbo8
|
||||
|
||||
deploy:ubuntu-18.04:
|
||||
extends: .debpkg_install
|
||||
@ -163,17 +164,17 @@ build:fedora-28:
|
||||
extends: .build_template
|
||||
image: fedora:28
|
||||
before_script:
|
||||
- dnf -y install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel
|
||||
- dnf -y install make git gcc gcc-c++ kernel-devel cmake libjpeg-devel libpng-devel libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel
|
||||
|
||||
##
|
||||
## MinGW for Windows
|
||||
##
|
||||
|
||||
.generic_win_template:
|
||||
image: ubuntu:bionic
|
||||
image: ubuntu:focal
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get install -y wget xz-utils unzip git cmake gettext
|
||||
- apt-get update
|
||||
- DEBIAN_FRONTEND=noninteractive apt-get install -y wget xz-utils unzip git cmake gettext
|
||||
- wget -nv http://minetest.kitsunemimi.pw/mingw-w64-${WIN_ARCH}_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
|
||||
- tar -xaf mingw.tar.xz -C /usr
|
||||
|
||||
@ -183,13 +184,13 @@ build:fedora-28:
|
||||
artifacts:
|
||||
expire_in: 1h
|
||||
paths:
|
||||
- build/minetest/_build/*
|
||||
- build/build/*.zip
|
||||
|
||||
.package_win_template:
|
||||
extends: .generic_win_template
|
||||
stage: package
|
||||
script:
|
||||
- unzip build/minetest/_build/minetest-*.zip
|
||||
- unzip build/build/*.zip
|
||||
- cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libgcc*.dll minetest-*-win*/bin/
|
||||
- cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libstdc++*.dll minetest-*-win*/bin/
|
||||
- cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libwinpthread*.dll minetest-*-win*/bin/
|
||||
@ -201,7 +202,7 @@ build:fedora-28:
|
||||
build:win32:
|
||||
extends: .build_win_template
|
||||
script:
|
||||
- ./util/buildbot/buildwin32.sh build
|
||||
- EXISTING_MINETEST_DIR=$PWD ./util/buildbot/buildwin32.sh build
|
||||
variables:
|
||||
WIN_ARCH: "i686"
|
||||
|
||||
@ -216,7 +217,7 @@ package:win32:
|
||||
build:win64:
|
||||
extends: .build_win_template
|
||||
script:
|
||||
- ./util/buildbot/buildwin64.sh build
|
||||
- EXISTING_MINETEST_DIR=$PWD ./util/buildbot/buildwin64.sh build
|
||||
variables:
|
||||
WIN_ARCH: "x86_64"
|
||||
|
||||
|
@ -19,8 +19,8 @@ read_globals = {
|
||||
"Settings",
|
||||
|
||||
string = {fields = {"split", "trim"}},
|
||||
table = {fields = {"copy", "getn", "indexof", "insert_all"}},
|
||||
math = {fields = {"hypot"}},
|
||||
table = {fields = {"copy", "getn", "indexof", "insert_all", "combine"}},
|
||||
math = {fields = {"hypot", "round"}},
|
||||
}
|
||||
|
||||
globals = {
|
||||
|
74
.mailmap
@ -1,33 +1,67 @@
|
||||
# Documentation: https://git-scm.com/docs/git-check-mailmap#_mapping_authors
|
||||
|
||||
0gb.us <0gb.us@0gb.us> <us_0gb@laptop-0gb-us.0gb.us>
|
||||
Calinou <calinou9999@gmail.com> <calinou9999spam@gmail.com>
|
||||
Perttu Ahola <celeron55@gmail.com> celeron55 <celeron55@gmail.com>
|
||||
Calinou <calinou@opmbx.org> <calinou9999@gmail.com>
|
||||
Calinou <calinou@opmbx.org> <calinou9999spam@gmail.com>
|
||||
Perttu Ahola <celeron55@gmail.com>
|
||||
Perttu Ahola <celeron55@gmail.com> celeron55 <celeron55@armada.(none)>
|
||||
Craig Robbins <kde.psych@gmail.com> <crobbins@localhost.localdomain>
|
||||
Zeno- <kde.psych@gmail.com>
|
||||
Zeno- <kde.psych@gmail.com> <crobbins@localhost.localdomain>
|
||||
Diego Martínez <kaeza@users.sf.net>
|
||||
Diego Martínez <kaeza@users.sf.net> <lkaezadl3@gmail.com>
|
||||
Ilya Zhuravlev <zhuravlevilya@ya.ru>
|
||||
Ilya Zhuravlev <zhuravlevilya@ya.ru> <whatever@xyz.is>
|
||||
kwolekr <kwolekr@minetest.net> <mirrorisim@gmail.com>
|
||||
PilzAdam <pilzadam@minetest.net> PilzAdam <adam-k@outlook.com>
|
||||
PilzAdam <pilzadam@minetest.net> Pilz Adam <PilzAdam@gmx.de>
|
||||
PilzAdam <pilzadam@minetest.net> PilzAdam <PilzAdam@gmx.de>
|
||||
PilzAdam <pilzadam@minetest.net> <adam-k@outlook.com>
|
||||
PilzAdam <pilzadam@minetest.net> <PilzAdam@gmx.de>
|
||||
proller <proller@github.com> <proler@github.com>
|
||||
proller <proller@github.com> <proler@gmail.com>
|
||||
RealBadAngel <maciej.kasatkin@o2.pl> <mk@realbadangel.pl>
|
||||
RealBadAngel <maciej.kasatkin@o2.pl> <maciej.kasatkin@yahoo.com>
|
||||
Selat <LongExampleTestName@gmail.com> <LongExampletestName@gmail.com>
|
||||
ShadowNinja <shadowninja@minetest.net> ShadowNinja <noreply@gmail.com>
|
||||
Shen Zheyu <arsdragonfly@gmail.com> arsdragonfly <arsdragonfly@gmail.com>
|
||||
Pavel Elagin <elagin.pasha@gmail.com> elagin <elagin.pasha@gmail.com>
|
||||
Esteban I. Ruiz Moreno <exio4.com@gmail.com> Esteban I. RM <exio4.com@gmail.com>
|
||||
manuel duarte <ffrogger0@yahoo.com> manuel joaquim <ffrogger0@yahoo.com>
|
||||
manuel duarte <ffrogger0@yahoo.com> sweetbomber <ffrogger _zero_ at yahoo dot com>
|
||||
Diego Martínez <kaeza@users.sf.net> kaeza <kaeza@users.sf.net>
|
||||
Diego Martínez <kaeza@users.sf.net> Diego Martinez <kaeza@users.sf.net>
|
||||
Lord James <neftali_dtctv@hotmail.com> Lord89James <neftali_dtctv@hotmail.com>
|
||||
BlockMen <nmuelll@web.de> Block Men <nmuelll@web.de>
|
||||
sfan5 <sfan5@live.de> Sfan5 <sfan5@live.de>
|
||||
DannyDark <the_skeleton_of_a_child@yahoo.co.uk> dannydark <the_skeleton_of_a_child@yahoo.co.uk>
|
||||
Ilya Pavlov <TTChangeTheWorld@gmail.com> Ilya <TTChangeTheWorld@gmail.com>
|
||||
Ilya Zhuravlev <zhuravlevilya@ya.ru> xyzz <zhuravlevilya@ya.ru>
|
||||
Esteban I. Ruiz Moreno <exio4.com@gmail.com>
|
||||
Esteban I. Ruiz Moreno <exio4.com@gmail.com> <me@exio4.xyz>
|
||||
Lord James <neftali_dtctv@hotmail.com>
|
||||
BlockMen <nmuelll@web.de>
|
||||
sfan5 <sfan5@live.de>
|
||||
DannyDark <the_skeleton_of_a_child@yahoo.co.uk>
|
||||
Ilya Pavlov <TTChangeTheWorld@gmail.com>
|
||||
sapier <Sapier at GMX dot net> sapier <sapier AT gmx DOT net>
|
||||
sapier <Sapier at GMX dot net> sapier <sapier at gmx dot net>
|
||||
|
||||
SmallJoker <SmallJoker@users.noreply.github.com> <mk939@ymail.com>
|
||||
Loïc Blot <nerzhul@users.noreply.github.com>
|
||||
Loïc Blot <nerzhul@users.noreply.github.com> <loic.blot@unix-experience.fr>
|
||||
numzero <numzer0@yandex.ru> Vitaliy <numzer0@yandex.ru>
|
||||
numzero <numzer0@yandex.ru> <silverunicorn2011@yandex.ru>
|
||||
Jean-Patrick Guerrero <kilbith@users.noreply.github.com>
|
||||
Jean-Patrick Guerrero <kilbith@users.noreply.github.com> <jeanpatrick.guerrero@gmail.com>
|
||||
HybridDog <3192173+HybridDog@users.noreply.github.com> <ovvv@web.de>
|
||||
srfqi <muhammadrifqipriyosusanto@gmail.com>
|
||||
Dániel Juhász <juhdanad@gmail.com>
|
||||
rubenwardy <rw@rubenwardy.com>
|
||||
rubenwardy <rw@rubenwardy.com> <rubenwardy@gmail.com>
|
||||
Paul Ouellette <oue.paul18@gmail.com>
|
||||
Vanessa Dannenberg <vanessa.e.dannenberg@gmail.com> <vanessaezekowitz@gmail.com>
|
||||
ClobberXD <ClobberXD@gmail.com>
|
||||
ClobberXD <ClobberXD@gmail.com> <ClobberXD@protonmail.com>
|
||||
ClobberXD <ClobberXD@gmail.com> <36130650+ClobberXD@users.noreply.github.com>
|
||||
Auke Kok <sofar+github@foo-projects.org>
|
||||
Auke Kok <sofar+github@foo-projects.org> <sofar@foo-projects.org>
|
||||
Desour <vorunbekannt75@web.de>
|
||||
Nathanaël Courant <Ekdohibs@users.noreply.github.com> <nathanael.courant@laposte.net>
|
||||
Ezhh <owlecho@live.com>
|
||||
paramat <paramat@users.noreply.github.com>
|
||||
paramat <paramat@users.noreply.github.com> <mat.gregory@virginmedia.com>
|
||||
lhofhansl <lhofhansl@yahoo.com> <larsh@apache.org>
|
||||
red-001 <red-001@outlook.ie> <red-001@openmailbox.org>
|
||||
Wuzzy <wuzzy2@mail.ru> <Wuzzy2@mail.ru>
|
||||
Wuzzy <wuzzy2@mail.ru> <almikes@aol.com>
|
||||
Jordach <jordach.snelling@gmail.com>
|
||||
MoNTE48 <MoNTE48@mail.ua>
|
||||
v-rob <robinsonvincent89@gmail.com>
|
||||
v-rob <robinsonvincent89@gmail.com> <31123645+v-rob@users.noreply.github.com>
|
||||
EvidenceB <49488517+EvidenceBKidscode@users.noreply.github.com>
|
||||
gregorycu <gregory.currie@gmail.com>
|
||||
Rogier <rogier777@gmail.com>
|
||||
Rogier <rogier777@gmail.com> <Rogier-5@users.noreply.github.com>
|
||||
|
@ -10,9 +10,9 @@ set(CLANG_MINIMUM_VERSION "3.4")
|
||||
|
||||
# Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing
|
||||
set(VERSION_MAJOR 5)
|
||||
set(VERSION_MINOR 4)
|
||||
set(VERSION_MINOR 5)
|
||||
set(VERSION_PATCH 0)
|
||||
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||
set(VERSION_EXTRA "dragonfire" CACHE STRING "Stuff to append to version string")
|
||||
|
||||
# Change to false for releases
|
||||
set(DEVELOPMENT_BUILD FALSE)
|
||||
@ -59,6 +59,29 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
# This is done here so that relative search paths are more reasonable
|
||||
find_package(Irrlicht)
|
||||
if(BUILD_CLIENT AND NOT IRRLICHT_FOUND)
|
||||
message(FATAL_ERROR "IrrlichtMt is required to build the client, but it was not found.")
|
||||
elseif(NOT IRRLICHT_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "Irrlicht or IrrlichtMt headers are required to build the server, but none found.")
|
||||
endif()
|
||||
|
||||
include(CheckSymbolExists)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${IRRLICHT_INCLUDE_DIR})
|
||||
unset(HAS_FORKED_IRRLICHT CACHE)
|
||||
check_symbol_exists(IRRLICHT_VERSION_MT "IrrCompileConfig.h" HAS_FORKED_IRRLICHT)
|
||||
if(NOT HAS_FORKED_IRRLICHT)
|
||||
string(CONCAT EXPLANATION_MSG
|
||||
"Irrlicht found, but it is not IrrlichtMt (Minetest's Irrlicht fork). "
|
||||
"The Minetest team has forked Irrlicht to make their own customizations. "
|
||||
"It can be found here: https://github.com/minetest/irrlicht")
|
||||
if(BUILD_CLIENT)
|
||||
message(FATAL_ERROR "${EXPLANATION_MSG}\n"
|
||||
"Building the client with upstream Irrlicht is no longer possible.")
|
||||
else()
|
||||
message(WARNING "${EXPLANATION_MSG}\n"
|
||||
"The server can still be built with upstream Irrlicht but this is DISCOURAGED.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Installation
|
||||
@ -167,7 +190,6 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/devtest" DESTINATION "${SHA
|
||||
if(BUILD_CLIENT)
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/shaders" DESTINATION "${SHAREDIR}/client")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fonts" DESTINATION "${SHAREDIR}")
|
||||
if(RUN_IN_PLACE)
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/clientmods" DESTINATION "${SHAREDIR}")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/serverlist" DESTINATION "${SHAREDIR}/client")
|
||||
@ -202,8 +224,8 @@ find_package(GMP REQUIRED)
|
||||
find_package(Json REQUIRED)
|
||||
find_package(Lua REQUIRED)
|
||||
|
||||
# JsonCPP doesn't compile well on GCC 4.8
|
||||
if(NOT ENABLE_SYSTEM_JSONCPP)
|
||||
# JsonCpp doesn't compile well on GCC 4.8
|
||||
if(NOT USE_SYSTEM_JSONCPP)
|
||||
set(GCC_MINIMUM_VERSION "4.9")
|
||||
endif()
|
||||
|
||||
@ -212,7 +234,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
message(FATAL_ERROR "Insufficient gcc version, found ${CMAKE_CXX_COMPILER_VERSION}. "
|
||||
"Version ${GCC_MINIMUM_VERSION} or higher is required.")
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${CLANG_MINIMUM_VERSION}")
|
||||
message(FATAL_ERROR "Insufficient clang version, found ${CMAKE_CXX_COMPILER_VERSION}. "
|
||||
"Version ${CLANG_MINIMUM_VERSION} or higher is required.")
|
||||
|
14
Dockerfile
@ -1,6 +1,7 @@
|
||||
FROM alpine:3.11
|
||||
FROM alpine:3.13
|
||||
|
||||
ENV MINETEST_GAME_VERSION master
|
||||
ENV IRRLICHT_VERSION master
|
||||
|
||||
COPY .git /usr/src/minetest/.git
|
||||
COPY CMakeLists.txt /usr/src/minetest/CMakeLists.txt
|
||||
@ -18,9 +19,7 @@ COPY textures /usr/src/minetest/textures
|
||||
|
||||
WORKDIR /usr/src/minetest
|
||||
|
||||
RUN apk add --no-cache git build-base irrlicht-dev cmake bzip2-dev libpng-dev \
|
||||
jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev \
|
||||
libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev \
|
||||
RUN apk add --no-cache git build-base cmake sqlite-dev curl-dev zlib-dev \
|
||||
gmp-dev jsoncpp-dev postgresql-dev luajit-dev ca-certificates && \
|
||||
git clone --depth=1 -b ${MINETEST_GAME_VERSION} https://github.com/minetest/minetest_game.git ./games/minetest_game && \
|
||||
rm -fr ./games/minetest_game/.git
|
||||
@ -36,6 +35,9 @@ RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp/ && \
|
||||
make -j2 && \
|
||||
make install
|
||||
|
||||
RUN git clone --depth=1 https://github.com/minetest/irrlicht/ -b ${IRRLICHT_VERSION} && \
|
||||
cp -r irrlicht/include /usr/include/irrlichtmt
|
||||
|
||||
WORKDIR /usr/src/minetest
|
||||
RUN mkdir build && \
|
||||
cd build && \
|
||||
@ -49,9 +51,9 @@ RUN mkdir build && \
|
||||
make -j2 && \
|
||||
make install
|
||||
|
||||
FROM alpine:3.11
|
||||
FROM alpine:3.13
|
||||
|
||||
RUN apk add --no-cache sqlite-libs curl gmp libstdc++ libgcc libpq luajit && \
|
||||
RUN apk add --no-cache sqlite-libs curl gmp libstdc++ libgcc libpq luajit jsoncpp && \
|
||||
adduser -D minetest --uid 30000 -h /var/lib/minetest && \
|
||||
chown -R minetest:minetest /var/lib/minetest
|
||||
|
||||
|
13
LICENSE.txt
@ -14,6 +14,9 @@ https://www.apache.org/licenses/LICENSE-2.0.html
|
||||
Textures by Zughy are under CC BY-SA 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
textures/base/pack/server_public.png is under CC-BY 4.0, taken from Twitter's Twemoji set
|
||||
https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
Authors of media files
|
||||
-----------------------
|
||||
Everything not listed in here:
|
||||
@ -39,10 +42,10 @@ EliasFleckenstein03:
|
||||
misc/dragonfire.svg
|
||||
textures/base/pack/logo.png
|
||||
|
||||
JRottm
|
||||
JRottm:
|
||||
textures/base/pack/player_marker.png
|
||||
|
||||
srifqi
|
||||
srifqi:
|
||||
textures/base/pack/chat_hide_btn.png
|
||||
textures/base/pack/chat_show_btn.png
|
||||
textures/base/pack/joystick_bg.png
|
||||
@ -58,6 +61,9 @@ Zughy:
|
||||
textures/base/pack/cdb_update.png
|
||||
textures/base/pack/cdb_viewonline.png
|
||||
|
||||
appgurueu:
|
||||
textures/base/pack/server_incompatible.png
|
||||
|
||||
License of Minetest source code
|
||||
-------------------------------
|
||||
|
||||
@ -81,7 +87,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
Irrlicht
|
||||
---------------
|
||||
|
||||
This program uses the Irrlicht Engine. http://irrlicht.sourceforge.net/
|
||||
This program uses IrrlichtMt, Minetest's fork of
|
||||
the Irrlicht Engine. http://irrlicht.sourceforge.net/
|
||||
|
||||
The Irrlicht Engine License
|
||||
|
||||
|
48
README.md
@ -31,10 +31,10 @@ Table of Contents
|
||||
|
||||
Further documentation
|
||||
----------------------
|
||||
- Website: http://minetest.net/
|
||||
- Wiki: http://wiki.minetest.net/
|
||||
- Developer wiki: http://dev.minetest.net/
|
||||
- Forum: http://forum.minetest.net/
|
||||
- Website: https://minetest.net/
|
||||
- Wiki: https://wiki.minetest.net/
|
||||
- Developer wiki: https://dev.minetest.net/
|
||||
- Forum: https://forum.minetest.net/
|
||||
- GitHub: https://github.com/minetest/minetest/
|
||||
- [doc/](doc/) directory of source distribution
|
||||
|
||||
@ -68,7 +68,7 @@ Some can be changed in the key config dialog in the settings tab.
|
||||
| P | Enable/disable pitch move mode |
|
||||
| J | Enable/disable fast mode (needs fast privilege) |
|
||||
| H | Enable/disable noclip mode (needs noclip privilege) |
|
||||
| E | Move fast in fast mode |
|
||||
| E | Aux1 (Move fast in fast mode. Games may add special features) |
|
||||
| C | Cycle through camera modes |
|
||||
| V | Cycle through minimap modes |
|
||||
| Shift + V | Change minimap orientation |
|
||||
@ -133,8 +133,8 @@ Compiling
|
||||
| Dependency | Version | Commentary |
|
||||
|------------|---------|------------|
|
||||
| GCC | 4.9+ | Can be replaced with Clang 3.4+ |
|
||||
| CMake | 2.6+ | |
|
||||
| Irrlicht | 1.7.3+ | |
|
||||
| CMake | 3.5+ | |
|
||||
| IrrlichtMt | - | Custom version of Irrlicht, see https://github.com/minetest/irrlicht |
|
||||
| SQLite3 | 3.0+ | |
|
||||
| LuaJIT | 2.0+ | Bundled Lua 5.1 is used if not present |
|
||||
| GMP | 5.0.0+ | Bundled mini-GMP is used if not present |
|
||||
@ -142,19 +142,19 @@ Compiling
|
||||
|
||||
For Debian/Ubuntu users:
|
||||
|
||||
sudo apt install g++ make libc6-dev libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
For Fedora users:
|
||||
|
||||
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel bzip2-libs gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel doxygen spatialindex-devel bzip2-devel
|
||||
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel
|
||||
|
||||
For Arch users:
|
||||
|
||||
sudo pacman -S base-devel libcurl-gnutls cmake libxxf86vm irrlicht libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses
|
||||
sudo pacman -S base-devel libcurl-gnutls cmake libxxf86vm libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses
|
||||
|
||||
For Alpine users:
|
||||
|
||||
sudo apk add build-base irrlicht-dev cmake bzip2-dev libpng-dev jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev
|
||||
sudo apk add build-base cmake libpng-dev jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev
|
||||
|
||||
#### Download
|
||||
|
||||
@ -209,8 +209,8 @@ Run it:
|
||||
- You can disable the client build by specifying `-DBUILD_CLIENT=FALSE`.
|
||||
- You can select between Release and Debug build by `-DCMAKE_BUILD_TYPE=<Debug or Release>`.
|
||||
- Debug build is slower, but gives much more useful output in a debugger.
|
||||
- If you build a bare server you don't need to have Irrlicht installed.
|
||||
- In that case use `-DIRRLICHT_SOURCE_DIR=/the/irrlicht/source`.
|
||||
- If you build a bare server you don't need to have the Irrlicht or IrrlichtMt library installed.
|
||||
- In that case use `-DIRRLICHT_INCLUDE_DIR=/some/where/irrlicht/include`.
|
||||
|
||||
### CMake options
|
||||
|
||||
@ -229,7 +229,7 @@ General options and their default values:
|
||||
ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
|
||||
ENABLE_FREETYPE=ON - Build with FreeType2; Allows using TTF fonts
|
||||
ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations
|
||||
ENABLE_GLES=OFF - Build for OpenGL ES instead of OpenGL (requires support by Irrlicht)
|
||||
ENABLE_GLES=OFF - Build for OpenGL ES instead of OpenGL (requires support by IrrlichtMt)
|
||||
ENABLE_LEVELDB=ON - Build with LevelDB; Enables use of LevelDB map backend
|
||||
ENABLE_POSTGRESQL=ON - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
|
||||
ENABLE_REDIS=ON - Build with libhiredis; Enables use of Redis map backend
|
||||
@ -238,7 +238,7 @@ General options and their default values:
|
||||
ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua)
|
||||
ENABLE_PROMETHEUS=OFF - Build with Prometheus metrics exporter (listens on tcp/30000 by default)
|
||||
ENABLE_SYSTEM_GMP=ON - Use GMP from system (much faster than bundled mini-gmp)
|
||||
ENABLE_SYSTEM_JSONCPP=OFF - Use JsonCPP from system
|
||||
ENABLE_SYSTEM_JSONCPP=ON - Use JsonCPP from system
|
||||
OPENGL_GL_PREFERENCE=LEGACY - Linux client build only; See CMake Policy CMP0072 for reference
|
||||
RUN_IN_PLACE=FALSE - Create a portable install (worlds, settings etc. in current directory)
|
||||
USE_GPROF=FALSE - Enable profiling using GProf
|
||||
@ -246,8 +246,6 @@ General options and their default values:
|
||||
|
||||
Library specific options:
|
||||
|
||||
BZIP2_INCLUDE_DIR - Linux only; directory where bzlib.h is located
|
||||
BZIP2_LIBRARY - Linux only; path to libbz2.a/libbz2.so
|
||||
CURL_DLL - Only if building with cURL on Windows; path to libcurl.dll
|
||||
CURL_INCLUDE_DIR - Only if building with cURL; directory where curl.h is located
|
||||
CURL_LIBRARY - Only if building with cURL; path to libcurl.a/libcurl.so/libcurl.lib
|
||||
@ -257,14 +255,13 @@ Library specific options:
|
||||
FREETYPE_INCLUDE_DIR_ft2build - Only if building with FreeType 2; directory that contains ft2build.h
|
||||
FREETYPE_LIBRARY - Only if building with FreeType 2; path to libfreetype.a/libfreetype.so/freetype.lib
|
||||
FREETYPE_DLL - Only if building with FreeType 2 on Windows; path to libfreetype.dll
|
||||
GETTEXT_DLL - Only when building with gettext on Windows; path to libintl3.dll
|
||||
GETTEXT_ICONV_DLL - Only when building with gettext on Windows; path to libiconv2.dll
|
||||
GETTEXT_DLL - Only when building with gettext on Windows; paths to libintl + libiconv DLLs
|
||||
GETTEXT_INCLUDE_DIR - Only when building with gettext; directory that contains iconv.h
|
||||
GETTEXT_LIBRARY - Only when building with gettext on Windows; path to libintl.dll.a
|
||||
GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe
|
||||
IRRLICHT_DLL - Only on Windows; path to Irrlicht.dll
|
||||
IRRLICHT_DLL - Only on Windows; path to IrrlichtMt.dll
|
||||
IRRLICHT_INCLUDE_DIR - Directory that contains IrrCompileConfig.h
|
||||
IRRLICHT_LIBRARY - Path to libIrrlicht.a/libIrrlicht.so/libIrrlicht.dll.a/Irrlicht.lib
|
||||
IRRLICHT_LIBRARY - Path to libIrrlichtMt.a/libIrrlichtMt.so/libIrrlichtMt.dll.a/IrrlichtMt.lib
|
||||
LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h
|
||||
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
|
||||
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
|
||||
@ -276,7 +273,6 @@ Library specific options:
|
||||
SPATIAL_LIBRARY - Only when building with LibSpatial; path to libspatialindex_c.so/spatialindex-32.lib
|
||||
LUA_INCLUDE_DIR - Only if you want to use LuaJIT; directory where luajit.h is located
|
||||
LUA_LIBRARY - Only if you want to use LuaJIT; path to libluajit.a/libluajit.so
|
||||
MINGWM10_DLL - Only if compiling with MinGW; path to mingwm10.dll
|
||||
OGG_DLL - Only if building with sound on Windows; path to libogg.dll
|
||||
OGG_INCLUDE_DIR - Only if building with sound; directory that contains an ogg directory which contains ogg.h
|
||||
OGG_LIBRARY - Only if building with sound; path to libogg.a/libogg.so/libogg.dll.a
|
||||
@ -287,9 +283,8 @@ Library specific options:
|
||||
OPENGLES2_LIBRARY - Only if building with GLES; path to libGLESv2.a/libGLESv2.so
|
||||
SQLITE3_INCLUDE_DIR - Directory that contains sqlite3.h
|
||||
SQLITE3_LIBRARY - Path to libsqlite3.a/libsqlite3.so/sqlite3.lib
|
||||
VORBISFILE_DLL - Only if building with sound on Windows; path to libvorbisfile-3.dll
|
||||
VORBISFILE_LIBRARY - Only if building with sound; path to libvorbisfile.a/libvorbisfile.so/libvorbisfile.dll.a
|
||||
VORBIS_DLL - Only if building with sound on Windows; path to libvorbis-0.dll
|
||||
VORBIS_DLL - Only if building with sound on Windows; paths to vorbis DLLs
|
||||
VORBIS_INCLUDE_DIR - Only if building with sound; directory that contains a directory vorbis with vorbisenc.h inside
|
||||
VORBIS_LIBRARY - Only if building with sound; path to libvorbis.a/libvorbis.so/libvorbis.dll.a
|
||||
XXF86VM_LIBRARY - Only on Linux; path to libXXf86vm.a/libXXf86vm.so
|
||||
@ -314,9 +309,10 @@ It is highly recommended to use vcpkg as package manager.
|
||||
|
||||
After you successfully built vcpkg you can easily install the required libraries:
|
||||
```powershell
|
||||
vcpkg install irrlicht zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit gmp jsoncpp --triplet x64-windows
|
||||
vcpkg install zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit gmp jsoncpp --triplet x64-windows
|
||||
```
|
||||
|
||||
- **Note that you currently need to build irrlicht on your own**
|
||||
- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
|
||||
- `openal-soft`, `libvorbis` and `libogg` are optional, but required to use sound.
|
||||
- `freetype` is optional, it allows true-type font rendering.
|
||||
@ -354,7 +350,7 @@ This is outdated and not recommended. Follow the instructions on https://dev.min
|
||||
Run the following script in PowerShell:
|
||||
|
||||
```powershell
|
||||
cmake . -G"Visual Studio 15 2017 Win64" -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GETTEXT=OFF -DENABLE_CURSES=OFF -DENABLE_SYSTEM_JSONCPP=ON
|
||||
cmake . -G"Visual Studio 15 2017 Win64" -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GETTEXT=OFF -DENABLE_CURSES=OFF
|
||||
cmake --build . --config Release
|
||||
```
|
||||
Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct.
|
||||
|
@ -1,8 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '30.0.2'
|
||||
ndkVersion '21.3.6528147'
|
||||
buildToolsVersion '30.0.3'
|
||||
ndkVersion '22.0.7026061'
|
||||
defaultConfig {
|
||||
applicationId 'net.minetest.minetest'
|
||||
minSdkVersion 16
|
||||
|
@ -1,10 +1,10 @@
|
||||
// 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("versionMinor", 3) // Version Minor
|
||||
project.ext.set("versionMinor", 5) // Version Minor
|
||||
project.ext.set("versionPatch", 0) // Version Patch
|
||||
project.ext.set("versionExtra", "-dev") // Version Extra
|
||||
project.ext.set("versionCode", 30) // Android Version Code
|
||||
project.ext.set("versionCode", 32) // Android Version Code
|
||||
// NOTE: +2 after each release!
|
||||
// +1 for ARM and +1 for ARM64 APK's, because
|
||||
// each APK must have a larger `versionCode` than the previous
|
||||
@ -15,7 +15,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
classpath 'com.android.tools.build:gradle:4.1.1'
|
||||
classpath 'de.undercouch:gradle-download-task:4.1.1'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@ -1,6 +1,6 @@
|
||||
#Mon Sep 07 22:11:10 CEST 2020
|
||||
#Fri Jan 08 17:52:00 UTC 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip
|
||||
|
143
build/android/icons/aux1_btn.svg
Normal file
@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
inkscape:export-ydpi="24.000002"
|
||||
inkscape:export-xdpi="24.000002"
|
||||
inkscape:export-filename="/home/stu/Desktop/icons/png/aux_btn.png"
|
||||
sodipodi:docname="aux_btn.svg"
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 135.46666 135.46667"
|
||||
height="512"
|
||||
width="512">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:snap-others="true"
|
||||
inkscape:snap-object-midpoints="false"
|
||||
inkscape:snap-to-guides="true"
|
||||
inkscape:snap-bbox="true"
|
||||
showguides="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:snap-grids="false"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="31"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-height="1024"
|
||||
inkscape:window-width="1920"
|
||||
units="px"
|
||||
showgrid="true"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:cy="212.91276"
|
||||
inkscape:cx="201.43176"
|
||||
inkscape:zoom="1.4633894"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#404040"
|
||||
id="base">
|
||||
<inkscape:grid
|
||||
empopacity="0.25098039"
|
||||
empcolor="#40ff40"
|
||||
opacity="0.1254902"
|
||||
color="#40ff40"
|
||||
empspacing="4"
|
||||
spacingy="0.26458333"
|
||||
spacingx="0.26458333"
|
||||
id="grid16"
|
||||
type="xygrid" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
style="display:inline"
|
||||
inkscape:label="Layer 2"
|
||||
id="layer2"
|
||||
inkscape:groupmode="layer">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path7055"
|
||||
d=""
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path7035"
|
||||
d=""
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path7005"
|
||||
d=""
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5127"
|
||||
d=""
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<text
|
||||
transform="scale(1.0078883,0.99217343)"
|
||||
id="text4716"
|
||||
y="85.59491"
|
||||
x="67.78315"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:48.4785px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#d9d9d9;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="fill:#d9d9d9;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
y="85.59491"
|
||||
x="67.78315"
|
||||
id="tspan4714"
|
||||
sodipodi:role="line">Aux1</tspan></text>
|
||||
<flowRoot
|
||||
transform="scale(0.26458333)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
|
||||
id="flowRoot4718"
|
||||
xml:space="preserve"><flowRegion
|
||||
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
|
||||
id="flowRegion4720"><rect
|
||||
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
|
||||
y="124.10143"
|
||||
x="264.65997"
|
||||
height="136.37059"
|
||||
width="157.5838"
|
||||
id="rect4722" /></flowRegion><flowPara
|
||||
id="flowPara4724" /></flowRoot>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
@ -1,411 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 135.46666 135.46667"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
sodipodi:docname="aux_btn.svg"
|
||||
inkscape:export-filename="/home/stu/Desktop/icons/png/aux_btn.png"
|
||||
inkscape:export-xdpi="24.000002"
|
||||
inkscape:export-ydpi="24.000002">
|
||||
<defs
|
||||
id="defs2">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Colorize"
|
||||
id="filter4628">
|
||||
<feComposite
|
||||
in2="SourceGraphic"
|
||||
operator="arithmetic"
|
||||
k1="0"
|
||||
k2="1"
|
||||
result="composite1"
|
||||
id="feComposite4614" />
|
||||
<feColorMatrix
|
||||
in="composite1"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix1"
|
||||
id="feColorMatrix4616" />
|
||||
<feFlood
|
||||
flood-opacity="1"
|
||||
flood-color="rgb(158,0,0)"
|
||||
result="flood1"
|
||||
id="feFlood4618" />
|
||||
<feBlend
|
||||
in="flood1"
|
||||
in2="colormatrix1"
|
||||
mode="multiply"
|
||||
result="blend1"
|
||||
id="feBlend4620" />
|
||||
<feBlend
|
||||
in2="blend1"
|
||||
mode="screen"
|
||||
result="blend2"
|
||||
id="feBlend4622" />
|
||||
<feColorMatrix
|
||||
in="blend2"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix2"
|
||||
id="feColorMatrix4624" />
|
||||
<feComposite
|
||||
in="colormatrix2"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
k2="1"
|
||||
result="composite2"
|
||||
id="feComposite4626" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Sharpen More"
|
||||
id="filter5109"
|
||||
inkscape:menu="Image Effects"
|
||||
inkscape:menu-tooltip="Sharpen edges and boundaries within the object, force=0.3">
|
||||
<feComposite
|
||||
in2="SourceGraphic"
|
||||
operator="arithmetic"
|
||||
k1="0"
|
||||
k2="1"
|
||||
result="composite1"
|
||||
id="feComposite5095" />
|
||||
<feColorMatrix
|
||||
in="composite1"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix1"
|
||||
id="feColorMatrix5097" />
|
||||
<feFlood
|
||||
flood-opacity="1"
|
||||
flood-color="rgb(158,67,0)"
|
||||
result="flood1"
|
||||
id="feFlood5099" />
|
||||
<feBlend
|
||||
in="flood1"
|
||||
in2="colormatrix1"
|
||||
mode="multiply"
|
||||
result="blend1"
|
||||
id="feBlend5101" />
|
||||
<feBlend
|
||||
in2="blend1"
|
||||
mode="screen"
|
||||
result="blend2"
|
||||
id="feBlend5103" />
|
||||
<feColorMatrix
|
||||
in="blend2"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix2"
|
||||
id="feColorMatrix5105" />
|
||||
<feComposite
|
||||
in="colormatrix2"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
k2="1"
|
||||
result="fbSourceGraphic"
|
||||
id="feComposite5107" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix5111" />
|
||||
<feComposite
|
||||
in2="fbSourceGraphic"
|
||||
id="feComposite5113"
|
||||
operator="arithmetic"
|
||||
k1="0"
|
||||
k2="1"
|
||||
result="composite1"
|
||||
in="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix5115"
|
||||
in="composite1"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix1" />
|
||||
<feFlood
|
||||
id="feFlood5117"
|
||||
flood-opacity="1"
|
||||
flood-color="rgb(158,0,0)"
|
||||
result="flood1" />
|
||||
<feBlend
|
||||
in2="colormatrix1"
|
||||
id="feBlend5119"
|
||||
in="flood1"
|
||||
mode="multiply"
|
||||
result="blend1" />
|
||||
<feBlend
|
||||
in2="blend1"
|
||||
id="feBlend5121"
|
||||
mode="screen"
|
||||
result="blend2" />
|
||||
<feColorMatrix
|
||||
id="feColorMatrix5123"
|
||||
in="blend2"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix2" />
|
||||
<feComposite
|
||||
in2="fbSourceGraphic"
|
||||
id="feComposite5125"
|
||||
in="colormatrix2"
|
||||
operator="in"
|
||||
k2="1"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix7007" />
|
||||
<feConvolveMatrix
|
||||
id="feConvolveMatrix7009"
|
||||
order="3 3"
|
||||
kernelMatrix="0 -0.15 0 -0.15 1.6 -0.15 0 -0.15 0"
|
||||
divisor="1"
|
||||
in="fbSourceGraphic"
|
||||
targetX="1"
|
||||
targetY="1"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix7011" />
|
||||
<feConvolveMatrix
|
||||
id="feConvolveMatrix7013"
|
||||
targetY="1"
|
||||
targetX="1"
|
||||
in="fbSourceGraphic"
|
||||
divisor="1"
|
||||
kernelMatrix="0 -0.3 0 -0.3 2.2 -0.3 0 -0.3 0"
|
||||
order="3 3"
|
||||
result="result1" />
|
||||
<feBlend
|
||||
in2="fbSourceGraphic"
|
||||
id="feBlend7015"
|
||||
mode="normal"
|
||||
result="result2" />
|
||||
</filter>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
orient="auto"
|
||||
id="DistanceX">
|
||||
<path
|
||||
id="path7410"
|
||||
style="stroke:#000000; stroke-width:0.5"
|
||||
d="M 3,-3 L -3,3 M 0,-5 L 0,5" />
|
||||
</marker>
|
||||
<pattern
|
||||
y="0"
|
||||
x="0"
|
||||
width="8"
|
||||
patternUnits="userSpaceOnUse"
|
||||
id="Hatch"
|
||||
height="8">
|
||||
<path
|
||||
id="path7413"
|
||||
stroke-width="0.25"
|
||||
stroke="#000000"
|
||||
linecap="square"
|
||||
d="M8 4 l-4,4" />
|
||||
<path
|
||||
id="path7415"
|
||||
stroke-width="0.25"
|
||||
stroke="#000000"
|
||||
linecap="square"
|
||||
d="M6 2 l-4,4" />
|
||||
<path
|
||||
id="path7417"
|
||||
stroke-width="0.25"
|
||||
stroke="#000000"
|
||||
linecap="square"
|
||||
d="M4 0 l-4,4" />
|
||||
</pattern>
|
||||
<symbol
|
||||
id="*Model_Space" />
|
||||
<symbol
|
||||
id="*Paper_Space" />
|
||||
<symbol
|
||||
id="*Paper_Space0" />
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Colorize"
|
||||
id="filter4883">
|
||||
<feComposite
|
||||
in2="SourceGraphic"
|
||||
operator="arithmetic"
|
||||
k1="0"
|
||||
k2="1"
|
||||
result="composite1"
|
||||
id="feComposite4869" />
|
||||
<feColorMatrix
|
||||
in="composite1"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix1"
|
||||
id="feColorMatrix4871" />
|
||||
<feFlood
|
||||
flood-opacity="1"
|
||||
flood-color="rgb(158,21,0)"
|
||||
result="flood1"
|
||||
id="feFlood4873" />
|
||||
<feBlend
|
||||
in="flood1"
|
||||
in2="colormatrix1"
|
||||
mode="multiply"
|
||||
result="blend1"
|
||||
id="feBlend4875" />
|
||||
<feBlend
|
||||
in2="blend1"
|
||||
mode="screen"
|
||||
result="blend2"
|
||||
id="feBlend4877" />
|
||||
<feColorMatrix
|
||||
in="blend2"
|
||||
values="1"
|
||||
type="saturate"
|
||||
result="colormatrix2"
|
||||
id="feColorMatrix4879" />
|
||||
<feComposite
|
||||
in="colormatrix2"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
k2="1"
|
||||
result="composite2"
|
||||
id="feComposite4881" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#404040"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="-341.34157"
|
||||
inkscape:cy="210.02973"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer2"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1023"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:snap-grids="false"
|
||||
inkscape:snap-page="true"
|
||||
showguides="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-to-guides="true"
|
||||
inkscape:snap-object-midpoints="false"
|
||||
inkscape:snap-others="true"
|
||||
inkscape:snap-bbox-midpoints="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid16"
|
||||
spacingx="0.26458333"
|
||||
spacingy="0.26458333"
|
||||
empspacing="4"
|
||||
color="#40ff40"
|
||||
opacity="0.1254902"
|
||||
empcolor="#40ff40"
|
||||
empopacity="0.25098039" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d=""
|
||||
id="path7055"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d=""
|
||||
id="path7035"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d=""
|
||||
id="path7005"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d=""
|
||||
id="path5127"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:48.47851181px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#d9d9d9;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
x="67.78315"
|
||||
y="85.59491"
|
||||
id="text4716"
|
||||
transform="scale(1.0078883,0.99217343)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4714"
|
||||
x="67.78315"
|
||||
y="85.59491"
|
||||
style="fill:#d9d9d9;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">AUX</tspan></text>
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot4718"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
|
||||
transform="scale(0.26458333)"><flowRegion
|
||||
id="flowRegion4720"
|
||||
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><rect
|
||||
id="rect4722"
|
||||
width="157.5838"
|
||||
height="136.37059"
|
||||
x="264.65997"
|
||||
y="124.10143"
|
||||
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /></flowRegion><flowPara
|
||||
id="flowPara4724" /></flowRoot> </g>
|
||||
</svg>
|
Before Width: | Height: | Size: 12 KiB |
@ -3,8 +3,8 @@ apply plugin: 'de.undercouch.download'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '30.0.2'
|
||||
ndkVersion '21.3.6528147'
|
||||
buildToolsVersion '30.0.3'
|
||||
ndkVersion '22.0.7026061'
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 29
|
||||
@ -71,7 +71,7 @@ task getDeps(dependsOn: downloadDeps, type: Copy) {
|
||||
}
|
||||
|
||||
// get sqlite
|
||||
def sqlite_ver = '3320200'
|
||||
def sqlite_ver = '3340000'
|
||||
task downloadSqlite(dependsOn: getDeps, type: Download) {
|
||||
src 'https://www.sqlite.org/2020/sqlite-amalgamation-' + sqlite_ver + '.zip'
|
||||
dest new File(buildDir, 'sqlite.zip')
|
||||
|
@ -14,7 +14,7 @@ include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := Irrlicht
|
||||
LOCAL_SRC_FILES := deps/Android/Irrlicht/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libIrrlicht.a
|
||||
LOCAL_SRC_FILES := deps/Android/Irrlicht/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libIrrlichtMt.a
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
#include $(CLEAR_VARS)
|
||||
@ -47,18 +47,6 @@ LOCAL_MODULE := OpenAL
|
||||
LOCAL_SRC_FILES := deps/Android/OpenAL-Soft/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libopenal.a
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
# You can use `OpenSSL and Crypto` instead `mbedTLS mbedx509 mbedcrypto`,
|
||||
#but it increase APK size on ~0.7MB
|
||||
#include $(CLEAR_VARS)
|
||||
#LOCAL_MODULE := OpenSSL
|
||||
#LOCAL_SRC_FILES := deps/Android/OpenSSL/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libssl.a
|
||||
#include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
#include $(CLEAR_VARS)
|
||||
#LOCAL_MODULE := Crypto
|
||||
#LOCAL_SRC_FILES := deps/Android/OpenSSL/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libcrypto.a
|
||||
#include $(PREBUILT_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := Vorbis
|
||||
LOCAL_SRC_FILES := deps/Android/Vorbis/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libvorbis.a
|
||||
@ -207,7 +195,6 @@ LOCAL_SRC_FILES += \
|
||||
LOCAL_SRC_FILES += deps/Android/sqlite/sqlite3.c
|
||||
|
||||
LOCAL_STATIC_LIBRARIES += Curl Freetype Irrlicht OpenAL mbedTLS mbedx509 mbedcrypto Vorbis LuaJIT android_native_app_glue $(PROFILER_LIBS) #LevelDB
|
||||
#OpenSSL Crypto
|
||||
|
||||
LOCAL_LDLIBS := -lEGL -lGLESv1_CM -lGLESv2 -landroid -lOpenSLES
|
||||
|
||||
|
@ -7,7 +7,7 @@ core.register_on_sending_chat_message(function(message)
|
||||
|
||||
local first_char = message:sub(1,1)
|
||||
if first_char == "/" or first_char == "." then
|
||||
core.display_chat_message(core.gettext("issued command: ") .. message)
|
||||
core.display_chat_message(core.gettext("Issued command: ") .. message)
|
||||
end
|
||||
|
||||
if first_char ~= "." then
|
||||
@ -18,7 +18,7 @@ core.register_on_sending_chat_message(function(message)
|
||||
param = param or ""
|
||||
|
||||
if not cmd then
|
||||
core.display_chat_message(core.gettext("-!- Empty command"))
|
||||
core.display_chat_message("-!- " .. core.gettext("Empty command."))
|
||||
return true
|
||||
end
|
||||
|
||||
@ -35,7 +35,7 @@ core.register_on_sending_chat_message(function(message)
|
||||
core.display_chat_message(result)
|
||||
end
|
||||
else
|
||||
core.display_chat_message(core.gettext("-!- Invalid command: ") .. cmd)
|
||||
core.display_chat_message("-!- " .. core.gettext("Invalid command: ") .. cmd)
|
||||
end
|
||||
|
||||
return true
|
||||
@ -69,7 +69,7 @@ core.register_chatcommand("teleport", {
|
||||
core.register_chatcommand("wielded", {
|
||||
description = "Print itemstring of wieleded item",
|
||||
func = function()
|
||||
return true, core.localplayer:get_wielded_item():get_name()
|
||||
return true, core.localplayer:get_wielded_item():to_string()
|
||||
end
|
||||
})
|
||||
|
||||
|
@ -11,12 +11,12 @@ core.register_on_death(function()
|
||||
if core.settings:get_bool("autorespawn") then
|
||||
core.send_respawn()
|
||||
else
|
||||
core.show_formspec("__builtin__:death", death_formspec)
|
||||
core.show_formspec("bultin:death", death_formspec)
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_on_formspec_input(function(formname, fields)
|
||||
if formname == "__builtin__:death" then
|
||||
if formname == "bultin:death" then
|
||||
if fields.btn_ghost_mode then
|
||||
core.display_chat_message("You are in ghost mode. Use .respawn to Respawn.")
|
||||
else
|
||||
|
@ -105,6 +105,10 @@ core.registered_on_inventory_open, core.register_on_inventory_open = make_regist
|
||||
core.registered_on_recieve_physics_override, core.register_on_recieve_physics_override = make_registration()
|
||||
core.registered_on_play_sound, core.register_on_play_sound = make_registration()
|
||||
core.registered_on_spawn_particle, core.register_on_spawn_particle = make_registration()
|
||||
core.registered_on_object_properties_change, core.register_on_object_properties_change = make_registration()
|
||||
core.registered_on_object_hp_change, core.register_on_object_hp_change = make_registration()
|
||||
core.registered_on_object_add, core.register_on_object_add = make_registration()
|
||||
|
||||
core.registered_nodes = {}
|
||||
core.registered_items = {}
|
||||
core.object_refs = {}
|
||||
|
@ -58,3 +58,23 @@ end
|
||||
function core.get_nearby_objects(radius)
|
||||
return core.get_objects_inside_radius(core.localplayer:get_pos(), radius)
|
||||
end
|
||||
|
||||
-- HTTP callback interface
|
||||
|
||||
function core.http_add_fetch(httpenv)
|
||||
httpenv.fetch = function(req, callback)
|
||||
local handle = httpenv.fetch_async(req)
|
||||
|
||||
local function update_http_status()
|
||||
local res = httpenv.fetch_async_get(handle)
|
||||
if res.completed then
|
||||
callback(res)
|
||||
else
|
||||
core.after(0, update_http_status)
|
||||
end
|
||||
end
|
||||
core.after(0, update_http_status)
|
||||
end
|
||||
|
||||
return httpenv
|
||||
end
|
||||
|
@ -1,5 +1,9 @@
|
||||
-- Minetest: builtin/common/chatcommands.lua
|
||||
|
||||
-- For server-side translations (if INIT == "game")
|
||||
-- Otherwise, use core.gettext
|
||||
local S = core.get_translator("__builtin")
|
||||
|
||||
core.registered_chatcommands = {}
|
||||
|
||||
function core.register_chatcommand(cmd, def)
|
||||
@ -74,25 +78,12 @@ if INIT == "client" then
|
||||
end
|
||||
end
|
||||
|
||||
local cmd_marker = "/"
|
||||
|
||||
local function gettext(...)
|
||||
return ...
|
||||
end
|
||||
|
||||
local function gettext_replace(text, replace)
|
||||
return text:gsub("$1", replace)
|
||||
end
|
||||
|
||||
|
||||
if INIT == "client" then
|
||||
cmd_marker = "."
|
||||
gettext = core.gettext
|
||||
gettext_replace = fgettext_ne
|
||||
end
|
||||
|
||||
local function do_help_cmd(name, param)
|
||||
local function format_help_line(cmd, def)
|
||||
local cmd_marker = "/"
|
||||
if INIT == "client" then
|
||||
cmd_marker = "."
|
||||
end
|
||||
local msg = core.colorize("#00ffff", cmd_marker .. cmd)
|
||||
if def.params and def.params ~= "" then
|
||||
msg = msg .. " " .. def.params
|
||||
@ -110,9 +101,21 @@ local function do_help_cmd(name, param)
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
return true, gettext("Available commands: ") .. table.concat(cmds, " ") .. "\n"
|
||||
.. gettext_replace("Use '$1help <cmd>' to get more information,"
|
||||
.. " or '$1help all' to list everything.", cmd_marker)
|
||||
local msg
|
||||
if INIT == "game" then
|
||||
msg = S("Available commands: @1",
|
||||
table.concat(cmds, " ")) .. "\n"
|
||||
.. S("Use '/help <cmd>' to get more "
|
||||
.. "information, or '/help all' to list "
|
||||
.. "everything.")
|
||||
else
|
||||
msg = core.gettext("Available commands: ")
|
||||
.. table.concat(cmds, " ") .. "\n"
|
||||
.. core.gettext("Use '.help <cmd>' to get more "
|
||||
.. "information, or '.help all' to list "
|
||||
.. "everything.")
|
||||
end
|
||||
return true, msg
|
||||
elseif param == "all" then
|
||||
local cmds = {}
|
||||
for cmd, def in pairs(core.registered_chatcommands) do
|
||||
@ -121,19 +124,31 @@ local function do_help_cmd(name, param)
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
return true, gettext("Available commands:").."\n"..table.concat(cmds, "\n")
|
||||
local msg
|
||||
if INIT == "game" then
|
||||
msg = S("Available commands:")
|
||||
else
|
||||
msg = core.gettext("Available commands:")
|
||||
end
|
||||
return true, msg.."\n"..table.concat(cmds, "\n")
|
||||
elseif INIT == "game" and param == "privs" then
|
||||
local privs = {}
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privs[#privs + 1] = priv .. ": " .. def.description
|
||||
end
|
||||
table.sort(privs)
|
||||
return true, "Available privileges:\n"..table.concat(privs, "\n")
|
||||
return true, S("Available privileges:").."\n"..table.concat(privs, "\n")
|
||||
else
|
||||
local cmd = param
|
||||
local def = core.registered_chatcommands[cmd]
|
||||
if not def then
|
||||
return false, gettext("Command not available: ")..cmd
|
||||
local msg
|
||||
if INIT == "game" then
|
||||
msg = S("Command not available: @1", cmd)
|
||||
else
|
||||
msg = core.gettext("Command not available: ") .. cmd
|
||||
end
|
||||
return false, msg
|
||||
else
|
||||
return true, format_help_line(cmd, def)
|
||||
end
|
||||
@ -142,16 +157,16 @@ end
|
||||
|
||||
if INIT == "client" then
|
||||
core.register_chatcommand("help", {
|
||||
params = gettext("[all | <cmd>]"),
|
||||
description = gettext("Get help for commands"),
|
||||
params = core.gettext("[all | <cmd>]"),
|
||||
description = core.gettext("Get help for commands"),
|
||||
func = function(param)
|
||||
return do_help_cmd(nil, param)
|
||||
end,
|
||||
})
|
||||
else
|
||||
core.register_chatcommand("help", {
|
||||
params = "[all | privs | <cmd>]",
|
||||
description = "Get help for commands or list privileges",
|
||||
params = S("[all | privs | <cmd>]"),
|
||||
description = S("Get help for commands or list privileges"),
|
||||
func = do_help_cmd,
|
||||
})
|
||||
end
|
||||
|
@ -20,7 +20,8 @@ local LIST_FORMSPEC_DESCRIPTION = [[
|
||||
button_exit[5,7;3,1;quit;%s]
|
||||
]]
|
||||
|
||||
local formspec_escape = core.formspec_escape
|
||||
local F = core.formspec_escape
|
||||
local S = core.get_translator("__builtin")
|
||||
local check_player_privs = core.check_player_privs
|
||||
|
||||
|
||||
@ -51,22 +52,23 @@ core.after(0, load_mod_command_tree)
|
||||
|
||||
local function build_chatcommands_formspec(name, sel, copy)
|
||||
local rows = {}
|
||||
rows[1] = "#FFF,0,Command,Parameters"
|
||||
rows[1] = "#FFF,0,"..F(S("Command"))..","..F(S("Parameters"))
|
||||
|
||||
local description = "For more information, click on any entry in the list.\n" ..
|
||||
"Double-click to copy the entry to the chat history."
|
||||
local description = S("For more information, click on "
|
||||
.. "any entry in the list.").. "\n" ..
|
||||
S("Double-click to copy the entry to the chat history.")
|
||||
|
||||
for i, data in ipairs(mod_cmds) do
|
||||
rows[#rows + 1] = COLOR_BLUE .. ",0," .. formspec_escape(data[1]) .. ","
|
||||
rows[#rows + 1] = COLOR_BLUE .. ",0," .. F(data[1]) .. ","
|
||||
for j, cmds in ipairs(data[2]) do
|
||||
local has_priv = check_player_privs(name, cmds[2].privs)
|
||||
rows[#rows + 1] = ("%s,1,%s,%s"):format(
|
||||
has_priv and COLOR_GREEN or COLOR_GRAY,
|
||||
cmds[1], formspec_escape(cmds[2].params))
|
||||
cmds[1], F(cmds[2].params))
|
||||
if sel == #rows then
|
||||
description = cmds[2].description
|
||||
if copy then
|
||||
core.chat_send_player(name, ("Command: %s %s"):format(
|
||||
core.chat_send_player(name, S("Command: @1 @2",
|
||||
core.colorize("#0FF", "/" .. cmds[1]), cmds[2].params))
|
||||
end
|
||||
end
|
||||
@ -74,9 +76,9 @@ local function build_chatcommands_formspec(name, sel, copy)
|
||||
end
|
||||
|
||||
return LIST_FORMSPEC_DESCRIPTION:format(
|
||||
"Available commands: (see also: /help <cmd>)",
|
||||
F(S("Available commands: (see also: /help <cmd>)")),
|
||||
table.concat(rows, ","), sel or 0,
|
||||
description, "Close"
|
||||
F(description), F(S("Close"))
|
||||
)
|
||||
end
|
||||
|
||||
@ -91,19 +93,19 @@ local function build_privs_formspec(name)
|
||||
table.sort(privs, function(a, b) return a[1] < b[1] end)
|
||||
|
||||
local rows = {}
|
||||
rows[1] = "#FFF,0,Privilege,Description"
|
||||
rows[1] = "#FFF,0,"..F(S("Privilege"))..","..F(S("Description"))
|
||||
|
||||
local player_privs = core.get_player_privs(name)
|
||||
for i, data in ipairs(privs) do
|
||||
rows[#rows + 1] = ("%s,0,%s,%s"):format(
|
||||
player_privs[data[1]] and COLOR_GREEN or COLOR_GRAY,
|
||||
data[1], formspec_escape(data[2].description))
|
||||
data[1], F(data[2].description))
|
||||
end
|
||||
|
||||
return LIST_FORMSPEC:format(
|
||||
"Available privileges:",
|
||||
F(S("Available privileges:")),
|
||||
table.concat(rows, ","),
|
||||
"Close"
|
||||
F(S("Close"))
|
||||
)
|
||||
end
|
||||
|
||||
@ -115,7 +117,7 @@ core.register_on_player_receive_fields(function(player, formname, fields)
|
||||
return
|
||||
end
|
||||
|
||||
local event = minetest.explode_table_event(fields.list)
|
||||
local event = core.explode_table_event(fields.list)
|
||||
if event.type ~= "INV" then
|
||||
local name = player:get_player_name()
|
||||
core.show_formspec(name, "__builtin:help_cmds",
|
||||
|
@ -244,6 +244,15 @@ function math.factorial(x)
|
||||
return v
|
||||
end
|
||||
|
||||
|
||||
function math.round(x)
|
||||
if x >= 0 then
|
||||
return math.floor(x + 0.5)
|
||||
end
|
||||
return math.ceil(x - 0.5)
|
||||
end
|
||||
|
||||
|
||||
function core.formspec_escape(text)
|
||||
if text ~= nil then
|
||||
text = string.gsub(text,"\\","\\\\")
|
||||
@ -785,3 +794,12 @@ end
|
||||
function core.is_nan(number)
|
||||
return number ~= number
|
||||
end
|
||||
|
||||
function core.inventorycube(img1, img2, img3)
|
||||
img2 = img2 or img1
|
||||
img3 = img3 or img1
|
||||
return "[inventorycube"
|
||||
.. "{" .. img1:gsub("%^", "&")
|
||||
.. "{" .. img2:gsub("%^", "&")
|
||||
.. "{" .. img3:gsub("%^", "&")
|
||||
end
|
||||
|
@ -48,6 +48,25 @@ describe("vector", function()
|
||||
assert.same({ x = 41, y = 52, z = 63 }, vector.offset(vector.new(1, 2, 3), 40, 50, 60))
|
||||
end)
|
||||
|
||||
it("to_string()", function()
|
||||
local v = vector.new(1, 2, 3.14)
|
||||
assert.same("(1, 2, 3.14)", vector.to_string(v))
|
||||
end)
|
||||
|
||||
it("from_string()", function()
|
||||
local v = vector.new(1, 2, 3.14)
|
||||
assert.same({v, 13}, {vector.from_string("(1, 2, 3.14)")})
|
||||
assert.same({v, 12}, {vector.from_string("(1,2 ,3.14)")})
|
||||
assert.same({v, 12}, {vector.from_string("(1,2,3.14,)")})
|
||||
assert.same({v, 11}, {vector.from_string("(1 2 3.14)")})
|
||||
assert.same({v, 15}, {vector.from_string("( 1, 2, 3.14 )")})
|
||||
assert.same({v, 15}, {vector.from_string(" ( 1, 2, 3.14) ")})
|
||||
assert.same({vector.new(), 8}, {vector.from_string("(0,0,0) ( 1, 2, 3.14) ")})
|
||||
assert.same({v, 22}, {vector.from_string("(0,0,0) ( 1, 2, 3.14) ", 8)})
|
||||
assert.same({v, 22}, {vector.from_string("(0,0,0) ( 1, 2, 3.14) ", 9)})
|
||||
assert.same(nil, vector.from_string("nothing"))
|
||||
end)
|
||||
|
||||
-- This function is needed because of floating point imprecision.
|
||||
local function almost_equal(a, b)
|
||||
if type(a) == "number" then
|
||||
|
@ -12,6 +12,22 @@ function vector.new(a, b, c)
|
||||
return {x=0, y=0, z=0}
|
||||
end
|
||||
|
||||
function vector.from_string(s, init)
|
||||
local x, y, z, np = string.match(s, "^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]" ..
|
||||
"%s*([^%s,]+)%s*[,%s]?%s*%)()", init)
|
||||
x = tonumber(x)
|
||||
y = tonumber(y)
|
||||
z = tonumber(z)
|
||||
if not (x and y and z) then
|
||||
return nil
|
||||
end
|
||||
return {x = x, y = y, z = z}, np
|
||||
end
|
||||
|
||||
function vector.to_string(v)
|
||||
return string.format("(%g, %g, %g)", v.x, v.y, v.z)
|
||||
end
|
||||
|
||||
function vector.equals(a, b)
|
||||
return a.x == b.x and
|
||||
a.y == b.y and
|
||||
@ -41,9 +57,9 @@ end
|
||||
|
||||
function vector.round(v)
|
||||
return {
|
||||
x = math.floor(v.x + 0.5),
|
||||
y = math.floor(v.y + 0.5),
|
||||
z = math.floor(v.z + 0.5)
|
||||
x = math.round(v.x),
|
||||
y = math.round(v.y),
|
||||
z = math.round(v.z)
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -58,26 +58,20 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function get_formspec(self)
|
||||
local formspec = ""
|
||||
|
||||
if not self.hidden and (self.parent == nil or not self.parent.hidden) then
|
||||
|
||||
if self.parent == nil then
|
||||
local tsize = self.tablist[self.last_tab_index].tabsize or
|
||||
{width=self.width, height=self.height}
|
||||
formspec = formspec ..
|
||||
string.format("size[%f,%f,%s]",tsize.width,tsize.height,
|
||||
dump(self.fixed_size))
|
||||
end
|
||||
formspec = formspec .. self:tab_header()
|
||||
formspec = formspec ..
|
||||
self.tablist[self.last_tab_index].get_formspec(
|
||||
self,
|
||||
self.tablist[self.last_tab_index].name,
|
||||
self.tablist[self.last_tab_index].tabdata,
|
||||
self.tablist[self.last_tab_index].tabsize
|
||||
)
|
||||
if self.hidden or (self.parent ~= nil and self.parent.hidden) then
|
||||
return ""
|
||||
end
|
||||
local tab = self.tablist[self.last_tab_index]
|
||||
|
||||
local content, prepend = tab.get_formspec(self, tab.name, tab.tabdata, tab.tabsize)
|
||||
|
||||
if self.parent == nil and not prepend then
|
||||
local tsize = tab.tabsize or {width=self.width, height=self.height}
|
||||
prepend = string.format("size[%f,%f,%s]", tsize.width, tsize.height,
|
||||
dump(self.fixed_size))
|
||||
end
|
||||
|
||||
local formspec = (prepend or "") .. self:tab_header() .. content
|
||||
return formspec
|
||||
end
|
||||
|
||||
@ -97,14 +91,9 @@ local function handle_buttons(self,fields)
|
||||
return true
|
||||
end
|
||||
|
||||
if self.tablist[self.last_tab_index].button_handler ~= nil then
|
||||
return
|
||||
self.tablist[self.last_tab_index].button_handler(
|
||||
self,
|
||||
fields,
|
||||
self.tablist[self.last_tab_index].name,
|
||||
self.tablist[self.last_tab_index].tabdata
|
||||
)
|
||||
local tab = self.tablist[self.last_tab_index]
|
||||
if tab.button_handler ~= nil then
|
||||
return tab.button_handler(self, fields, tab.name, tab.tabdata)
|
||||
end
|
||||
|
||||
return false
|
||||
@ -122,14 +111,9 @@ local function handle_events(self,event)
|
||||
return true
|
||||
end
|
||||
|
||||
if self.tablist[self.last_tab_index].evt_handler ~= nil then
|
||||
return
|
||||
self.tablist[self.last_tab_index].evt_handler(
|
||||
self,
|
||||
event,
|
||||
self.tablist[self.last_tab_index].name,
|
||||
self.tablist[self.last_tab_index].tabdata
|
||||
)
|
||||
local tab = self.tablist[self.last_tab_index]
|
||||
if tab.evt_handler ~= nil then
|
||||
return tab.evt_handler(self, event, tab.name, tab.tabdata)
|
||||
end
|
||||
|
||||
return false
|
||||
|
@ -18,6 +18,8 @@
|
||||
ui = {}
|
||||
ui.childlist = {}
|
||||
ui.default = nil
|
||||
-- Whether fstk is currently showing its own formspec instead of active ui elements.
|
||||
ui.overridden = false
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ui.add(child)
|
||||
@ -55,6 +57,7 @@ end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ui.update()
|
||||
ui.overridden = false
|
||||
local formspec = {}
|
||||
|
||||
-- handle errors
|
||||
@ -71,6 +74,7 @@ function ui.update()
|
||||
"button[2,6.6;4,1;btn_reconnect_yes;" .. fgettext("Reconnect") .. "]",
|
||||
"button[8,6.6;4,1;btn_reconnect_no;" .. fgettext("Main menu") .. "]"
|
||||
}
|
||||
ui.overridden = true
|
||||
elseif gamedata ~= nil and gamedata.errormessage ~= nil then
|
||||
local error_message = core.formspec_escape(gamedata.errormessage)
|
||||
|
||||
@ -89,6 +93,7 @@ function ui.update()
|
||||
error_title, error_message),
|
||||
"button[5,6.6;4,1;btn_error_confirm;" .. fgettext("OK") .. "]"
|
||||
}
|
||||
ui.overridden = true
|
||||
else
|
||||
local active_toplevel_ui_elements = 0
|
||||
for key,value in pairs(ui.childlist) do
|
||||
@ -185,6 +190,16 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
core.event_handler = function(event)
|
||||
-- Handle error messages
|
||||
if ui.overridden then
|
||||
if event == "MenuQuit" then
|
||||
gamedata.errormessage = nil
|
||||
gamedata.reconnect_requested = false
|
||||
ui.update()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if ui.handle_events(event) then
|
||||
ui.update()
|
||||
return
|
||||
|
@ -1,28 +1,5 @@
|
||||
-- Minetest: builtin/deprecated.lua
|
||||
|
||||
--
|
||||
-- Default material types
|
||||
--
|
||||
local function digprop_err()
|
||||
core.log("deprecated", "The core.digprop_* functions are obsolete and need to be replaced by item groups.")
|
||||
end
|
||||
|
||||
core.digprop_constanttime = digprop_err
|
||||
core.digprop_stonelike = digprop_err
|
||||
core.digprop_dirtlike = digprop_err
|
||||
core.digprop_gravellike = digprop_err
|
||||
core.digprop_woodlike = digprop_err
|
||||
core.digprop_leaveslike = digprop_err
|
||||
core.digprop_glasslike = digprop_err
|
||||
|
||||
function core.node_metadata_inventory_move_allow_all()
|
||||
core.log("deprecated", "core.node_metadata_inventory_move_allow_all is obsolete and does nothing.")
|
||||
end
|
||||
|
||||
function core.add_to_creative_inventory(itemstring)
|
||||
core.log("deprecated", "core.add_to_creative_inventory is obsolete and does nothing.")
|
||||
end
|
||||
|
||||
--
|
||||
-- EnvRef
|
||||
--
|
||||
@ -77,7 +54,7 @@ core.setting_save = setting_proxy("write")
|
||||
|
||||
function core.register_on_auth_fail(func)
|
||||
core.log("deprecated", "core.register_on_auth_fail " ..
|
||||
"is obsolete and should be replaced by " ..
|
||||
"is deprecated and should be replaced by " ..
|
||||
"core.register_on_authplayer instead.")
|
||||
|
||||
core.register_on_authplayer(function (player_name, ip, is_success)
|
||||
|
@ -84,9 +84,6 @@ core.register_entity(":__builtin:falling_node", {
|
||||
local textures
|
||||
if def.tiles and def.tiles[1] then
|
||||
local tile = def.tiles[1]
|
||||
if def.drawtype == "torchlike" and def.paramtype2 ~= "wallmounted" then
|
||||
tile = def.tiles[2] or def.tiles[1]
|
||||
end
|
||||
if type(tile) == "table" then
|
||||
tile = tile.name
|
||||
end
|
||||
@ -147,11 +144,7 @@ core.register_entity(":__builtin:falling_node", {
|
||||
|
||||
-- Rotate entity
|
||||
if def.drawtype == "torchlike" then
|
||||
if def.paramtype2 == "wallmounted" then
|
||||
self.object:set_yaw(math.pi*0.25)
|
||||
else
|
||||
self.object:set_yaw(-math.pi*0.25)
|
||||
end
|
||||
self.object:set_yaw(math.pi*0.25)
|
||||
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"
|
||||
@ -165,8 +158,12 @@ core.register_entity(":__builtin:falling_node", {
|
||||
if euler then
|
||||
self.object:set_rotation(euler)
|
||||
end
|
||||
elseif (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted") then
|
||||
elseif (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
|
||||
@ -208,6 +205,14 @@ core.register_entity(":__builtin:falling_node", {
|
||||
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,
|
||||
@ -407,7 +412,7 @@ local function convert_to_falling_node(pos, node)
|
||||
|
||||
obj:get_luaentity():set_node(node, metatable)
|
||||
core.remove_node(pos)
|
||||
return true
|
||||
return true, obj
|
||||
end
|
||||
|
||||
function core.spawn_falling_node(pos)
|
||||
|
@ -18,6 +18,8 @@ core.features = {
|
||||
pathfinder_works = true,
|
||||
object_step_has_moveresult = true,
|
||||
direct_velocity_on_players = true,
|
||||
use_texture_alpha_string_modes = true,
|
||||
degrotate_240_steps = true,
|
||||
}
|
||||
|
||||
function core.has_feature(arg)
|
||||
|
@ -15,15 +15,6 @@ end
|
||||
-- Item definition helpers
|
||||
--
|
||||
|
||||
function core.inventorycube(img1, img2, img3)
|
||||
img2 = img2 or img1
|
||||
img3 = img3 or img1
|
||||
return "[inventorycube"
|
||||
.. "{" .. img1:gsub("%^", "&")
|
||||
.. "{" .. img2:gsub("%^", "&")
|
||||
.. "{" .. img3:gsub("%^", "&")
|
||||
end
|
||||
|
||||
function core.dir_to_facedir(dir, is6d)
|
||||
--account for y if requested
|
||||
if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
|
||||
@ -144,7 +135,7 @@ end
|
||||
|
||||
function core.is_colored_paramtype(ptype)
|
||||
return (ptype == "color") or (ptype == "colorfacedir") or
|
||||
(ptype == "colorwallmounted")
|
||||
(ptype == "colorwallmounted") or (ptype == "colordegrotate")
|
||||
end
|
||||
|
||||
function core.strip_param2_color(param2, paramtype2)
|
||||
@ -155,6 +146,8 @@ function core.strip_param2_color(param2, paramtype2)
|
||||
param2 = math.floor(param2 / 32) * 32
|
||||
elseif paramtype2 == "colorwallmounted" then
|
||||
param2 = math.floor(param2 / 8) * 8
|
||||
elseif paramtype2 == "colordegrotate" then
|
||||
param2 = math.floor(param2 / 32) * 32
|
||||
end
|
||||
-- paramtype2 == "color" requires no modification.
|
||||
return param2
|
||||
@ -332,6 +325,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
|
||||
color_divisor = 8
|
||||
elseif def.paramtype2 == "colorfacedir" then
|
||||
color_divisor = 32
|
||||
elseif def.paramtype2 == "colordegrotate" then
|
||||
color_divisor = 32
|
||||
end
|
||||
if color_divisor then
|
||||
local color = math.floor(metatable.palette_index / color_divisor)
|
||||
@ -544,7 +539,7 @@ function core.node_dig(pos, node, digger)
|
||||
log("info", diggername .. " tried to dig "
|
||||
.. node.name .. " which is not diggable "
|
||||
.. core.pos_to_string(pos))
|
||||
return
|
||||
return false
|
||||
end
|
||||
|
||||
if core.is_protected(pos, diggername) then
|
||||
@ -553,7 +548,7 @@ function core.node_dig(pos, node, digger)
|
||||
.. " at protected position "
|
||||
.. core.pos_to_string(pos))
|
||||
core.record_protection_violation(pos, diggername)
|
||||
return
|
||||
return false
|
||||
end
|
||||
|
||||
log('action', diggername .. " digs "
|
||||
@ -636,6 +631,8 @@ function core.node_dig(pos, node, digger)
|
||||
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
|
||||
callback(pos_copy, node_copy, digger)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function core.itemstring_with_palette(item, palette_index)
|
||||
@ -663,7 +660,7 @@ end
|
||||
-- Item definition defaults
|
||||
--
|
||||
|
||||
local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99
|
||||
local default_stack_max = tonumber(core.settings:get("default_stack_max")) or 99
|
||||
|
||||
core.nodedef_default = {
|
||||
-- Item properties
|
||||
@ -692,10 +689,6 @@ core.nodedef_default = {
|
||||
|
||||
on_receive_fields = nil,
|
||||
|
||||
on_metadata_inventory_move = core.node_metadata_inventory_move_allow_all,
|
||||
on_metadata_inventory_offer = core.node_metadata_inventory_offer_allow_all,
|
||||
on_metadata_inventory_take = core.node_metadata_inventory_take_allow_all,
|
||||
|
||||
-- Node properties
|
||||
drawtype = "normal",
|
||||
visual_scale = 1.0,
|
||||
@ -706,7 +699,6 @@ core.nodedef_default = {
|
||||
-- {name="", backface_culling=true},
|
||||
-- {name="", backface_culling=true},
|
||||
--},
|
||||
alpha = 255,
|
||||
post_effect_color = {a=0, r=0, g=0, b=0},
|
||||
paramtype = "none",
|
||||
paramtype2 = "none",
|
||||
|
@ -42,5 +42,5 @@ core.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool
|
||||
return -- barely noticeable, so don't even send
|
||||
end
|
||||
|
||||
player:add_player_velocity(kdir)
|
||||
player:add_velocity(kdir)
|
||||
end)
|
||||
|
@ -1,5 +1,7 @@
|
||||
-- Minetest: builtin/misc.lua
|
||||
|
||||
local S = core.get_translator("__builtin")
|
||||
|
||||
--
|
||||
-- Misc. API functions
|
||||
--
|
||||
@ -42,15 +44,15 @@ end
|
||||
|
||||
function core.send_join_message(player_name)
|
||||
if not core.is_singleplayer() then
|
||||
core.chat_send_all("*** " .. player_name .. " joined the game.")
|
||||
core.chat_send_all("*** " .. S("@1 joined the game.", player_name))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function core.send_leave_message(player_name, timed_out)
|
||||
local announcement = "*** " .. player_name .. " left the game."
|
||||
local announcement = "*** " .. S("@1 left the game.", player_name)
|
||||
if timed_out then
|
||||
announcement = announcement .. " (timed out)"
|
||||
announcement = "*** " .. S("@1 left the game (timed out).", player_name)
|
||||
end
|
||||
core.chat_send_all(announcement)
|
||||
end
|
||||
@ -266,3 +268,26 @@ end
|
||||
function core.cancel_shutdown_requests()
|
||||
core.request_shutdown("", false, -1)
|
||||
end
|
||||
|
||||
|
||||
-- Callback handling for dynamic_add_media
|
||||
|
||||
local dynamic_add_media_raw = core.dynamic_add_media_raw
|
||||
core.dynamic_add_media_raw = nil
|
||||
function core.dynamic_add_media(filepath, callback)
|
||||
local ret = dynamic_add_media_raw(filepath)
|
||||
if ret == false then
|
||||
return ret
|
||||
end
|
||||
if callback == nil then
|
||||
core.log("deprecated", "Calling minetest.dynamic_add_media without "..
|
||||
"a callback is deprecated and will stop working in future versions.")
|
||||
else
|
||||
-- At the moment async loading is not actually implemented, so we
|
||||
-- immediately call the callback ourselves
|
||||
for _, name in ipairs(ret) do
|
||||
callback(name)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
@ -1,5 +1,7 @@
|
||||
-- Minetest: builtin/privileges.lua
|
||||
|
||||
local S = core.get_translator("__builtin")
|
||||
|
||||
--
|
||||
-- Privileges
|
||||
--
|
||||
@ -15,7 +17,7 @@ function core.register_privilege(name, param)
|
||||
def.give_to_admin = def.give_to_singleplayer
|
||||
end
|
||||
if def.description == nil then
|
||||
def.description = "(no description)"
|
||||
def.description = S("(no description)")
|
||||
end
|
||||
end
|
||||
local def
|
||||
@ -28,69 +30,75 @@ function core.register_privilege(name, param)
|
||||
core.registered_privileges[name] = def
|
||||
end
|
||||
|
||||
core.register_privilege("interact", "Can interact with things and modify the world")
|
||||
core.register_privilege("shout", "Can speak in chat")
|
||||
core.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
|
||||
core.register_privilege("privs", "Can modify privileges")
|
||||
core.register_privilege("interact", S("Can interact with things and modify the world"))
|
||||
core.register_privilege("shout", S("Can speak in chat"))
|
||||
|
||||
local basic_privs =
|
||||
core.string_to_privs((core.settings:get("basic_privs") or "shout,interact"))
|
||||
local basic_privs_desc = S("Can modify basic privileges (@1)",
|
||||
core.privs_to_string(basic_privs, ', '))
|
||||
core.register_privilege("basic_privs", basic_privs_desc)
|
||||
|
||||
core.register_privilege("privs", S("Can modify privileges"))
|
||||
|
||||
core.register_privilege("teleport", {
|
||||
description = "Can teleport self",
|
||||
description = S("Can teleport self"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("bring", {
|
||||
description = "Can teleport other players",
|
||||
description = S("Can teleport other players"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("settime", {
|
||||
description = "Can set the time of day using /time",
|
||||
description = S("Can set the time of day using /time"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("server", {
|
||||
description = "Can do server maintenance stuff",
|
||||
description = S("Can do server maintenance stuff"),
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = true,
|
||||
})
|
||||
core.register_privilege("protection_bypass", {
|
||||
description = "Can bypass node protection in the world",
|
||||
description = S("Can bypass node protection in the world"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("ban", {
|
||||
description = "Can ban and unban players",
|
||||
description = S("Can ban and unban players"),
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = true,
|
||||
})
|
||||
core.register_privilege("kick", {
|
||||
description = "Can kick players",
|
||||
description = S("Can kick players"),
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = true,
|
||||
})
|
||||
core.register_privilege("give", {
|
||||
description = "Can use /give and /giveme",
|
||||
description = S("Can use /give and /giveme"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("password", {
|
||||
description = "Can use /setpassword and /clearpassword",
|
||||
description = S("Can use /setpassword and /clearpassword"),
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = true,
|
||||
})
|
||||
core.register_privilege("fly", {
|
||||
description = "Can use fly mode",
|
||||
description = S("Can use fly mode"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("fast", {
|
||||
description = "Can use fast mode",
|
||||
description = S("Can use fast mode"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("noclip", {
|
||||
description = "Can fly through solid nodes using noclip mode",
|
||||
description = S("Can fly through solid nodes using noclip mode"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("rollback", {
|
||||
description = "Can use the rollback functionality",
|
||||
description = S("Can use the rollback functionality"),
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("debug", {
|
||||
description = "Allows enabling various debug options that may affect gameplay",
|
||||
description = S("Allows enabling various debug options that may affect gameplay"),
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = true,
|
||||
})
|
||||
|
@ -1,5 +1,7 @@
|
||||
-- Minetest: builtin/misc_register.lua
|
||||
|
||||
local S = core.get_translator("__builtin")
|
||||
|
||||
--
|
||||
-- Make raw registration functions inaccessible to anyone except this file
|
||||
--
|
||||
@ -118,10 +120,6 @@ function core.register_item(name, itemdef)
|
||||
end
|
||||
itemdef.name = name
|
||||
|
||||
-- default short_description to first line of description
|
||||
itemdef.short_description = itemdef.short_description or
|
||||
(itemdef.description or ""):gsub("\n.*","")
|
||||
|
||||
-- Apply defaults and add to registered_* table
|
||||
if itemdef.type == "node" then
|
||||
-- Use the nodebox as selection box if it's not set manually
|
||||
@ -324,20 +322,13 @@ for name in pairs(forbidden_item_names) do
|
||||
register_alias_raw(name, "")
|
||||
end
|
||||
|
||||
|
||||
-- Obsolete:
|
||||
-- Aliases for core.register_alias (how ironic...)
|
||||
-- core.alias_node = core.register_alias
|
||||
-- core.alias_tool = core.register_alias
|
||||
-- core.alias_craftitem = core.register_alias
|
||||
|
||||
--
|
||||
-- Built-in node definitions. Also defined in C.
|
||||
--
|
||||
|
||||
core.register_item(":unknown", {
|
||||
type = "none",
|
||||
description = "Unknown Item",
|
||||
description = S("Unknown Item"),
|
||||
inventory_image = "unknown_item.png",
|
||||
on_place = core.item_place,
|
||||
on_secondary_use = core.item_secondary_use,
|
||||
@ -347,7 +338,7 @@ core.register_item(":unknown", {
|
||||
})
|
||||
|
||||
core.register_node(":air", {
|
||||
description = "Air",
|
||||
description = S("Air"),
|
||||
inventory_image = "air.png",
|
||||
wield_image = "air.png",
|
||||
drawtype = "airlike",
|
||||
@ -364,7 +355,7 @@ core.register_node(":air", {
|
||||
})
|
||||
|
||||
core.register_node(":ignore", {
|
||||
description = "Ignore",
|
||||
description = S("Ignore"),
|
||||
inventory_image = "ignore.png",
|
||||
wield_image = "ignore.png",
|
||||
drawtype = "airlike",
|
||||
@ -377,11 +368,12 @@ core.register_node(":ignore", {
|
||||
air_equivalent = true,
|
||||
drop = "",
|
||||
groups = {not_in_creative_inventory=1},
|
||||
node_placement_prediction = "",
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
core.chat_send_player(
|
||||
placer:get_player_name(),
|
||||
core.colorize("#FF0000",
|
||||
"You can't place 'ignore' nodes!"))
|
||||
S("You can't place 'ignore' nodes!")))
|
||||
return ""
|
||||
end,
|
||||
})
|
||||
@ -617,6 +609,7 @@ core.registered_can_bypass_userlimit, core.register_can_bypass_userlimit = make_
|
||||
core.registered_on_modchannel_message, core.register_on_modchannel_message = make_registration()
|
||||
core.registered_on_player_inventory_actions, core.register_on_player_inventory_action = make_registration()
|
||||
core.registered_allow_player_inventory_actions, core.register_allow_player_inventory_action = make_registration()
|
||||
core.registered_on_rightclickplayers, core.register_on_rightclickplayer = make_registration()
|
||||
|
||||
--
|
||||
-- Compatibility for on_mapgen_init()
|
||||
|
@ -84,8 +84,8 @@ local function update_builtin_statbars(player)
|
||||
end
|
||||
|
||||
if hud.id_breathbar and (not show_breathbar or breath == breath_max) then
|
||||
minetest.after(1, function(player_name, breath_bar)
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
core.after(1, function(player_name, breath_bar)
|
||||
local player = core.get_player_by_name(player_name)
|
||||
if player then
|
||||
player:hud_remove(breath_bar)
|
||||
end
|
||||
|
@ -38,9 +38,20 @@ if INIT == "game" then
|
||||
dofile(gamepath .. "init.lua")
|
||||
elseif INIT == "mainmenu" then
|
||||
local mm_script = core.settings:get("main_menu_script")
|
||||
local custom_loaded = false
|
||||
if mm_script and mm_script ~= "" then
|
||||
dofile(mm_script)
|
||||
else
|
||||
local testfile = io.open(mm_script, "r")
|
||||
if testfile then
|
||||
testfile:close()
|
||||
dofile(mm_script)
|
||||
custom_loaded = true
|
||||
core.log("info", "Loaded custom main menu script: "..mm_script)
|
||||
else
|
||||
core.log("error", "Failed to load custom main menu script: "..mm_script)
|
||||
core.log("info", "Falling back to default main menu script")
|
||||
end
|
||||
end
|
||||
if not custom_loaded then
|
||||
dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
|
||||
end
|
||||
elseif INIT == "async" then
|
||||
|
240
builtin/locale/__builtin.de.tr
Normal file
@ -0,0 +1,240 @@
|
||||
# textdomain: __builtin
|
||||
Empty command.=Leerer Befehl.
|
||||
Invalid command: @1=Ungültiger Befehl: @1
|
||||
Invalid command usage.=Ungültige Befehlsverwendung.
|
||||
(@1 s)= (@1 s)
|
||||
Command execution took @1 s=Befehlsausführung brauchte @1 s
|
||||
You don't have permission to run this command (missing privileges: @1).=Sie haben keine Erlaubnis, diesen Befehl auszuführen (fehlende Privilegien: @1).
|
||||
Unable to get position of player @1.=Konnte Position vom Spieler @1 nicht ermitteln.
|
||||
Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Ungültiges Gebietsformat. Erwartet: (x1,y1,z1) (x2,y2,z2)
|
||||
<action>=<Aktion>
|
||||
Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Chataktion zeigen (z.B. wird „/me isst Pizza“ zu „<Spielername> isst Pizza“)
|
||||
Show the name of the server owner=Den Namen des Servereigentümers zeigen
|
||||
The administrator of this server is @1.=Der Administrator dieses Servers ist @1.
|
||||
There's no administrator named in the config file.=In der Konfigurationsdatei wurde kein Administrator angegeben.
|
||||
@1 does not have any privileges.=@1 hat keine Privilegien.
|
||||
Privileges of @1: @2=Privilegien von @1: @2
|
||||
[<name>]=[<Name>]
|
||||
Show privileges of yourself or another player=Ihre eigenen Privilegien oder die eines anderen Spielers anzeigen
|
||||
Player @1 does not exist.=Spieler @1 existiert nicht.
|
||||
<privilege>=<Privileg>
|
||||
Return list of all online players with privilege=Liste aller Spieler mit einem Privileg ausgeben
|
||||
Invalid parameters (see /help haspriv).=Ungültige Parameter (siehe „/help haspriv“).
|
||||
Unknown privilege!=Unbekanntes Privileg!
|
||||
Players online with the "@1" privilege: @2=Derzeit online spielende Spieler mit dem „@1“-Privileg: @2
|
||||
Your privileges are insufficient.=Ihre Privilegien sind unzureichend.
|
||||
Your privileges are insufficient. '@1' only allows you to grant: @2=Ihre Privilegien sind unzureichend. Mit „@1“ können Sie nur folgendes gewähren: @2
|
||||
Unknown privilege: @1=Unbekanntes Privileg: @1
|
||||
@1 granted you privileges: @2=@1 gewährte Ihnen Privilegien: @2
|
||||
<name> (<privilege> [, <privilege2> [<...>]] | all)=<Name> (<Privileg> [, <Privileg2> [<...>]] | all)
|
||||
Give privileges to player=Privileg an Spieler vergeben
|
||||
Invalid parameters (see /help grant).=Ungültige Parameter (siehe „/help grant“).
|
||||
<privilege> [, <privilege2> [<...>]] | all=<Privileg> [, <Privileg2> [<...>]] | all
|
||||
Grant privileges to yourself=Privilegien an Ihnen selbst vergeben
|
||||
Invalid parameters (see /help grantme).=Ungültige Parameter (siehe „/help grantme“).
|
||||
Your privileges are insufficient. '@1' only allows you to revoke: @2=Ihre Privilegien sind unzureichend. Mit „@1“ können Sie nur folgendes entziehen: @2
|
||||
Note: Cannot revoke in singleplayer: @1=Anmerkung: Im Einzelspielermodus kann man folgendes nicht entziehen: @1
|
||||
Note: Cannot revoke from admin: @1=Anmerkung: Vom Admin kann man folgendes nicht entziehen: @1
|
||||
No privileges were revoked.=Es wurden keine Privilegien entzogen.
|
||||
@1 revoked privileges from you: @2=@1 entfernte Privilegien von Ihnen: @2
|
||||
Remove privileges from player=Privilegien von Spieler entfernen
|
||||
Invalid parameters (see /help revoke).=Ungültige Parameter (siehe „/help revoke“).
|
||||
Revoke privileges from yourself=Privilegien von Ihnen selbst entfernen
|
||||
Invalid parameters (see /help revokeme).=Ungültige Parameter (siehe „/help revokeme“).
|
||||
<name> <password>=<Name> <Passwort>
|
||||
Set player's password=Passwort von Spieler setzen
|
||||
Name field required.=Namensfeld benötigt.
|
||||
Your password was cleared by @1.=Ihr Passwort wurde von @1 geleert.
|
||||
Password of player "@1" cleared.=Passwort von Spieler „@1“ geleert.
|
||||
Your password was set by @1.=Ihr Passwort wurde von @1 gesetzt.
|
||||
Password of player "@1" set.=Passwort von Spieler „@1“ gesetzt.
|
||||
<name>=<Name>
|
||||
Set empty password for a player=Leeres Passwort für einen Spieler setzen
|
||||
Reload authentication data=Authentifizierungsdaten erneut laden
|
||||
Done.=Fertig.
|
||||
Failed.=Fehlgeschlagen.
|
||||
Remove a player's data=Daten eines Spielers löschen
|
||||
Player "@1" removed.=Spieler „@1“ gelöscht.
|
||||
No such player "@1" to remove.=Es gibt keinen Spieler „@1“, der gelöscht werden könnte.
|
||||
Player "@1" is connected, cannot remove.=Spieler „@1“ ist verbunden, er kann nicht gelöscht werden.
|
||||
Unhandled remove_player return code @1.=Nicht berücksichtigter remove_player-Rückgabewert @1.
|
||||
Cannot teleport out of map bounds!=Eine Teleportation außerhalb der Kartengrenzen ist nicht möglich!
|
||||
Cannot get player with name @1.=Spieler mit Namen @1 kann nicht gefunden werden.
|
||||
Cannot teleport, @1 is attached to an object!=Teleportation nicht möglich, @1 ist an einem Objekt befestigt!
|
||||
Teleporting @1 to @2.=Teleportation von @1 nach @2
|
||||
One does not teleport to oneself.=Man teleportiert sich doch nicht zu sich selbst.
|
||||
Cannot get teleportee with name @1.=Der zu teleportierende Spieler mit Namen @1 kann nicht gefunden werden.
|
||||
Cannot get target player with name @1.=Zielspieler mit Namen @1 kann nicht gefunden werden.
|
||||
Teleporting @1 to @2 at @3.=Teleportation von @1 zu @2 bei @3
|
||||
<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>,<Y>,<Z> | <zu_Name> | <Name> <X>,<Y>,<Z> | <Name> <zu_Name>
|
||||
Teleport to position or player=Zu Position oder Spieler teleportieren
|
||||
You don't have permission to teleport other players (missing privilege: @1).=Sie haben nicht die Erlaubnis, andere Spieler zu teleportieren (fehlendes Privileg: @1).
|
||||
([-n] <name> <value>) | <name>=([-n] <Name> <Wert>) | <Name>
|
||||
Set or read server configuration setting=Serverkonfigurationseinstellung setzen oder lesen
|
||||
Failed. Use '/set -n <name> <value>' to create a new setting.=Fehlgeschlagen. Benutzen Sie „/set -n <Name> <Wert>“, um eine neue Einstellung zu erstellen.
|
||||
@1 @= @2=@1 @= @2
|
||||
<not set>=<nicht gesetzt>
|
||||
Invalid parameters (see /help set).=Ungültige Parameter (siehe „/help set“).
|
||||
Finished emerging @1 blocks in @2ms.=Fertig mit Erzeugung von @1 Blöcken in @2 ms.
|
||||
emergeblocks update: @1/@2 blocks emerged (@3%)=emergeblocks-Update: @1/@2 Kartenblöcke geladen (@3%)
|
||||
(here [<radius>]) | (<pos1> <pos2>)=(here [<Radius>]) | (<Pos1> <Pos2>)
|
||||
Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Lade (oder, wenn nicht existent, generiere) Kartenblöcke im Gebiet zwischen Pos1 und Pos2 (<Pos1> und <Pos2> müssen in Klammern stehen)
|
||||
Started emerge of area ranging from @1 to @2.=Start des Ladevorgangs des Gebiets zwischen @1 und @2.
|
||||
Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Kartenblöcke innerhalb des Gebiets zwischen Pos1 und Pos2 löschen (<Pos1> und <Pos2> müssen in Klammern stehen)
|
||||
Successfully cleared area ranging from @1 to @2.=Gebiet zwischen @1 und @2 erfolgreich geleert.
|
||||
Failed to clear one or more blocks in area.=Fehlgeschlagen: Ein oder mehrere Kartenblöcke im Gebiet konnten nicht geleert werden.
|
||||
Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)=Setzt das Licht im Gebiet zwischen Pos1 und Pos2 zurück (<Pos1> und <Pos2> müssen in Klammern stehen)
|
||||
Successfully reset light in the area ranging from @1 to @2.=Das Licht im Gebiet zwischen @1 und @2 wurde erfolgreich zurückgesetzt.
|
||||
Failed to load one or more blocks in area.=Fehlgeschlagen: Ein oder mehrere Kartenblöcke im Gebiet konnten nicht geladen werden.
|
||||
List mods installed on the server=Installierte Mods auf dem Server auflisten
|
||||
Cannot give an empty item.=Ein leerer Gegenstand kann nicht gegeben werden.
|
||||
Cannot give an unknown item.=Ein unbekannter Gegenstand kann nicht gegeben werden.
|
||||
Giving 'ignore' is not allowed.=„ignore“ darf nicht gegeben werden.
|
||||
@1 is not a known player.=@1 ist kein bekannter Spieler.
|
||||
@1 partially added to inventory.=@1 teilweise ins Inventar eingefügt.
|
||||
@1 could not be added to inventory.=@1 konnte nicht ins Inventar eingefügt werden.
|
||||
@1 added to inventory.=@1 zum Inventar hinzugefügt.
|
||||
@1 partially added to inventory of @2.=@1 teilweise ins Inventar von @2 eingefügt.
|
||||
@1 could not be added to inventory of @2.=@1 konnte nicht ins Inventar von @2 eingefügt werden.
|
||||
@1 added to inventory of @2.=@1 ins Inventar von @2 eingefügt.
|
||||
<name> <ItemString> [<count> [<wear>]]=<Name> <ItemString> [<Anzahl> [<Abnutzung>]]
|
||||
Give item to player=Gegenstand an Spieler geben
|
||||
Name and ItemString required.=Name und ItemString benötigt.
|
||||
<ItemString> [<count> [<wear>]]=<ItemString> [<Anzahl> [<Abnutzung>]]
|
||||
Give item to yourself=Gegenstand Ihnen selbst geben
|
||||
ItemString required.=ItemString benötigt.
|
||||
<EntityName> [<X>,<Y>,<Z>]=<EntityName> [<X>,<Y>,<Z>]
|
||||
Spawn entity at given (or your) position=Entity an angegebener (oder Ihrer eigenen) Position spawnen
|
||||
EntityName required.=EntityName benötigt.
|
||||
Unable to spawn entity, player is nil.=Entity konnte nicht gespawnt werden, Spieler ist nil.
|
||||
Cannot spawn an unknown entity.=Ein unbekanntes Entity kann nicht gespawnt werden.
|
||||
Invalid parameters (@1).=Ungültige Parameter (@1).
|
||||
@1 spawned.=@1 gespawnt.
|
||||
@1 failed to spawn.=@1 konnte nicht gespawnt werden.
|
||||
Destroy item in hand=Gegenstand in der Hand zerstören
|
||||
Unable to pulverize, no player.=Konnte nicht pulverisieren, kein Spieler.
|
||||
Unable to pulverize, no item in hand.=Konnte nicht pulverisieren, kein Gegenstand in der Hand.
|
||||
An item was pulverized.=Ein Gegenstand wurde pulverisiert.
|
||||
[<range>] [<seconds>] [<limit>]=[<Reichweite>] [<Sekunden>] [<Limit>]
|
||||
Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Überprüfen, wer als letztes einen Node oder einen Node in der Nähe innerhalb der in <Sekunden> angegebenen Zeitspanne angefasst hat. Standard: Reichweite @= 0, Sekunden @= 86400 @= 24h, Limit @= 5. <Sekunden> auf „inf“ setzen, um Zeitlimit zu deaktivieren.
|
||||
Rollback functions are disabled.=Rollback-Funktionen sind deaktiviert.
|
||||
That limit is too high!=Dieses Limit ist zu hoch!
|
||||
Checking @1 ...=Überprüfe @1 ...
|
||||
Nobody has touched the specified location in @1 seconds.=Niemand hat die angegebene Position seit @1 Sekunden angefasst.
|
||||
@1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 vor @5 Sekunden.
|
||||
Punch a node (range@=@1, seconds@=@2, limit@=@3).=Hauen Sie einen Node (Reichweite@=@1, Sekunden@=@2, Limit@=@3).
|
||||
(<name> [<seconds>]) | (:<actor> [<seconds>])=(<Name> [<Sekunden>]) | (:<Akteur> [<Sekunden>])
|
||||
Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Aktionen eines Spielers zurückrollen. Standard für <Sekunden> ist 60. <Sekunden> auf „inf“ setzen, um Zeitlimit zu deaktivieren
|
||||
Invalid parameters. See /help rollback and /help rollback_check.=Ungültige Parameter. Siehe /help rollback und /help rollback_check.
|
||||
Reverting actions of player '@1' since @2 seconds.=Die Aktionen des Spielers „@1“ seit @2 Sekunden werden rückgängig gemacht.
|
||||
Reverting actions of @1 since @2 seconds.=Die Aktionen von @1 seit @2 Sekunden werden rückgängig gemacht.
|
||||
(log is too long to show)=(Protokoll ist zu lang für die Anzeige)
|
||||
Reverting actions succeeded.=Die Aktionen wurden erfolgreich rückgängig gemacht.
|
||||
Reverting actions FAILED.=FEHLGESCHLAGEN: Die Aktionen konnten nicht rückgängig gemacht werden.
|
||||
Show server status=Serverstatus anzeigen
|
||||
This command was disabled by a mod or game.=Dieser Befehl wurde von einer Mod oder einem Spiel deaktiviert.
|
||||
[<0..23>:<0..59> | <0..24000>]=[<0..23>:<0..59> | <0..24000>]
|
||||
Show or set time of day=Tageszeit anzeigen oder setzen
|
||||
Current time is @1:@2.=Es ist jetzt @1:@2 Uhr.
|
||||
You don't have permission to run this command (missing privilege: @1).=Sie haben nicht die Erlaubnis, diesen Befehl auszuführen (fehlendes Privileg: @1).
|
||||
Invalid time.=Ungültige Zeit.
|
||||
Time of day changed.=Tageszeit geändert.
|
||||
Invalid hour (must be between 0 and 23 inclusive).=Ungültige Stunde (muss zwischen 0 und 23 inklusive liegen).
|
||||
Invalid minute (must be between 0 and 59 inclusive).=Ungültige Minute (muss zwischen 0 und 59 inklusive liegen).
|
||||
Show day count since world creation=Anzahl Tage seit der Erschaffung der Welt anzeigen
|
||||
Current day is @1.=Aktueller Tag ist @1.
|
||||
[<delay_in_seconds> | -1] [reconnect] [<message>]=[<Verzögerung_in_Sekunden> | -1] [reconnect] [<Nachricht>]
|
||||
Shutdown server (-1 cancels a delayed shutdown)=Server herunterfahren (-1 bricht einen verzögerten Abschaltvorgang ab)
|
||||
Server shutting down (operator request).=Server wird heruntergefahren (Betreiberanfrage).
|
||||
Ban the IP of a player or show the ban list=Die IP eines Spielers verbannen oder die Bannliste anzeigen
|
||||
The ban list is empty.=Die Bannliste ist leer.
|
||||
Ban list: @1=Bannliste: @1
|
||||
Player is not online.=Spieler ist nicht online.
|
||||
Failed to ban player.=Konnte Spieler nicht verbannen.
|
||||
Banned @1.=@1 verbannt.
|
||||
<name> | <IP_address>=<Name> | <IP_Adresse>
|
||||
Remove IP ban belonging to a player/IP=Einen IP-Bann auf einen Spieler zurücknehmen
|
||||
Failed to unban player/IP.=Konnte Bann auf Spieler/IP nicht zurücknehmen.
|
||||
Unbanned @1.=Bann auf @1 zurückgenommen.
|
||||
<name> [<reason>]=<Name> [<Grund>]
|
||||
Kick a player=Spieler hinauswerfen
|
||||
Failed to kick player @1.=Spieler @1 konnte nicht hinausgeworfen werden.
|
||||
Kicked @1.=@1 hinausgeworfen.
|
||||
[full | quick]=[full | quick]
|
||||
Clear all objects in world=Alle Objekte in der Welt löschen
|
||||
Invalid usage, see /help clearobjects.=Ungültige Verwendung, siehe /help clearobjects.
|
||||
Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Lösche alle Objekte. Dies kann eine lange Zeit dauern. Eine Netzwerkzeitüberschreitung könnte für Sie auftreten. (von @1)
|
||||
Cleared all objects.=Alle Objekte gelöscht.
|
||||
<name> <message>=<Name> <Nachricht>
|
||||
Send a direct message to a player=Eine Direktnachricht an einen Spieler senden
|
||||
Invalid usage, see /help msg.=Ungültige Verwendung, siehe /help msg.
|
||||
The player @1 is not online.=Der Spieler @1 ist nicht online.
|
||||
DM from @1: @2=DN von @1: @2
|
||||
Message sent.=Nachricht gesendet.
|
||||
Get the last login time of a player or yourself=Den letzten Loginzeitpunkt eines Spielers oder Ihren eigenen anfragen
|
||||
@1's last login time was @2.=Letzter Loginzeitpunkt von @1 war @2.
|
||||
@1's last login time is unknown.=Letzter Loginzeitpunkt von @1 ist unbekannt.
|
||||
Clear the inventory of yourself or another player=Das Inventar von Ihnen oder einem anderen Spieler leeren
|
||||
You don't have permission to clear another player's inventory (missing privilege: @1).=Sie haben nicht die Erlaubnis, das Inventar eines anderen Spielers zu leeren (fehlendes Privileg: @1).
|
||||
@1 cleared your inventory.=@1 hat Ihr Inventar geleert.
|
||||
Cleared @1's inventory.=Inventar von @1 geleert.
|
||||
Player must be online to clear inventory!=Spieler muss online sein, um das Inventar leeren zu können!
|
||||
Players can't be killed, damage has been disabled.=Spieler können nicht getötet werden, Schaden ist deaktiviert.
|
||||
Player @1 is not online.=Spieler @1 ist nicht online.
|
||||
You are already dead.=Sie sind schon tot.
|
||||
@1 is already dead.=@1 ist bereits tot.
|
||||
@1 has been killed.=@1 wurde getötet.
|
||||
Kill player or yourself=Einen Spieler oder Sie selbst töten
|
||||
Available commands: @1=Verfügbare Befehle: @1
|
||||
Use '/help <cmd>' to get more information, or '/help all' to list everything.=„/help <Befehl>“ benutzen, um mehr Informationen zu erhalten, oder „/help all“, um alles aufzulisten.
|
||||
Available commands:=Verfügbare Befehle:
|
||||
Command not available: @1=Befehl nicht verfügbar: @1
|
||||
[all | privs | <cmd>]=[all | privs | <Befehl>]
|
||||
Get help for commands or list privileges=Hilfe für Befehle erhalten oder Privilegien auflisten
|
||||
Command=Befehl
|
||||
Parameters=Parameter
|
||||
For more information, click on any entry in the list.=Für mehr Informationen klicken Sie auf einen beliebigen Eintrag in der Liste.
|
||||
Double-click to copy the entry to the chat history.=Doppelklicken, um den Eintrag in die Chathistorie einzufügen.
|
||||
Command: @1 @2=Befehl: @1 @2
|
||||
Available commands: (see also: /help <cmd>)=Verfügbare Befehle: (siehe auch: /help <Befehl>)
|
||||
Close=Schließen
|
||||
Privilege=Privileg
|
||||
Description=Beschreibung
|
||||
Available privileges:=Verfügbare Privilegien:
|
||||
print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<Filter>] | dump [<Filter>] | save [<Format> [<Filter>]]
|
||||
Handle the profiler and profiling data=Den Profiler und Profilingdaten verwalten
|
||||
Statistics written to action log.=Statistiken zum Aktionsprotokoll geschrieben.
|
||||
Statistics were reset.=Statistiken wurden zurückgesetzt.
|
||||
Usage: @1=Verwendung: @1
|
||||
Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=Format kann entweder „txt“, „csv“, „lua“, „json“ oder „json_pretty“ sein (die Struktur kann sich in Zukunft ändern).
|
||||
@1 joined the game.=@1 ist dem Spiel beigetreten.
|
||||
@1 left the game.=@1 hat das Spiel verlassen.
|
||||
@1 left the game (timed out).=@1 hat das Spiel verlassen (Netzwerkzeitüberschreitung).
|
||||
(no description)=(keine Beschreibung)
|
||||
Can interact with things and modify the world=Kann mit Dingen interagieren und die Welt verändern
|
||||
Can speak in chat=Kann im Chat sprechen
|
||||
Can modify basic privileges (@1)=Kann grundlegende Privilegien anpassen (@1)
|
||||
Can modify privileges=Kann Privilegien anpassen
|
||||
Can teleport self=Kann sich selbst teleportieren
|
||||
Can teleport other players=Kann andere Spieler teleportieren
|
||||
Can set the time of day using /time=Kann die Tageszeit mit /time setzen
|
||||
Can do server maintenance stuff=Kann Serverwartungsdinge machen
|
||||
Can bypass node protection in the world=Kann den Schutz auf Blöcken in der Welt umgehen
|
||||
Can ban and unban players=Kann Spieler verbannen und entbannen
|
||||
Can kick players=Kann Spieler hinauswerfen
|
||||
Can use /give and /giveme=Kann /give und /giveme benutzen
|
||||
Can use /setpassword and /clearpassword=Kann /setpassword und /clearpassword benutzen
|
||||
Can use fly mode=Kann den Flugmodus benutzen
|
||||
Can use fast mode=Kann den Schnellmodus benutzen
|
||||
Can fly through solid nodes using noclip mode=Kann durch feste Blöcke mit dem Geistmodus fliegen
|
||||
Can use the rollback functionality=Kann die Rollback-Funktionalität benutzen
|
||||
Allows enabling various debug options that may affect gameplay=Erlaubt die Aktivierung diverser Debugoptionen, die das Spielgeschehen beeinflussen könnten
|
||||
Unknown Item=Unbekannter Gegenstand
|
||||
Air=Luft
|
||||
Ignore=Ignorieren
|
||||
You can't place 'ignore' nodes!=Sie können keine „ignore“-Blöcke platzieren!
|
||||
Values below show absolute/relative times spend per server step by the instrumented function.=Die unten angegebenen Werte zeigen absolute/relative Zeitspannen, die je Server-Step von der instrumentierten Funktion in Anspruch genommen wurden.
|
||||
A total of @1 sample(s) were taken.=Es wurden insgesamt @1 Datenpunkt(e) aufgezeichnet.
|
||||
The output is limited to '@1'.=Die Ausgabe ist beschränkt auf „@1“.
|
||||
Saving of profile failed: @1=Speichern des Profils fehlgeschlagen: @1
|
||||
Profile saved to @1=Profil abgespeichert nach @1
|
247
builtin/locale/__builtin.it.tr
Normal file
@ -0,0 +1,247 @@
|
||||
# textdomain: __builtin
|
||||
Empty command.=Comando vuoto.
|
||||
Invalid command: @1=Comando non valido: @1
|
||||
Invalid command usage.=Utilizzo del comando non valido.
|
||||
(@1 s)=
|
||||
Command execution took @1 s=
|
||||
You don't have permission to run this command (missing privileges: @1).=Non hai il permesso di eseguire questo comando (privilegi mancanti: @1).
|
||||
Unable to get position of player @1.=Impossibile ottenere la posizione del giocatore @1.
|
||||
Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Formato dell'area non corretto. Richiesto: (x1,y1,z1) (x2,y2,z2)
|
||||
<action>=<azione>
|
||||
Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Mostra un'azione in chat (es. `/me ordina una pizza` mostra `<nome giocatore> ordina una pizza`)
|
||||
Show the name of the server owner=Mostra il nome del proprietario del server
|
||||
The administrator of this server is @1.=L'amministratore di questo server è @1.
|
||||
There's no administrator named in the config file.=Non c'è nessun amministratore nel file di configurazione.
|
||||
@1 does not have any privileges.=
|
||||
Privileges of @1: @2=Privilegi di @1: @2
|
||||
[<name>]=[<nome>]
|
||||
Show privileges of yourself or another player=Mostra i privilegi propri o di un altro giocatore
|
||||
Player @1 does not exist.=Il giocatore @1 non esiste.
|
||||
<privilege>=<privilegio>
|
||||
Return list of all online players with privilege=Ritorna una lista di tutti i giocatori connessi col tale privilegio
|
||||
Invalid parameters (see /help haspriv).=Parametri non validi (vedi /help haspriv).
|
||||
Unknown privilege!=Privilegio sconosciuto!
|
||||
Players online with the "@1" privilege: @2=Giocatori connessi con il privilegio "@1": @2
|
||||
Your privileges are insufficient.=I tuoi privilegi sono insufficienti.
|
||||
Your privileges are insufficient. '@1' only allows you to grant: @2=
|
||||
Unknown privilege: @1=Privilegio sconosciuto: @1
|
||||
@1 granted you privileges: @2=@1 ti ha assegnato i seguenti privilegi: @2
|
||||
<name> (<privilege> [, <privilege2> [<...>]] | all)=
|
||||
Give privileges to player=Dà privilegi al giocatore
|
||||
Invalid parameters (see /help grant).=Parametri non validi (vedi /help grant).
|
||||
<privilege> [, <privilege2> [<...>]] | all=
|
||||
Grant privileges to yourself=Assegna dei privilegi a te stessǝ
|
||||
Invalid parameters (see /help grantme).=Parametri non validi (vedi /help grantme).
|
||||
Your privileges are insufficient. '@1' only allows you to revoke: @2=
|
||||
Note: Cannot revoke in singleplayer: @1=
|
||||
Note: Cannot revoke from admin: @1=
|
||||
No privileges were revoked.=
|
||||
@1 revoked privileges from you: @2=@1 ti ha revocato i seguenti privilegi: @2
|
||||
Remove privileges from player=Rimuove privilegi dal giocatore
|
||||
Invalid parameters (see /help revoke).=Parametri non validi (vedi /help revoke).
|
||||
Revoke privileges from yourself=Revoca privilegi a te stessǝ
|
||||
Invalid parameters (see /help revokeme).=Parametri non validi (vedi /help revokeme).
|
||||
<name> <password>=<nome> <password>
|
||||
Set player's password=Imposta la password del giocatore
|
||||
Name field required.=Campo "nome" richiesto.
|
||||
Your password was cleared by @1.=La tua password è stata resettata da @1.
|
||||
Password of player "@1" cleared.=Password del giocatore "@1" resettata.
|
||||
Your password was set by @1.=La tua password è stata impostata da @1.
|
||||
Password of player "@1" set.=Password del giocatore "@1" impostata.
|
||||
<name>=<nome>
|
||||
Set empty password for a player=Imposta una password vuota a un giocatore
|
||||
Reload authentication data=Ricarica i dati d'autenticazione
|
||||
Done.=Fatto.
|
||||
Failed.=Errore.
|
||||
Remove a player's data=Rimuove i dati di un giocatore
|
||||
Player "@1" removed.=Giocatore "@1" rimosso.
|
||||
No such player "@1" to remove.=Non è presente nessun giocatore "@1" da rimuovere.
|
||||
Player "@1" is connected, cannot remove.=Il giocatore "@1" è connesso, non può essere rimosso.
|
||||
Unhandled remove_player return code @1.=Codice ritornato da remove_player non gestito (@1).
|
||||
Cannot teleport out of map bounds!=Non ci si può teletrasportare fuori dai limiti della mappa!
|
||||
Cannot get player with name @1.=Impossibile trovare il giocatore chiamato @1.
|
||||
Cannot teleport, @1 is attached to an object!=Impossibile teletrasportare, @1 è attaccato a un oggetto!
|
||||
Teleporting @1 to @2.=Teletrasportando @1 da @2.
|
||||
One does not teleport to oneself.=Non ci si può teletrasportare su se stessi.
|
||||
Cannot get teleportee with name @1.=Impossibile trovare il giocatore chiamato @1 per il teletrasporto
|
||||
Cannot get target player with name @1.=Impossibile trovare il giocatore chiamato @1 per il teletrasporto
|
||||
Teleporting @1 to @2 at @3.=Teletrasportando @1 da @2 a @3
|
||||
<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>,<Y>,<Z> | <da_nome> | <nome> <X>,<Y>,<Z> | <nome> <da_nome>
|
||||
Teleport to position or player=Teletrasporta a una posizione o da un giocatore
|
||||
You don't have permission to teleport other players (missing privilege: @1).=Non hai il permesso di teletrasportare altri giocatori (privilegio mancante: @1).
|
||||
([-n] <name> <value>) | <name>=([-n] <nome> <valore>) | <nome>
|
||||
Set or read server configuration setting=Imposta o ottieni le configurazioni del server
|
||||
Failed. Use '/set -n <name> <value>' to create a new setting.=Errore. Usa 'set -n <nome> <valore>' per creare una nuova impostazione
|
||||
@1 @= @2=@1 @= @2
|
||||
<not set>=<non impostato>
|
||||
Invalid parameters (see /help set).=Parametri non validi (vedi /help set).
|
||||
Finished emerging @1 blocks in @2ms.=Finito di emergere @1 blocchi in @2ms
|
||||
emergeblocks update: @1/@2 blocks emerged (@3%)=aggiornamento emergeblocks: @1/@2 blocchi emersi (@3%)
|
||||
(here [<radius>]) | (<pos1> <pos2>)=(here [<raggio>]) | (<pos1> <pos2>)
|
||||
Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Carica (o, se non esiste, genera) blocchi mappa contenuti nell'area tra pos1 e pos2 (<pos1> e <pos2> vanno tra parentesi)
|
||||
Started emerge of area ranging from @1 to @2.=Iniziata emersione dell'area tra @1 e @2.
|
||||
Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Cancella i blocchi mappa contenuti nell'area tra pos1 e pos2 (<pos1> e <pos2> vanno tra parentesi)
|
||||
Successfully cleared area ranging from @1 to @2.=Area tra @1 e @2 ripulita con successo.
|
||||
Failed to clear one or more blocks in area.=Errore nel ripulire uno o più blocchi mappa nell'area
|
||||
Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)=Reimposta l'illuminazione nell'area tra pos1 e po2 (<pos1> e <pos2> vanno tra parentesi)
|
||||
Successfully reset light in the area ranging from @1 to @2.=Luce nell'area tra @1 e @2 reimpostata con successo.
|
||||
Failed to load one or more blocks in area.=Errore nel caricare uno o più blocchi mappa nell'area.
|
||||
List mods installed on the server=Elenca le mod installate nel server
|
||||
Cannot give an empty item.=Impossibile dare un oggetto vuoto.
|
||||
Cannot give an unknown item.=Impossibile dare un oggetto sconosciuto.
|
||||
Giving 'ignore' is not allowed.=Non è permesso dare 'ignore'.
|
||||
@1 is not a known player.=@1 non è un giocatore conosciuto.
|
||||
@1 partially added to inventory.=@1 parzialmente aggiunto all'inventario.
|
||||
@1 could not be added to inventory.=@1 non può essere aggiunto all'inventario.
|
||||
@1 added to inventory.=@1 aggiunto all'inventario.
|
||||
@1 partially added to inventory of @2.=@1 parzialmente aggiunto all'inventario di @2.
|
||||
@1 could not be added to inventory of @2.=Non è stato possibile aggiungere @1 all'inventario di @2.
|
||||
@1 added to inventory of @2.=@1 aggiunto all'inventario di @2.
|
||||
<name> <ItemString> [<count> [<wear>]]=<nome> <NomeOggetto> [<quantità> [<usura>]]
|
||||
Give item to player=Dà oggetti ai giocatori
|
||||
Name and ItemString required.=Richiesti nome e NomeOggetto.
|
||||
<ItemString> [<count> [<wear>]]=<NomeOggetto> [<quantità> [<usura>]]
|
||||
Give item to yourself=Dà oggetti a te stessǝ
|
||||
ItemString required.=Richiesto NomeOggetto.
|
||||
<EntityName> [<X>,<Y>,<Z>]=<NomeEntità> [<X>,<Y>,<Z>]
|
||||
Spawn entity at given (or your) position=Genera un'entità alla data coordinata (o la tua)
|
||||
EntityName required.=Richiesto NomeEntità
|
||||
Unable to spawn entity, player is nil.=Impossibile generare l'entità, il giocatore è nil.
|
||||
Cannot spawn an unknown entity.=Impossibile generare un'entità sconosciuta.
|
||||
Invalid parameters (@1).=Parametri non validi (@1).
|
||||
@1 spawned.=Generata entità @1.
|
||||
@1 failed to spawn.=Errore nel generare @1
|
||||
Destroy item in hand=Distrugge l'oggetto in mano
|
||||
Unable to pulverize, no player.=Impossibile polverizzare, nessun giocatore.
|
||||
Unable to pulverize, no item in hand.=Impossibile polverizzare, nessun oggetto in mano.
|
||||
An item was pulverized.=Un oggetto è stato polverizzato.
|
||||
[<range>] [<seconds>] [<limit>]=[<raggio>] [<secondi>] [<limite>]
|
||||
Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Controlla chi è l'ultimo giocatore che ha toccato un nodo o un nodo nelle sue vicinanze, negli ultimi secondi indicati. Di base: raggio @= 0, secondi @= 86400 @= 24h, limite @= 5.
|
||||
Rollback functions are disabled.=Le funzioni di rollback sono disabilitate.
|
||||
That limit is too high!=Il limite è troppo alto!
|
||||
Checking @1 ...=Controllando @1 ...
|
||||
Nobody has touched the specified location in @1 seconds.=Nessuno ha toccato il punto specificato negli ultimi @1 secondi.
|
||||
@1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 @5 secondi fa.
|
||||
Punch a node (range@=@1, seconds@=@2, limit@=@3).=Colpisce un nodo (raggio@=@1, secondi@=@2, limite@=@3)
|
||||
(<name> [<seconds>]) | (:<actor> [<seconds>])=(<nome> [<secondi>]) | (:<attore> [<secondi>])
|
||||
Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Riavvolge le azioni di un giocatore. Di base, <secondi> è 60. Imposta <secondi> a inf per nessun limite di tempo
|
||||
Invalid parameters. See /help rollback and /help rollback_check.=Parametri non validi. Vedi /help rollback e /help rollback_check.
|
||||
Reverting actions of player '@1' since @2 seconds.=Riavvolge le azioni del giocatore '@1' avvenute negli ultimi @2 secondi.
|
||||
Reverting actions of @1 since @2 seconds.=Riavvolge le azioni di @1 avvenute negli ultimi @2 secondi.
|
||||
(log is too long to show)=(il log è troppo lungo per essere mostrato)
|
||||
Reverting actions succeeded.=Riavvolgimento azioni avvenuto con successo.
|
||||
Reverting actions FAILED.=Errore nel riavvolgere le azioni.
|
||||
Show server status=Mostra lo stato del server
|
||||
This command was disabled by a mod or game.=Questo comando è stato disabilitato da una mod o dal gioco.
|
||||
[<0..23>:<0..59> | <0..24000>]=[<0..23>:<0..59> | <0..24000>]
|
||||
Show or set time of day=Mostra o imposta l'orario della giornata
|
||||
Current time is @1:@2.=Orario corrente: @1:@2.
|
||||
You don't have permission to run this command (missing privilege: @1).=Non hai il permesso di eseguire questo comando (privilegio mancante: @1)
|
||||
Invalid time.=Orario non valido.
|
||||
Time of day changed.=Orario della giornata cambiato.
|
||||
Invalid hour (must be between 0 and 23 inclusive).=Ora non valida (deve essere tra 0 e 23 inclusi)
|
||||
Invalid minute (must be between 0 and 59 inclusive).=Minuto non valido (deve essere tra 0 e 59 inclusi)
|
||||
Show day count since world creation=Mostra il conteggio dei giorni da quando il mondo è stato creato
|
||||
Current day is @1.=Giorno attuale: @1.
|
||||
[<delay_in_seconds> | -1] [reconnect] [<message>]=[<ritardo_in_secondi> | -1] [reconnect] [<messaggio>]
|
||||
Shutdown server (-1 cancels a delayed shutdown)=Arresta il server (-1 annulla un arresto programmato)
|
||||
Server shutting down (operator request).=Arresto del server in corso (per richiesta dell'operatore)
|
||||
Ban the IP of a player or show the ban list=Bandisce l'IP del giocatore o mostra la lista di quelli banditi
|
||||
The ban list is empty.=La lista banditi è vuota.
|
||||
Ban list: @1=Lista banditi: @1
|
||||
Player is not online.=Il giocatore non è connesso.
|
||||
Failed to ban player.=Errore nel bandire il giocatore.
|
||||
Banned @1.=@1 banditǝ.
|
||||
<name> | <IP_address>=<nome> | <indirizzo_IP>
|
||||
Remove IP ban belonging to a player/IP=Perdona l'IP appartenente a un giocatore/IP
|
||||
Failed to unban player/IP.=Errore nel perdonare il giocatore/IP
|
||||
Unbanned @1.=@1 perdonatǝ
|
||||
<name> [<reason>]=<nome> [<ragione>]
|
||||
Kick a player=Caccia un giocatore
|
||||
Failed to kick player @1.=Errore nel cacciare il giocatore @1.
|
||||
Kicked @1.=@1 cacciatǝ.
|
||||
[full | quick]=[full | quick]
|
||||
Clear all objects in world=Elimina tutti gli oggetti/entità nel mondo
|
||||
Invalid usage, see /help clearobjects.=Uso incorretto, vedi /help clearobjects.
|
||||
Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Eliminando tutti gli oggetti/entità. Questo potrebbe richiedere molto tempo e farti eventualmente crashare. (di @1)
|
||||
Cleared all objects.=Tutti gli oggetti sono stati eliminati.
|
||||
<name> <message>=<nome> <messaggio>
|
||||
Send a direct message to a player=Invia un messaggio privato al giocatore
|
||||
Invalid usage, see /help msg.=Uso incorretto, vedi /help msg
|
||||
The player @1 is not online.=Il giocatore @1 non è connesso.
|
||||
DM from @1: @2=Messaggio privato da @1: @2
|
||||
Message sent.=Messaggio inviato.
|
||||
Get the last login time of a player or yourself=Ritorna l'ultimo accesso di un giocatore o di te stessǝ
|
||||
@1's last login time was @2.=L'ultimo accesso di @1 è avvenuto il @2
|
||||
@1's last login time is unknown.=L'ultimo accesso di @1 non è conosciuto
|
||||
Clear the inventory of yourself or another player=Svuota l'inventario tuo o di un altro giocatore
|
||||
You don't have permission to clear another player's inventory (missing privilege: @1).=Non hai il permesso di svuotare l'inventario di un altro giocatore (privilegio mancante: @1).
|
||||
@1 cleared your inventory.=@1 ha svuotato il tuo inventario.
|
||||
Cleared @1's inventory.=L'inventario di @1 è stato svuotato.
|
||||
Player must be online to clear inventory!=Il giocatore deve essere connesso per svuotarne l'inventario!
|
||||
Players can't be killed, damage has been disabled.=I giocatori non possono essere uccisi, il danno è disabilitato.
|
||||
Player @1 is not online.=Il giocatore @1 non è connesso.
|
||||
You are already dead.=Sei già mortǝ.
|
||||
@1 is already dead.=@1 è già mortǝ.
|
||||
@1 has been killed.=@1 è stato uccisǝ.
|
||||
Kill player or yourself=Uccide un giocatore o te stessǝ
|
||||
Available commands: @1=Comandi disponibili: @1
|
||||
Use '/help <cmd>' to get more information, or '/help all' to list everything.=Usa '/help <comando>' per ottenere più informazioni, o '/help all' per elencare tutti i comandi.
|
||||
Available commands:=Comandi disponibili:
|
||||
Command not available: @1=Comando non disponibile: @1
|
||||
[all | privs | <cmd>]=[all | privs | <comando>]
|
||||
Get help for commands or list privileges=Richiama la finestra d'aiuto dei comandi o dei privilegi
|
||||
Command=Comando
|
||||
Parameters=Parametri
|
||||
For more information, click on any entry in the list.=Per più informazioni, clicca su una qualsiasi voce dell'elenco.
|
||||
Double-click to copy the entry to the chat history.=Doppio click per copiare la voce nella cronologia della chat.
|
||||
Command: @1 @2=Comando: @1 @2
|
||||
Available commands: (see also: /help <cmd>)=Comandi disponibili: (vedi anche /help <comando>)
|
||||
Close=Chiudi
|
||||
Privilege=Privilegio
|
||||
Description=Descrizione
|
||||
Available privileges:=Privilegi disponibili:
|
||||
print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<filtro>] | dump [<filtro>] | save [<formato> [<filtro>]] | reset
|
||||
Handle the profiler and profiling data=Gestisce il profiler e i dati da esso elaborati
|
||||
Statistics written to action log.=Statistiche scritte nel log delle azioni.
|
||||
Statistics were reset.=Le statistiche sono state resettate.
|
||||
Usage: @1=Utilizzo: @1
|
||||
Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=I formati supportati sono txt, csv, lua, json e json_pretty (le strutture potrebbero essere soggetti a cambiamenti).
|
||||
@1 joined the game.=
|
||||
@1 left the game.=
|
||||
@1 left the game (timed out).=
|
||||
(no description)=(nessuna descrizione)
|
||||
Can interact with things and modify the world=Si può interagire con le cose e modificare il mondo
|
||||
Can speak in chat=Si può parlare in chat
|
||||
Can modify basic privileges (@1)=
|
||||
Can modify privileges=Si possono modificare i privilegi
|
||||
Can teleport self=Si può teletrasportare se stessз
|
||||
Can teleport other players=Si possono teletrasportare gli altri giocatori
|
||||
Can set the time of day using /time=Si può impostate l'orario della giornata tramite /time
|
||||
Can do server maintenance stuff=Si possono eseguire operazioni di manutenzione del server
|
||||
Can bypass node protection in the world=Si può aggirare la protezione dei nodi nel mondo
|
||||
Can ban and unban players=Si possono bandire e perdonare i giocatori
|
||||
Can kick players=Si possono cacciare i giocatori
|
||||
Can use /give and /giveme=Si possono usare /give e /give me
|
||||
Can use /setpassword and /clearpassword=Si possono usare /setpassword e /clearpassword
|
||||
Can use fly mode=Si può usare la modalità volo
|
||||
Can use fast mode=Si può usare la modalità rapida
|
||||
Can fly through solid nodes using noclip mode=Si può volare attraverso i nodi solidi con la modalità incorporea
|
||||
Can use the rollback functionality=Si può usare la funzione di rollback
|
||||
Allows enabling various debug options that may affect gameplay=Permette di abilitare varie opzioni di debug che potrebbero influenzare l'esperienza di gioco
|
||||
Unknown Item=Oggetto sconosciuto
|
||||
Air=Aria
|
||||
Ignore=Ignora
|
||||
You can't place 'ignore' nodes!=Non puoi piazzare nodi 'ignore'!
|
||||
Values below show absolute/relative times spend per server step by the instrumented function.=
|
||||
A total of @1 sample(s) were taken.=
|
||||
The output is limited to '@1'.=
|
||||
Saving of profile failed: @1=
|
||||
Profile saved to @1=
|
||||
|
||||
|
||||
##### not used anymore #####
|
||||
|
||||
<name> (<privilege> | all)=<nome> (<privilegio> | all)
|
||||
<privilege> | all=<privilegio> | all
|
||||
Can modify 'shout' and 'interact' privileges=Si possono modificare i privilegi 'shout' e 'interact'
|
240
builtin/locale/template.txt
Normal file
@ -0,0 +1,240 @@
|
||||
# textdomain: __builtin
|
||||
Empty command.=
|
||||
Invalid command: @1=
|
||||
Invalid command usage.=
|
||||
(@1 s)=
|
||||
Command execution took @1 s=
|
||||
You don't have permission to run this command (missing privileges: @1).=
|
||||
Unable to get position of player @1.=
|
||||
Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=
|
||||
<action>=
|
||||
Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=
|
||||
Show the name of the server owner=
|
||||
The administrator of this server is @1.=
|
||||
There's no administrator named in the config file.=
|
||||
@1 does not have any privileges.=
|
||||
Privileges of @1: @2=
|
||||
[<name>]=
|
||||
Show privileges of yourself or another player=
|
||||
Player @1 does not exist.=
|
||||
<privilege>=
|
||||
Return list of all online players with privilege=
|
||||
Invalid parameters (see /help haspriv).=
|
||||
Unknown privilege!=
|
||||
Players online with the "@1" privilege: @2=
|
||||
Your privileges are insufficient.=
|
||||
Your privileges are insufficient. '@1' only allows you to grant: @2=
|
||||
Unknown privilege: @1=
|
||||
@1 granted you privileges: @2=
|
||||
<name> (<privilege> [, <privilege2> [<...>]] | all)=
|
||||
Give privileges to player=
|
||||
Invalid parameters (see /help grant).=
|
||||
<privilege> [, <privilege2> [<...>]] | all=
|
||||
Grant privileges to yourself=
|
||||
Invalid parameters (see /help grantme).=
|
||||
Your privileges are insufficient. '@1' only allows you to revoke: @2=
|
||||
Note: Cannot revoke in singleplayer: @1=
|
||||
Note: Cannot revoke from admin: @1=
|
||||
No privileges were revoked.=
|
||||
@1 revoked privileges from you: @2=
|
||||
Remove privileges from player=
|
||||
Invalid parameters (see /help revoke).=
|
||||
Revoke privileges from yourself=
|
||||
Invalid parameters (see /help revokeme).=
|
||||
<name> <password>=
|
||||
Set player's password=
|
||||
Name field required.=
|
||||
Your password was cleared by @1.=
|
||||
Password of player "@1" cleared.=
|
||||
Your password was set by @1.=
|
||||
Password of player "@1" set.=
|
||||
<name>=
|
||||
Set empty password for a player=
|
||||
Reload authentication data=
|
||||
Done.=
|
||||
Failed.=
|
||||
Remove a player's data=
|
||||
Player "@1" removed.=
|
||||
No such player "@1" to remove.=
|
||||
Player "@1" is connected, cannot remove.=
|
||||
Unhandled remove_player return code @1.=
|
||||
Cannot teleport out of map bounds!=
|
||||
Cannot get player with name @1.=
|
||||
Cannot teleport, @1 is attached to an object!=
|
||||
Teleporting @1 to @2.=
|
||||
One does not teleport to oneself.=
|
||||
Cannot get teleportee with name @1.=
|
||||
Cannot get target player with name @1.=
|
||||
Teleporting @1 to @2 at @3.=
|
||||
<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=
|
||||
Teleport to position or player=
|
||||
You don't have permission to teleport other players (missing privilege: @1).=
|
||||
([-n] <name> <value>) | <name>=
|
||||
Set or read server configuration setting=
|
||||
Failed. Use '/set -n <name> <value>' to create a new setting.=
|
||||
@1 @= @2=
|
||||
<not set>=
|
||||
Invalid parameters (see /help set).=
|
||||
Finished emerging @1 blocks in @2ms.=
|
||||
emergeblocks update: @1/@2 blocks emerged (@3%)=
|
||||
(here [<radius>]) | (<pos1> <pos2>)=
|
||||
Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=
|
||||
Started emerge of area ranging from @1 to @2.=
|
||||
Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=
|
||||
Successfully cleared area ranging from @1 to @2.=
|
||||
Failed to clear one or more blocks in area.=
|
||||
Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)=
|
||||
Successfully reset light in the area ranging from @1 to @2.=
|
||||
Failed to load one or more blocks in area.=
|
||||
List mods installed on the server=
|
||||
Cannot give an empty item.=
|
||||
Cannot give an unknown item.=
|
||||
Giving 'ignore' is not allowed.=
|
||||
@1 is not a known player.=
|
||||
@1 partially added to inventory.=
|
||||
@1 could not be added to inventory.=
|
||||
@1 added to inventory.=
|
||||
@1 partially added to inventory of @2.=
|
||||
@1 could not be added to inventory of @2.=
|
||||
@1 added to inventory of @2.=
|
||||
<name> <ItemString> [<count> [<wear>]]=
|
||||
Give item to player=
|
||||
Name and ItemString required.=
|
||||
<ItemString> [<count> [<wear>]]=
|
||||
Give item to yourself=
|
||||
ItemString required.=
|
||||
<EntityName> [<X>,<Y>,<Z>]=
|
||||
Spawn entity at given (or your) position=
|
||||
EntityName required.=
|
||||
Unable to spawn entity, player is nil.=
|
||||
Cannot spawn an unknown entity.=
|
||||
Invalid parameters (@1).=
|
||||
@1 spawned.=
|
||||
@1 failed to spawn.=
|
||||
Destroy item in hand=
|
||||
Unable to pulverize, no player.=
|
||||
Unable to pulverize, no item in hand.=
|
||||
An item was pulverized.=
|
||||
[<range>] [<seconds>] [<limit>]=
|
||||
Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=
|
||||
Rollback functions are disabled.=
|
||||
That limit is too high!=
|
||||
Checking @1 ...=
|
||||
Nobody has touched the specified location in @1 seconds.=
|
||||
@1 @2 @3 -> @4 @5 seconds ago.=
|
||||
Punch a node (range@=@1, seconds@=@2, limit@=@3).=
|
||||
(<name> [<seconds>]) | (:<actor> [<seconds>])=
|
||||
Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=
|
||||
Invalid parameters. See /help rollback and /help rollback_check.=
|
||||
Reverting actions of player '@1' since @2 seconds.=
|
||||
Reverting actions of @1 since @2 seconds.=
|
||||
(log is too long to show)=
|
||||
Reverting actions succeeded.=
|
||||
Reverting actions FAILED.=
|
||||
Show server status=
|
||||
This command was disabled by a mod or game.=
|
||||
[<0..23>:<0..59> | <0..24000>]=
|
||||
Show or set time of day=
|
||||
Current time is @1:@2.=
|
||||
You don't have permission to run this command (missing privilege: @1).=
|
||||
Invalid time.=
|
||||
Time of day changed.=
|
||||
Invalid hour (must be between 0 and 23 inclusive).=
|
||||
Invalid minute (must be between 0 and 59 inclusive).=
|
||||
Show day count since world creation=
|
||||
Current day is @1.=
|
||||
[<delay_in_seconds> | -1] [reconnect] [<message>]=
|
||||
Shutdown server (-1 cancels a delayed shutdown)=
|
||||
Server shutting down (operator request).=
|
||||
Ban the IP of a player or show the ban list=
|
||||
The ban list is empty.=
|
||||
Ban list: @1=
|
||||
Player is not online.=
|
||||
Failed to ban player.=
|
||||
Banned @1.=
|
||||
<name> | <IP_address>=
|
||||
Remove IP ban belonging to a player/IP=
|
||||
Failed to unban player/IP.=
|
||||
Unbanned @1.=
|
||||
<name> [<reason>]=
|
||||
Kick a player=
|
||||
Failed to kick player @1.=
|
||||
Kicked @1.=
|
||||
[full | quick]=
|
||||
Clear all objects in world=
|
||||
Invalid usage, see /help clearobjects.=
|
||||
Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=
|
||||
Cleared all objects.=
|
||||
<name> <message>=
|
||||
Send a direct message to a player=
|
||||
Invalid usage, see /help msg.=
|
||||
The player @1 is not online.=
|
||||
DM from @1: @2=
|
||||
Message sent.=
|
||||
Get the last login time of a player or yourself=
|
||||
@1's last login time was @2.=
|
||||
@1's last login time is unknown.=
|
||||
Clear the inventory of yourself or another player=
|
||||
You don't have permission to clear another player's inventory (missing privilege: @1).=
|
||||
@1 cleared your inventory.=
|
||||
Cleared @1's inventory.=
|
||||
Player must be online to clear inventory!=
|
||||
Players can't be killed, damage has been disabled.=
|
||||
Player @1 is not online.=
|
||||
You are already dead.=
|
||||
@1 is already dead.=
|
||||
@1 has been killed.=
|
||||
Kill player or yourself=
|
||||
Available commands: @1=
|
||||
Use '/help <cmd>' to get more information, or '/help all' to list everything.=
|
||||
Available commands:=
|
||||
Command not available: @1=
|
||||
[all | privs | <cmd>]=
|
||||
Get help for commands or list privileges=
|
||||
Command=
|
||||
Parameters=
|
||||
For more information, click on any entry in the list.=
|
||||
Double-click to copy the entry to the chat history.=
|
||||
Command: @1 @2=
|
||||
Available commands: (see also: /help <cmd>)=
|
||||
Close=
|
||||
Privilege=
|
||||
Description=
|
||||
Available privileges:=
|
||||
print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=
|
||||
Handle the profiler and profiling data=
|
||||
Statistics written to action log.=
|
||||
Statistics were reset.=
|
||||
Usage: @1=
|
||||
Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=
|
||||
@1 joined the game.=
|
||||
@1 left the game.=
|
||||
@1 left the game (timed out).=
|
||||
(no description)=
|
||||
Can interact with things and modify the world=
|
||||
Can speak in chat=
|
||||
Can modify basic privileges (@1)=
|
||||
Can modify privileges=
|
||||
Can teleport self=
|
||||
Can teleport other players=
|
||||
Can set the time of day using /time=
|
||||
Can do server maintenance stuff=
|
||||
Can bypass node protection in the world=
|
||||
Can ban and unban players=
|
||||
Can kick players=
|
||||
Can use /give and /giveme=
|
||||
Can use /setpassword and /clearpassword=
|
||||
Can use fly mode=
|
||||
Can use fast mode=
|
||||
Can fly through solid nodes using noclip mode=
|
||||
Can use the rollback functionality=
|
||||
Allows enabling various debug options that may affect gameplay=
|
||||
Unknown Item=
|
||||
Air=
|
||||
Ignore=
|
||||
You can't place 'ignore' nodes!=
|
||||
Values below show absolute/relative times spend per server step by the instrumented function.=
|
||||
A total of @1 sample(s) were taken.=
|
||||
The output is limited to '@1'.=
|
||||
Saving of profile failed: @1=
|
||||
Profile saved to @1=
|
@ -14,14 +14,11 @@
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- Global menu data
|
||||
--------------------------------------------------------------------------------
|
||||
menudata = {}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Local cached values
|
||||
--------------------------------------------------------------------------------
|
||||
local min_supp_proto, max_supp_proto
|
||||
|
||||
function common_update_cached_supp_proto()
|
||||
@ -29,14 +26,12 @@ function common_update_cached_supp_proto()
|
||||
max_supp_proto = core.get_max_supp_proto()
|
||||
end
|
||||
common_update_cached_supp_proto()
|
||||
--------------------------------------------------------------------------------
|
||||
-- Menu helper functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Menu helper functions
|
||||
|
||||
local function render_client_count(n)
|
||||
if n > 99 then return '99+'
|
||||
elseif n >= 0 then return tostring(n)
|
||||
if n > 999 then return '99+'
|
||||
elseif n >= 0 then return tostring(n)
|
||||
else return '?' end
|
||||
end
|
||||
|
||||
@ -50,39 +45,7 @@ local function configure_selected_world_params(idx)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function image_column(tooltip, flagname)
|
||||
return "image,tooltip=" .. core.formspec_escape(tooltip) .. "," ..
|
||||
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
|
||||
"1=" .. core.formspec_escape(defaulttexturedir ..
|
||||
(flagname and "server_flags_" .. flagname .. ".png" or "blank.png")) .. "," ..
|
||||
"2=" .. core.formspec_escape(defaulttexturedir .. "server_ping_4.png") .. "," ..
|
||||
"3=" .. core.formspec_escape(defaulttexturedir .. "server_ping_3.png") .. "," ..
|
||||
"4=" .. core.formspec_escape(defaulttexturedir .. "server_ping_2.png") .. "," ..
|
||||
"5=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function order_favorite_list(list)
|
||||
local res = {}
|
||||
--orders the favorite list after support
|
||||
for i = 1, #list do
|
||||
local fav = list[i]
|
||||
if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
res[#res + 1] = fav
|
||||
end
|
||||
end
|
||||
for i = 1, #list do
|
||||
local fav = list[i]
|
||||
if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
res[#res + 1] = fav
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function render_serverlist_row(spec, is_favorite)
|
||||
function render_serverlist_row(spec)
|
||||
local text = ""
|
||||
if spec.name then
|
||||
text = text .. core.formspec_escape(spec.name:trim())
|
||||
@ -93,31 +56,29 @@ function render_serverlist_row(spec, is_favorite)
|
||||
end
|
||||
end
|
||||
|
||||
local grey_out = not is_server_protocol_compat(spec.proto_min, spec.proto_max)
|
||||
local grey_out = not spec.is_compatible
|
||||
|
||||
local details
|
||||
if is_favorite then
|
||||
details = "1,"
|
||||
else
|
||||
details = "0,"
|
||||
end
|
||||
local details = {}
|
||||
|
||||
if spec.ping then
|
||||
local ping = spec.ping * 1000
|
||||
if ping <= 50 then
|
||||
details = details .. "2,"
|
||||
elseif ping <= 100 then
|
||||
details = details .. "3,"
|
||||
elseif ping <= 250 then
|
||||
details = details .. "4,"
|
||||
if spec.lag or spec.ping then
|
||||
local lag = (spec.lag or 0) * 1000 + (spec.ping or 0) * 250
|
||||
if lag <= 125 then
|
||||
table.insert(details, "1")
|
||||
elseif lag <= 175 then
|
||||
table.insert(details, "2")
|
||||
elseif lag <= 250 then
|
||||
table.insert(details, "3")
|
||||
else
|
||||
details = details .. "5,"
|
||||
table.insert(details, "4")
|
||||
end
|
||||
else
|
||||
details = details .. "0,"
|
||||
table.insert(details, "0")
|
||||
end
|
||||
|
||||
if spec.clients and spec.clients_max then
|
||||
table.insert(details, ",")
|
||||
|
||||
local color = (grey_out and "#aaaaaa") or ((spec.is_favorite and "#ddddaa") or "#ffffff")
|
||||
if spec.clients and (spec.clients_max or 0) > 0 then
|
||||
local clients_percent = 100 * spec.clients / spec.clients_max
|
||||
|
||||
-- Choose a color depending on how many clients are connected
|
||||
@ -128,74 +89,50 @@ function render_serverlist_row(spec, is_favorite)
|
||||
elseif clients_percent <= 60 then clients_color = '#a1e587' -- 0-60%: green
|
||||
elseif clients_percent <= 90 then clients_color = '#ffdc97' -- 60-90%: yellow
|
||||
elseif clients_percent == 100 then clients_color = '#dd5b5b' -- full server: red (darker)
|
||||
else clients_color = '#ffba97' -- 90-100%: orange
|
||||
else clients_color = '#ffba97' -- 90-100%: orange
|
||||
end
|
||||
|
||||
details = details .. clients_color .. ',' ..
|
||||
render_client_count(spec.clients) .. ',/,' ..
|
||||
render_client_count(spec.clients_max) .. ','
|
||||
|
||||
elseif grey_out then
|
||||
details = details .. '#aaaaaa,?,/,?,'
|
||||
table.insert(details, clients_color)
|
||||
table.insert(details, render_client_count(spec.clients) .. " / " ..
|
||||
render_client_count(spec.clients_max))
|
||||
else
|
||||
details = details .. ',?,/,?,'
|
||||
table.insert(details, color)
|
||||
table.insert(details, "?")
|
||||
end
|
||||
|
||||
if spec.creative then
|
||||
details = details .. "1,"
|
||||
table.insert(details, "1") -- creative icon
|
||||
else
|
||||
details = details .. "0,"
|
||||
end
|
||||
|
||||
if spec.damage then
|
||||
details = details .. "1,"
|
||||
else
|
||||
details = details .. "0,"
|
||||
table.insert(details, "0")
|
||||
end
|
||||
|
||||
if spec.pvp then
|
||||
details = details .. "1,"
|
||||
table.insert(details, "2") -- pvp icon
|
||||
elseif spec.damage then
|
||||
table.insert(details, "1") -- heart icon
|
||||
else
|
||||
details = details .. "0,"
|
||||
table.insert(details, "0")
|
||||
end
|
||||
|
||||
return details .. (grey_out and '#aaaaaa,' or ',') .. text
|
||||
table.insert(details, color)
|
||||
table.insert(details, text)
|
||||
|
||||
return table.concat(details, ",")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
os.tempfolder = function()
|
||||
if core.settings:get("TMPFolder") then
|
||||
return core.settings:get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000)
|
||||
end
|
||||
|
||||
local filetocheck = os.tmpname()
|
||||
os.remove(filetocheck)
|
||||
|
||||
-- luacheck: ignore
|
||||
-- https://blogs.msdn.microsoft.com/vcblog/2014/06/18/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
|
||||
-- The C runtime (CRT) function called by os.tmpname is tmpnam.
|
||||
-- Microsofts tmpnam implementation in older CRT / MSVC releases is defective.
|
||||
-- tmpnam return values starting with a backslash characterize this behavior.
|
||||
-- https://sourceforge.net/p/mingw-w64/bugs/555/
|
||||
-- MinGW tmpnam implementation is forwarded to the CRT directly.
|
||||
-- https://sourceforge.net/p/mingw-w64/discussion/723797/thread/55520785/
|
||||
-- MinGW links to an older CRT release (msvcrt.dll).
|
||||
-- Due to legal concerns MinGW will never use a newer CRT.
|
||||
--
|
||||
-- Make use of TEMP to compose the temporary filename if an old
|
||||
-- style tmpnam return value is detected.
|
||||
if filetocheck:sub(1, 1) == "\\" then
|
||||
local tempfolder = os.getenv("TEMP")
|
||||
return tempfolder .. filetocheck
|
||||
end
|
||||
|
||||
local randname = "MTTempModFolder_" .. math.random(0,10000)
|
||||
local backstring = filetocheck:reverse()
|
||||
return filetocheck:sub(0, filetocheck:len() - backstring:find(DIR_DELIM) + 1) ..
|
||||
randname
|
||||
local temp = core.get_temp_path()
|
||||
return temp .. DIR_DELIM .. "MT_" .. math.random(0, 10000)
|
||||
end
|
||||
|
||||
os.tmpname = function()
|
||||
local path = os.tempfolder()
|
||||
io.open(path, "w"):close()
|
||||
return path
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function menu_render_worldlist()
|
||||
local retval = ""
|
||||
local current_worldlist = menudata.worldlist:get_list()
|
||||
@ -209,7 +146,6 @@ function menu_render_worldlist()
|
||||
return retval
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function menu_handle_key_up_down(fields, textlist, settingname)
|
||||
local oldidx, newidx = core.get_textlist_index(textlist), 1
|
||||
if fields.key_up or fields.key_down then
|
||||
@ -226,42 +162,6 @@ function menu_handle_key_up_down(fields, textlist, settingname)
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function asyncOnlineFavourites()
|
||||
if not menudata.public_known then
|
||||
menudata.public_known = {{
|
||||
name = fgettext("Loading..."),
|
||||
description = fgettext_ne("Try reenabling public serverlist and check your internet connection.")
|
||||
}}
|
||||
end
|
||||
menudata.favorites = menudata.public_known
|
||||
menudata.favorites_is_public = true
|
||||
|
||||
if not menudata.public_downloading then
|
||||
menudata.public_downloading = true
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
core.handle_async(
|
||||
function(param)
|
||||
return core.get_favorites("online")
|
||||
end,
|
||||
nil,
|
||||
function(result)
|
||||
menudata.public_downloading = nil
|
||||
local favs = order_favorite_list(result)
|
||||
if favs[1] then
|
||||
menudata.public_known = favs
|
||||
menudata.favorites = menudata.public_known
|
||||
menudata.favorites_is_public = true
|
||||
end
|
||||
core.event_handler("Refresh")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency)
|
||||
local textlines = core.wrap_text(text, textlen, true)
|
||||
local retval = "textlist[" .. xpos .. "," .. ypos .. ";" .. width ..
|
||||
@ -279,7 +179,6 @@ function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transp
|
||||
return retval
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function is_server_protocol_compat(server_proto_min, server_proto_max)
|
||||
if (not server_proto_min) or (not server_proto_max) then
|
||||
-- There is no info. Assume the best and act as if we would be compatible.
|
||||
@ -287,7 +186,7 @@ function is_server_protocol_compat(server_proto_min, server_proto_max)
|
||||
end
|
||||
return min_supp_proto <= server_proto_max and max_supp_proto >= server_proto_min
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function is_server_protocol_compat_or_error(server_proto_min, server_proto_max)
|
||||
if not is_server_protocol_compat(server_proto_min, server_proto_max) then
|
||||
local server_prot_ver_info, client_prot_ver_info
|
||||
@ -315,7 +214,7 @@ function is_server_protocol_compat_or_error(server_proto_min, server_proto_max)
|
||||
|
||||
return true
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function menu_worldmt(selected, setting, value)
|
||||
local world = menudata.worldlist:get_list()[selected]
|
||||
if world then
|
||||
|
@ -74,7 +74,7 @@ local function get_formspec(data)
|
||||
"label[1.75,0;" .. data.worldspec.name .. "]"
|
||||
|
||||
if mod.is_modpack or mod.type == "game" then
|
||||
local info = minetest.formspec_escape(
|
||||
local info = core.formspec_escape(
|
||||
core.get_content_info(mod.path).description)
|
||||
if info == "" then
|
||||
if mod.is_modpack then
|
||||
|
@ -15,7 +15,7 @@
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
if not minetest.get_http_api then
|
||||
if not core.get_http_api then
|
||||
function create_store_dlg()
|
||||
return messagebox("store",
|
||||
fgettext("ContentDB is not available when Minetest was compiled without cURL"))
|
||||
@ -23,9 +23,11 @@ if not minetest.get_http_api then
|
||||
return
|
||||
end
|
||||
|
||||
local store = { packages = {}, packages_full = {} }
|
||||
-- Unordered preserves the original order of the ContentDB API,
|
||||
-- before the package list is ordered based on installed state.
|
||||
local store = { packages = {}, packages_full = {}, packages_full_unordered = {} }
|
||||
|
||||
local http = minetest.get_http_api()
|
||||
local http = core.get_http_api()
|
||||
|
||||
-- Screenshot
|
||||
local screenshot_dir = core.get_cache_path() .. DIR_DELIM .. "cdb"
|
||||
@ -150,7 +152,7 @@ local function start_install(package)
|
||||
end
|
||||
|
||||
local function queue_download(package)
|
||||
local max_concurrent_downloads = tonumber(minetest.settings:get("contentdb_max_concurrent_downloads"))
|
||||
local max_concurrent_downloads = tonumber(core.settings:get("contentdb_max_concurrent_downloads"))
|
||||
if number_downloading < max_concurrent_downloads then
|
||||
start_install(package)
|
||||
else
|
||||
@ -318,7 +320,7 @@ function install_dialog.get_formspec()
|
||||
selected_game_idx = i
|
||||
end
|
||||
|
||||
games[i] = minetest.formspec_escape(games[i].name)
|
||||
games[i] = core.formspec_escape(games[i].name)
|
||||
end
|
||||
|
||||
local selected_game = pkgmgr.games[selected_game_idx]
|
||||
@ -329,7 +331,7 @@ function install_dialog.get_formspec()
|
||||
local formatted_deps = {}
|
||||
for _, dep in pairs(install_dialog.dependencies) do
|
||||
formatted_deps[#formatted_deps + 1] = "#fff"
|
||||
formatted_deps[#formatted_deps + 1] = minetest.formspec_escape(dep.name)
|
||||
formatted_deps[#formatted_deps + 1] = core.formspec_escape(dep.name)
|
||||
if dep.installed then
|
||||
formatted_deps[#formatted_deps + 1] = "#ccf"
|
||||
formatted_deps[#formatted_deps + 1] = fgettext("Already installed")
|
||||
@ -400,7 +402,7 @@ function install_dialog.handle_submit(this, fields)
|
||||
end
|
||||
|
||||
if fields.will_install_deps ~= nil then
|
||||
install_dialog.will_install_deps = minetest.is_yes(fields.will_install_deps)
|
||||
install_dialog.will_install_deps = core.is_yes(fields.will_install_deps)
|
||||
return true
|
||||
end
|
||||
|
||||
@ -551,7 +553,7 @@ function store.load()
|
||||
end
|
||||
end
|
||||
|
||||
local timeout = tonumber(minetest.settings:get("curl_file_download_timeout"))
|
||||
local timeout = tonumber(core.settings:get("curl_file_download_timeout"))
|
||||
local response = http.fetch_sync({ url = url, timeout = timeout })
|
||||
if not response.succeeded then
|
||||
return
|
||||
@ -572,6 +574,7 @@ function store.load()
|
||||
end
|
||||
end
|
||||
|
||||
store.packages_full_unordered = store.packages_full
|
||||
store.packages = store.packages_full
|
||||
store.loaded = true
|
||||
end
|
||||
@ -580,7 +583,7 @@ function store.update_paths()
|
||||
local mod_hash = {}
|
||||
pkgmgr.refresh_globals()
|
||||
for _, mod in pairs(pkgmgr.clientmods:get_list()) do
|
||||
if mod.author then
|
||||
if mod.author and mod.release > 0 then
|
||||
mod_hash[mod.author:lower() .. "/" .. mod.name] = mod
|
||||
end
|
||||
end
|
||||
@ -588,14 +591,14 @@ function store.update_paths()
|
||||
local game_hash = {}
|
||||
pkgmgr.update_gamelist()
|
||||
for _, game in pairs(pkgmgr.games) do
|
||||
if game.author ~= "" then
|
||||
if game.author ~= "" and game.release > 0 then
|
||||
game_hash[game.author:lower() .. "/" .. game.id] = game
|
||||
end
|
||||
end
|
||||
|
||||
local txp_hash = {}
|
||||
for _, txp in pairs(pkgmgr.get_texture_packs()) do
|
||||
if txp.author then
|
||||
if txp.author and txp.release > 0 then
|
||||
txp_hash[txp.author:lower() .. "/" .. txp.name] = txp
|
||||
end
|
||||
end
|
||||
@ -619,6 +622,33 @@ function store.update_paths()
|
||||
end
|
||||
end
|
||||
|
||||
function store.sort_packages()
|
||||
local ret = {}
|
||||
|
||||
-- Add installed content
|
||||
for i=1, #store.packages_full_unordered do
|
||||
local package = store.packages_full_unordered[i]
|
||||
if package.path then
|
||||
ret[#ret + 1] = package
|
||||
end
|
||||
end
|
||||
|
||||
-- Sort installed content by title
|
||||
table.sort(ret, function(a, b)
|
||||
return a.title < b.title
|
||||
end)
|
||||
|
||||
-- Add uninstalled content
|
||||
for i=1, #store.packages_full_unordered do
|
||||
local package = store.packages_full_unordered[i]
|
||||
if not package.path then
|
||||
ret[#ret + 1] = package
|
||||
end
|
||||
end
|
||||
|
||||
store.packages_full = ret
|
||||
end
|
||||
|
||||
function store.filter_packages(query)
|
||||
if query == "" and filter_type == 1 then
|
||||
store.packages = store.packages_full
|
||||
@ -652,7 +682,6 @@ function store.filter_packages(query)
|
||||
store.packages[#store.packages + 1] = package
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function store.get_formspec(dlgdata)
|
||||
@ -764,8 +793,8 @@ function store.get_formspec(dlgdata)
|
||||
-- title
|
||||
formspec[#formspec + 1] = "label[1.875,0.1;"
|
||||
formspec[#formspec + 1] = core.formspec_escape(
|
||||
minetest.colorize(mt_color_green, package.title) ..
|
||||
minetest.colorize("#BFBFBF", " by " .. package.author))
|
||||
core.colorize(mt_color_green, package.title) ..
|
||||
core.colorize("#BFBFBF", " by " .. package.author))
|
||||
formspec[#formspec + 1] = "]"
|
||||
|
||||
-- buttons
|
||||
@ -960,6 +989,9 @@ function create_store_dlg(type)
|
||||
store.load()
|
||||
end
|
||||
|
||||
store.update_paths()
|
||||
store.sort_packages()
|
||||
|
||||
search_string = ""
|
||||
cur_page = 1
|
||||
|
||||
|
@ -443,7 +443,7 @@ local function create_world_buttonhandler(this, fields)
|
||||
end
|
||||
|
||||
if fields["mgv6_biomes"] then
|
||||
local entry = minetest.formspec_escape(fields["mgv6_biomes"])
|
||||
local entry = core.formspec_escape(fields["mgv6_biomes"])
|
||||
for b=1, #mgv6_biomes do
|
||||
if entry == mgv6_biomes[b][1] then
|
||||
local ftable = core.settings:get_flags("mgv6_spflags")
|
||||
|
@ -34,6 +34,7 @@ dofile(basepath .. "fstk" .. DIR_DELIM .. "ui.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "async_event.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "common.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "pkgmgr.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "serverlistmgr.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "textures.lua")
|
||||
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
|
||||
@ -48,7 +49,7 @@ local tabs = {}
|
||||
|
||||
tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
|
||||
tabs.content = dofile(menupath .. DIR_DELIM .. "tab_content.lua")
|
||||
tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
|
||||
tabs.about = dofile(menupath .. DIR_DELIM .. "tab_about.lua")
|
||||
tabs.local_game = dofile(menupath .. DIR_DELIM .. "tab_local.lua")
|
||||
tabs.play_online = dofile(menupath .. DIR_DELIM .. "tab_online.lua")
|
||||
|
||||
@ -97,7 +98,7 @@ local function init_globals()
|
||||
|
||||
tv_main:add(tabs.content)
|
||||
tv_main:add(tabs.settings)
|
||||
tv_main:add(tabs.credits)
|
||||
tv_main:add(tabs.about)
|
||||
|
||||
tv_main:set_global_event_handler(main_event_handler)
|
||||
tv_main:set_fixed_size(false)
|
||||
|
@ -72,6 +72,34 @@ local function cleanup_path(temppath)
|
||||
return temppath
|
||||
end
|
||||
|
||||
local function load_texture_packs(txtpath, retval)
|
||||
local list = core.get_dir_list(txtpath, true)
|
||||
local current_texture_path = core.settings:get("texture_path")
|
||||
|
||||
for _, item in ipairs(list) do
|
||||
if item ~= "base" then
|
||||
local name = item
|
||||
|
||||
local path = txtpath .. DIR_DELIM .. item .. DIR_DELIM
|
||||
if path == current_texture_path then
|
||||
name = fgettext("$1 (Enabled)", name)
|
||||
end
|
||||
|
||||
local conf = Settings(path .. "texture_pack.conf")
|
||||
|
||||
retval[#retval + 1] = {
|
||||
name = item,
|
||||
author = conf:get("author"),
|
||||
release = tonumber(conf:get("release")) or 0,
|
||||
list_name = name,
|
||||
type = "txp",
|
||||
path = path,
|
||||
enabled = path == current_texture_path,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function get_mods(path,retval,modpack)
|
||||
local mods = core.get_dir_list(path, true)
|
||||
|
||||
@ -107,12 +135,12 @@ function get_mods(path,retval,modpack)
|
||||
-- Read from config
|
||||
toadd.name = name
|
||||
toadd.author = mod_conf.author
|
||||
toadd.release = tonumber(mod_conf.release or "0")
|
||||
toadd.release = tonumber(mod_conf.release) or 0
|
||||
toadd.path = prefix
|
||||
toadd.type = "mod"
|
||||
|
||||
-- Check modpack.txt
|
||||
-- Note: modpack.conf is already checked above
|
||||
-- Note: modpack.conf is already checked above
|
||||
local modpackfile = io.open(prefix .. DIR_DELIM .. "modpack.txt")
|
||||
if modpackfile then
|
||||
modpackfile:close()
|
||||
@ -136,32 +164,13 @@ pkgmgr = {}
|
||||
|
||||
function pkgmgr.get_texture_packs()
|
||||
local txtpath = core.get_texturepath()
|
||||
local list = core.get_dir_list(txtpath, true)
|
||||
local txtpath_system = core.get_texturepath_share()
|
||||
local retval = {}
|
||||
|
||||
local current_texture_path = core.settings:get("texture_path")
|
||||
|
||||
for _, item in ipairs(list) do
|
||||
if item ~= "base" then
|
||||
local name = item
|
||||
|
||||
local path = txtpath .. DIR_DELIM .. item .. DIR_DELIM
|
||||
if path == current_texture_path then
|
||||
name = fgettext("$1 (Enabled)", name)
|
||||
end
|
||||
|
||||
local conf = Settings(path .. "texture_pack.conf")
|
||||
|
||||
retval[#retval + 1] = {
|
||||
name = item,
|
||||
author = conf:get("author"),
|
||||
release = tonumber(conf:get("release") or "0"),
|
||||
list_name = name,
|
||||
type = "txp",
|
||||
path = path,
|
||||
enabled = path == current_texture_path,
|
||||
}
|
||||
end
|
||||
load_texture_packs(txtpath, retval)
|
||||
-- on portable versions these two paths coincide. It avoids loading the path twice
|
||||
if txtpath ~= txtpath_system then
|
||||
load_texture_packs(txtpath_system, retval)
|
||||
end
|
||||
|
||||
table.sort(retval, function(a, b)
|
||||
@ -404,18 +413,7 @@ function pkgmgr.is_modpack_entirely_enabled(data, name)
|
||||
end
|
||||
|
||||
---------- toggles or en/disables a mod or modpack and its dependencies --------
|
||||
function pkgmgr.enable_mod(this, toset)
|
||||
local list = this.data.list:get_list()
|
||||
local mod = list[this.data.selected_mod]
|
||||
|
||||
-- Game mods can't be enabled or disabled
|
||||
if mod.is_game_content then
|
||||
return
|
||||
end
|
||||
|
||||
local toggled_mods = {}
|
||||
|
||||
local enabled_mods = {}
|
||||
local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod)
|
||||
if not mod.is_modpack then
|
||||
-- Toggle or en/disable the mod
|
||||
if toset == nil then
|
||||
@ -434,23 +432,29 @@ function pkgmgr.enable_mod(this, toset)
|
||||
-- interleaved unsupported
|
||||
for i = 1, #list do
|
||||
if list[i].modpack == mod.name then
|
||||
if toset == nil then
|
||||
toset = not list[i].enabled
|
||||
end
|
||||
if list[i].enabled ~= toset then
|
||||
list[i].enabled = toset
|
||||
toggled_mods[#toggled_mods+1] = list[i].name
|
||||
end
|
||||
if toset then
|
||||
enabled_mods[list[i].name] = true
|
||||
end
|
||||
toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, list[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function pkgmgr.enable_mod(this, toset)
|
||||
local list = this.data.list:get_list()
|
||||
local mod = list[this.data.selected_mod]
|
||||
|
||||
-- Game mods can't be enabled or disabled
|
||||
if mod.is_game_content then
|
||||
return
|
||||
end
|
||||
|
||||
local toggled_mods = {}
|
||||
local enabled_mods = {}
|
||||
toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod)
|
||||
|
||||
if not toset then
|
||||
-- Mod(s) were disabled, so no dependencies need to be enabled
|
||||
table.sort(toggled_mods)
|
||||
minetest.log("info", "Following mods were disabled: " ..
|
||||
core.log("info", "Following mods were disabled: " ..
|
||||
table.concat(toggled_mods, ", "))
|
||||
return
|
||||
end
|
||||
@ -487,7 +491,7 @@ function pkgmgr.enable_mod(this, toset)
|
||||
enabled_mods[name] = true
|
||||
local mod_to_enable = list[mod_ids[name]]
|
||||
if not mod_to_enable then
|
||||
minetest.log("warning", "Mod dependency \"" .. name ..
|
||||
core.log("warning", "Mod dependency \"" .. name ..
|
||||
"\" not found!")
|
||||
else
|
||||
if mod_to_enable.enabled == false then
|
||||
@ -508,7 +512,7 @@ function pkgmgr.enable_mod(this, toset)
|
||||
|
||||
-- Log the list of enabled mods
|
||||
table.sort(toggled_mods)
|
||||
minetest.log("info", "Following mods were enabled: " ..
|
||||
core.log("info", "Following mods were enabled: " ..
|
||||
table.concat(toggled_mods, ", "))
|
||||
end
|
||||
|
||||
|
252
builtin/mainmenu/serverlistmgr.lua
Normal file
@ -0,0 +1,252 @@
|
||||
--Minetest
|
||||
--Copyright (C) 2020 rubenwardy
|
||||
--
|
||||
--This program is free software; you can redistribute it and/or modify
|
||||
--it under the terms of the GNU Lesser General Public License as published by
|
||||
--the Free Software Foundation; either version 2.1 of the License, or
|
||||
--(at your option) any later version.
|
||||
--
|
||||
--This program is distributed in the hope that it will be useful,
|
||||
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
--GNU Lesser General Public License for more details.
|
||||
--
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
serverlistmgr = {}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function order_server_list(list)
|
||||
local res = {}
|
||||
--orders the favorite list after support
|
||||
for i = 1, #list do
|
||||
local fav = list[i]
|
||||
if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
res[#res + 1] = fav
|
||||
end
|
||||
end
|
||||
for i = 1, #list do
|
||||
local fav = list[i]
|
||||
if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
res[#res + 1] = fav
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
local public_downloading = false
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function serverlistmgr.sync()
|
||||
if not serverlistmgr.servers then
|
||||
serverlistmgr.servers = {{
|
||||
name = fgettext("Loading..."),
|
||||
description = fgettext_ne("Try reenabling public serverlist and check your internet connection.")
|
||||
}}
|
||||
end
|
||||
|
||||
local serverlist_url = core.settings:get("serverlist_url") or ""
|
||||
if not core.get_http_api or serverlist_url == "" then
|
||||
serverlistmgr.servers = {{
|
||||
name = fgettext("Public server list is disabled"),
|
||||
description = ""
|
||||
}}
|
||||
return
|
||||
end
|
||||
|
||||
if public_downloading then
|
||||
return
|
||||
end
|
||||
public_downloading = true
|
||||
|
||||
core.handle_async(
|
||||
function(param)
|
||||
local http = core.get_http_api()
|
||||
local url = ("%s/list?proto_version_min=%d&proto_version_max=%d"):format(
|
||||
core.settings:get("serverlist_url"),
|
||||
core.get_min_supp_proto(),
|
||||
core.get_max_supp_proto())
|
||||
|
||||
local response = http.fetch_sync({ url = url })
|
||||
if not response.succeeded then
|
||||
return {}
|
||||
end
|
||||
|
||||
local retval = core.parse_json(response.data)
|
||||
return retval and retval.list or {}
|
||||
end,
|
||||
nil,
|
||||
function(result)
|
||||
public_downloading = nil
|
||||
local favs = order_server_list(result)
|
||||
if favs[1] then
|
||||
serverlistmgr.servers = favs
|
||||
end
|
||||
core.event_handler("Refresh")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function get_favorites_path(folder)
|
||||
local base = core.get_user_path() .. DIR_DELIM .. "client" .. DIR_DELIM .. "serverlist" .. DIR_DELIM
|
||||
if folder then
|
||||
return base
|
||||
end
|
||||
return base .. core.settings:get("serverlist_file")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function save_favorites(favorites)
|
||||
local filename = core.settings:get("serverlist_file")
|
||||
-- If setting specifies legacy format change the filename to the new one
|
||||
if filename:sub(#filename - 3):lower() == ".txt" then
|
||||
core.settings:set("serverlist_file", filename:sub(1, #filename - 4) .. ".json")
|
||||
end
|
||||
|
||||
assert(core.create_dir(get_favorites_path(true)))
|
||||
core.safe_file_write(get_favorites_path(), core.write_json(favorites))
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function serverlistmgr.read_legacy_favorites(path)
|
||||
local file = io.open(path, "r")
|
||||
if not file then
|
||||
return nil
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
for line in file:lines() do
|
||||
lines[#lines + 1] = line
|
||||
end
|
||||
file:close()
|
||||
|
||||
local favorites = {}
|
||||
|
||||
local i = 1
|
||||
while i < #lines do
|
||||
local function pop()
|
||||
local line = lines[i]
|
||||
i = i + 1
|
||||
return line and line:trim()
|
||||
end
|
||||
|
||||
if pop():lower() == "[server]" then
|
||||
local name = pop()
|
||||
local address = pop()
|
||||
local port = tonumber(pop())
|
||||
local description = pop()
|
||||
|
||||
if name == "" then
|
||||
name = nil
|
||||
end
|
||||
|
||||
if description == "" then
|
||||
description = nil
|
||||
end
|
||||
|
||||
if not address or #address < 3 then
|
||||
core.log("warning", "Malformed favorites file, missing address at line " .. i)
|
||||
elseif not port or port < 1 or port > 65535 then
|
||||
core.log("warning", "Malformed favorites file, missing port at line " .. i)
|
||||
elseif (name and name:upper() == "[SERVER]") or
|
||||
(address and address:upper() == "[SERVER]") or
|
||||
(description and description:upper() == "[SERVER]") then
|
||||
core.log("warning", "Potentially malformed favorites file, overran at line " .. i)
|
||||
else
|
||||
favorites[#favorites + 1] = {
|
||||
name = name,
|
||||
address = address,
|
||||
port = port,
|
||||
description = description
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return favorites
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function read_favorites()
|
||||
local path = get_favorites_path()
|
||||
|
||||
-- If new format configured fall back to reading the legacy file
|
||||
if path:sub(#path - 4):lower() == ".json" then
|
||||
local file = io.open(path, "r")
|
||||
if file then
|
||||
local json = file:read("*all")
|
||||
file:close()
|
||||
return core.parse_json(json)
|
||||
end
|
||||
|
||||
path = path:sub(1, #path - 5) .. ".txt"
|
||||
end
|
||||
|
||||
local favs = serverlistmgr.read_legacy_favorites(path)
|
||||
if favs then
|
||||
save_favorites(favs)
|
||||
os.remove(path)
|
||||
end
|
||||
return favs
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function delete_favorite(favorites, del_favorite)
|
||||
for i=1, #favorites do
|
||||
local fav = favorites[i]
|
||||
|
||||
if fav.address == del_favorite.address and fav.port == del_favorite.port then
|
||||
table.remove(favorites, i)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function serverlistmgr.get_favorites()
|
||||
if serverlistmgr.favorites then
|
||||
return serverlistmgr.favorites
|
||||
end
|
||||
|
||||
serverlistmgr.favorites = {}
|
||||
|
||||
-- Add favorites, removing duplicates
|
||||
local seen = {}
|
||||
for _, fav in ipairs(read_favorites() or {}) do
|
||||
local key = ("%s:%d"):format(fav.address:lower(), fav.port)
|
||||
if not seen[key] then
|
||||
seen[key] = true
|
||||
serverlistmgr.favorites[#serverlistmgr.favorites + 1] = fav
|
||||
end
|
||||
end
|
||||
|
||||
return serverlistmgr.favorites
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function serverlistmgr.add_favorite(new_favorite)
|
||||
assert(type(new_favorite.port) == "number")
|
||||
|
||||
-- Whitelist favorite keys
|
||||
new_favorite = {
|
||||
name = new_favorite.name,
|
||||
address = new_favorite.address,
|
||||
port = new_favorite.port,
|
||||
description = new_favorite.description,
|
||||
}
|
||||
|
||||
local favorites = serverlistmgr.get_favorites()
|
||||
delete_favorite(favorites, new_favorite)
|
||||
table.insert(favorites, 1, new_favorite)
|
||||
save_favorites(favorites)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function serverlistmgr.delete_favorite(del_favorite)
|
||||
local favorites = serverlistmgr.get_favorites()
|
||||
delete_favorite(favorites, del_favorite)
|
||||
save_favorites(favorites)
|
||||
end
|
@ -33,28 +33,37 @@ local core_developers = {
|
||||
"Nathanaël Courant (Nore/Ekdohibs) <nore@mesecons.net>",
|
||||
"Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>",
|
||||
"paramat",
|
||||
"Auke Kok (sofar) <sofar@foo-projects.org>",
|
||||
"Andrew Ward (rubenwardy) <rw@rubenwardy.com>",
|
||||
"Krock/SmallJoker <mk939@ymail.com>",
|
||||
"Lars Hofhansl <larsh@apache.org>",
|
||||
"Pierre-Yves Rollo <dev@pyrollo.com>",
|
||||
"v-rob <robinsonvincent89@gmail.com>",
|
||||
}
|
||||
|
||||
-- For updating active/previous contributors, see the script in ./util/gather_git_credits.py
|
||||
|
||||
local active_contributors = {
|
||||
"Hugues Ross [Formspecs]",
|
||||
"Wuzzy [devtest game, visual corrections]",
|
||||
"Zughy [Visual improvements, various fixes]",
|
||||
"Maksim (MoNTE48) [Android]",
|
||||
"DS [Formspecs]",
|
||||
"pyrollo [Formspecs: Hypertext]",
|
||||
"v-rob [Formspecs]",
|
||||
"Jordach [set_sky]",
|
||||
"random-geek [Formspecs]",
|
||||
"Wuzzy [Pathfinder, builtin, translations]",
|
||||
"ANAND (ClobberXD) [Fixes, per-player FOV]",
|
||||
"Warr1024 [Fixes]",
|
||||
"Paul Ouellette (pauloue) [Fixes, Script API]",
|
||||
"Jean-Patrick G (kilbith) <jeanpatrick.guerrero@gmail.com> [Audiovisuals]",
|
||||
"HybridDog [Script API]",
|
||||
"numzero [Graphics and rendering]",
|
||||
"appgurueu [Various internal fixes]",
|
||||
"Desour [Formspec and vector API changes]",
|
||||
"HybridDog [Rendering fixes and documentation]",
|
||||
"Hugues Ross [Graphics-related improvements]",
|
||||
"ANAND (ClobberXD) [Mouse buttons rebinding]",
|
||||
"luk3yx [Fixes]",
|
||||
"hecks [Audiovisuals, Lua API]",
|
||||
"LoneWolfHT [Object crosshair, documentation fixes]",
|
||||
"Lejo [Server-related improvements]",
|
||||
"EvidenceB [Compass HUD element]",
|
||||
"Paul Ouellette (pauloue) [Lua API, documentation]",
|
||||
"TheTermos [Collision detection, physics]",
|
||||
"David CARLIER [Unix & Haiku build fixes]",
|
||||
"dcbrwn [Object shading]",
|
||||
"srifqi [Fixes]",
|
||||
"Elias Fleckenstein [API features/fixes]",
|
||||
"Jean-Patrick Guerrero (kilbith) [model element, visual fixes]",
|
||||
"k.h.lai [Memory leak fixes, documentation]",
|
||||
}
|
||||
|
||||
local previous_core_developers = {
|
||||
@ -70,30 +79,23 @@ local previous_core_developers = {
|
||||
"sapier",
|
||||
"Zeno",
|
||||
"ShadowNinja <shadowninja@minetest.net>",
|
||||
"Auke Kok (sofar) <sofar@foo-projects.org>",
|
||||
}
|
||||
|
||||
local previous_contributors = {
|
||||
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest Logo]",
|
||||
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
|
||||
"red-001 <red-001@outlook.ie>",
|
||||
"numberZero [Audiovisuals: meshgen]",
|
||||
"Giuseppe Bilotta",
|
||||
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
|
||||
"MirceaKitsune <mirceakitsune@gmail.com>",
|
||||
"Constantin Wenger (SpeedProg)",
|
||||
"Ciaran Gultnieks (CiaranG)",
|
||||
"stujones11 [Android UX improvements]",
|
||||
"Jeija <jeija@mesecons.net> [HTTP, particles]",
|
||||
"Vincent Glize (Dumbeldor) [Cleanups, CSM APIs]",
|
||||
"Ben Deutsch [Rendering, Fixes, SQLite auth]",
|
||||
"TeTpaAka [Hand overriding, nametag colors]",
|
||||
"Rui [Sound Pitch]",
|
||||
"Duane Robertson <duane@duanerobertson.com> [MGValleys]",
|
||||
"Raymoo [Tool Capabilities]",
|
||||
"Rogier <rogier777@gmail.com> [Fixes]",
|
||||
"Gregory Currie (gregorycu) [optimisation]",
|
||||
"TriBlade9 <triblade9@mail.com> [Audiovisuals]",
|
||||
"T4im [Profiler]",
|
||||
"Jurgen Doser (doserj) <jurgen.doser@gmail.com>",
|
||||
"srifqi [Fixes]",
|
||||
"JacobF",
|
||||
"Jeija <jeija@mesecons.net> [HTTP, particles]",
|
||||
}
|
||||
|
||||
local function buildCreditList(source)
|
||||
@ -105,8 +107,8 @@ local function buildCreditList(source)
|
||||
end
|
||||
|
||||
return {
|
||||
name = "credits",
|
||||
caption = fgettext("Credits"),
|
||||
name = "about",
|
||||
caption = fgettext("About"),
|
||||
cbf_formspec = function(tabview, name, tabdata)
|
||||
local logofile = defaulttexturedir .. "logo.png"
|
||||
local version = core.get_version()
|
||||
@ -129,11 +131,16 @@ return {
|
||||
buildCreditList(previous_contributors) .. "," ..
|
||||
";1]"
|
||||
|
||||
-- Render information
|
||||
fs = fs .. "label[0.75,4.9;" ..
|
||||
fgettext("Active renderer:") .. "\n" ..
|
||||
core.formspec_escape(core.get_screen_info().render_info) .. "]"
|
||||
|
||||
if PLATFORM ~= "Android" then
|
||||
fs = fs .. "tooltip[userdata;" ..
|
||||
fgettext("Opens the directory that contains user-provided worlds, games, mods,\n" ..
|
||||
"and texture packs in a file manager / explorer.") .. "]"
|
||||
fs = fs .. "button[0,4.75;3.5,1;userdata;" .. fgettext("Open User Data Directory") .. "]"
|
||||
fs = fs .. "button[0,4;3.5,1;userdata;" .. fgettext("Open User Data Directory") .. "]"
|
||||
end
|
||||
|
||||
return fs
|
@ -205,16 +205,28 @@ local function get_formspec(tabview, name, tabdata)
|
||||
return retval
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function handle_doubleclick(pkg, pkg_name)
|
||||
if pkg.type == "txp" then
|
||||
if core.settings:get("texture_path") == pkg.path then
|
||||
core.settings:set("texture_path", "")
|
||||
else
|
||||
core.settings:set("texture_path", pkg.path)
|
||||
end
|
||||
packages = nil
|
||||
elseif pkg.is_clientside then
|
||||
pkgmgr.enable_mod({data = {list = packages, selected_mod = pkg_name}})
|
||||
packages = nil
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function handle_buttons(tabview, fields, tabname, tabdata)
|
||||
if fields["pkglist"] ~= nil then
|
||||
local event = core.explode_table_event(fields["pkglist"])
|
||||
tabdata.selected_pkg = event.row
|
||||
local mod = packages:get_list()[tabdata.selected_pkg]
|
||||
|
||||
if event.type == "DCL" and mod.is_clientside then
|
||||
pkgmgr.enable_mod({data = {list = packages, selected_mod = tabdata.selected_pkg}})
|
||||
packages = nil
|
||||
if event.type == "DCL" then
|
||||
handle_doubleclick(packages:get_list()[tabdata.selected_pkg], tabdata.selected_pkg)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
@ -116,7 +116,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||
|
||||
retval = retval ..
|
||||
"button[3.9,3.8;2.8,1;world_delete;".. fgettext("Delete") .. "]" ..
|
||||
"button[6.55,3.8;2.8,1;world_configure;".. fgettext("Configure") .. "]" ..
|
||||
"button[6.55,3.8;2.8,1;world_configure;".. fgettext("Select Mods") .. "]" ..
|
||||
"button[9.2,3.8;2.8,1;world_create;".. fgettext("New") .. "]" ..
|
||||
"label[3.9,-0.05;".. fgettext("Select World:") .. "]"..
|
||||
"checkbox[0,-0.20;cb_creative_mode;".. fgettext("Creative Mode") .. ";" ..
|
||||
|
@ -15,17 +15,50 @@
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function get_sorted_servers()
|
||||
local servers = {
|
||||
fav = {},
|
||||
public = {},
|
||||
incompatible = {}
|
||||
}
|
||||
|
||||
local favs = serverlistmgr.get_favorites()
|
||||
local taken_favs = {}
|
||||
local result = menudata.search_result or serverlistmgr.servers
|
||||
for _, server in ipairs(result) do
|
||||
server.is_favorite = false
|
||||
for index, fav in ipairs(favs) do
|
||||
if server.address == fav.address and server.port == fav.port then
|
||||
taken_favs[index] = true
|
||||
server.is_favorite = true
|
||||
break
|
||||
end
|
||||
end
|
||||
server.is_compatible = is_server_protocol_compat(server.proto_min, server.proto_max)
|
||||
if server.is_favorite then
|
||||
table.insert(servers.fav, server)
|
||||
elseif server.is_compatible then
|
||||
table.insert(servers.public, server)
|
||||
else
|
||||
table.insert(servers.incompatible, server)
|
||||
end
|
||||
end
|
||||
|
||||
if not menudata.search_result then
|
||||
for index, fav in ipairs(favs) do
|
||||
if not taken_favs[index] then
|
||||
table.insert(servers.fav, fav)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return servers
|
||||
end
|
||||
|
||||
local function get_formspec(tabview, name, tabdata)
|
||||
-- Update the cached supported proto info,
|
||||
-- it may have changed after a change by the settings menu.
|
||||
common_update_cached_supp_proto()
|
||||
local fav_selected
|
||||
if menudata.search_result then
|
||||
fav_selected = menudata.search_result[tabdata.fav_selected]
|
||||
else
|
||||
fav_selected = menudata.favorites[tabdata.fav_selected]
|
||||
end
|
||||
|
||||
if not tabdata.search_for then
|
||||
tabdata.search_for = ""
|
||||
@ -33,129 +66,221 @@ local function get_formspec(tabview, name, tabdata)
|
||||
|
||||
local retval =
|
||||
-- Search
|
||||
"field[0.15,0.075;5.91,1;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" ..
|
||||
"image_button[5.63,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" ..
|
||||
"image_button[6.3,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "clear.png") .. ";btn_mp_clear;]" ..
|
||||
"image_button[6.97,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "refresh.png")
|
||||
.. ";btn_mp_refresh;]" ..
|
||||
"field[0.25,0.25;7,0.75;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" ..
|
||||
"container[7.25,0.25]" ..
|
||||
"image_button[0,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" ..
|
||||
"image_button[0.75,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "clear.png") .. ";btn_mp_clear;]" ..
|
||||
"image_button[1.5,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "refresh.png") .. ";btn_mp_refresh;]" ..
|
||||
"tooltip[btn_mp_clear;" .. fgettext("Clear") .. "]" ..
|
||||
"tooltip[btn_mp_search;" .. fgettext("Search") .. "]" ..
|
||||
"tooltip[btn_mp_refresh;" .. fgettext("Refresh") .. "]" ..
|
||||
"container_end[]" ..
|
||||
|
||||
"container[9.75,0]" ..
|
||||
"box[0,0;5.75,7;#666666]" ..
|
||||
|
||||
-- Address / Port
|
||||
"label[7.75,-0.25;" .. fgettext("Address / Port") .. "]" ..
|
||||
"field[8,0.65;3.25,0.5;te_address;;" ..
|
||||
"label[0.25,0.35;" .. fgettext("Address") .. "]" ..
|
||||
"label[4.25,0.35;" .. fgettext("Port") .. "]" ..
|
||||
"field[0.25,0.5;4,0.75;te_address;;" ..
|
||||
core.formspec_escape(core.settings:get("address")) .. "]" ..
|
||||
"field[11.1,0.65;1.4,0.5;te_port;;" ..
|
||||
"field[4.25,0.5;1.25,0.75;te_port;;" ..
|
||||
core.formspec_escape(core.settings:get("remote_port")) .. "]" ..
|
||||
|
||||
-- Name / Password
|
||||
"label[7.75,0.95;" .. fgettext("Name / Password") .. "]" ..
|
||||
"field[8,1.85;2.9,0.5;te_name;;" ..
|
||||
"label[0.25,1.55;" .. fgettext("Name") .. "]" ..
|
||||
"label[3,1.55;" .. fgettext("Password") .. "]" ..
|
||||
"field[0.25,1.75;2.75,0.75;te_name;;" ..
|
||||
core.formspec_escape(core.settings:get("name")) .. "]" ..
|
||||
"pwdfield[10.73,1.85;1.77,0.5;te_pwd;]" ..
|
||||
"pwdfield[3,1.75;2.5,0.75;te_pwd;]" ..
|
||||
|
||||
-- Description Background
|
||||
"box[7.73,2.25;4.25,2.6;#999999]"..
|
||||
"label[0.25,2.75;" .. fgettext("Server Description") .. "]" ..
|
||||
"box[0.25,3;5.25,2.75;#999999]"..
|
||||
|
||||
-- Connect
|
||||
"button[9.88,4.9;2.3,1;btn_mp_connect;" .. fgettext("Connect") .. "]"
|
||||
"button[3,6;2.5,0.75;btn_mp_connect;" .. fgettext("Connect") .. "]"
|
||||
|
||||
if tabdata.fav_selected and fav_selected then
|
||||
if tabdata.selected then
|
||||
if gamedata.fav then
|
||||
retval = retval .. "button[7.73,4.9;2.3,1;btn_delete_favorite;" ..
|
||||
retval = retval .. "button[0.25,6;2.5,0.75;btn_delete_favorite;" ..
|
||||
fgettext("Del. Favorite") .. "]"
|
||||
end
|
||||
if fav_selected.description then
|
||||
retval = retval .. "textarea[8.1,2.3;4.23,2.9;;;" ..
|
||||
core.formspec_escape((gamedata.serverdescription or ""), true) .. "]"
|
||||
if gamedata.serverdescription then
|
||||
retval = retval .. "textarea[0.25,3;5.25,2.75;;;" ..
|
||||
core.formspec_escape(gamedata.serverdescription) .. "]"
|
||||
end
|
||||
end
|
||||
|
||||
--favourites
|
||||
retval = retval .. "container_end[]"
|
||||
|
||||
-- Table
|
||||
retval = retval .. "tablecolumns[" ..
|
||||
image_column(fgettext("Favorite"), "favorite") .. ";" ..
|
||||
image_column(fgettext("Ping")) .. ",padding=0.25;" ..
|
||||
"color,span=3;" ..
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
--~ PvP = Player versus Player
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"image,tooltip=" .. fgettext("Ping") .. "," ..
|
||||
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
|
||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_ping_4.png") .. "," ..
|
||||
"2=" .. core.formspec_escape(defaulttexturedir .. "server_ping_3.png") .. "," ..
|
||||
"3=" .. core.formspec_escape(defaulttexturedir .. "server_ping_2.png") .. "," ..
|
||||
"4=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png") .. "," ..
|
||||
"5=" .. core.formspec_escape(defaulttexturedir .. "server_favorite.png") .. "," ..
|
||||
"6=" .. core.formspec_escape(defaulttexturedir .. "server_public.png") .. "," ..
|
||||
"7=" .. core.formspec_escape(defaulttexturedir .. "server_incompatible.png") .. ";" ..
|
||||
"color,span=1;" ..
|
||||
"text,padding=1]" ..
|
||||
"table[-0.15,0.6;7.75,5.15;favourites;"
|
||||
"text,align=inline;"..
|
||||
"color,span=1;" ..
|
||||
"text,align=inline,width=4.25;" ..
|
||||
"image,tooltip=" .. fgettext("Creative mode") .. "," ..
|
||||
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
|
||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_creative.png") .. "," ..
|
||||
"align=inline,padding=0.25,width=1.5;" ..
|
||||
--~ PvP = Player versus Player
|
||||
"image,tooltip=" .. fgettext("Damage / PvP") .. "," ..
|
||||
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
|
||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_damage.png") .. "," ..
|
||||
"2=" .. core.formspec_escape(defaulttexturedir .. "server_flags_pvp.png") .. "," ..
|
||||
"align=inline,padding=0.25,width=1.5;" ..
|
||||
"color,align=inline,span=1;" ..
|
||||
"text,align=inline,padding=1]" ..
|
||||
"table[0.25,1;9.25,5.75;servers;"
|
||||
|
||||
if menudata.search_result then
|
||||
for i = 1, #menudata.search_result do
|
||||
local favs = core.get_favorites("local")
|
||||
local server = menudata.search_result[i]
|
||||
local servers = get_sorted_servers()
|
||||
|
||||
for fav_id = 1, #favs do
|
||||
if server.address == favs[fav_id].address and
|
||||
server.port == favs[fav_id].port then
|
||||
server.is_favorite = true
|
||||
end
|
||||
end
|
||||
local dividers = {
|
||||
fav = "5,#ffff00," .. fgettext("Favorites") .. ",,,0,0,,",
|
||||
public = "6,#4bdd42," .. fgettext("Public Servers") .. ",,,0,0,,",
|
||||
incompatible = "7,"..mt_color_grey.."," .. fgettext("Incompatible Servers") .. ",,,0,0,,"
|
||||
}
|
||||
local order = {"fav", "public", "incompatible"}
|
||||
|
||||
if i ~= 1 then
|
||||
retval = retval .. ","
|
||||
tabdata.lookup = {} -- maps row number to server
|
||||
local rows = {}
|
||||
for _, section in ipairs(order) do
|
||||
local section_servers = servers[section]
|
||||
if next(section_servers) ~= nil then
|
||||
rows[#rows + 1] = dividers[section]
|
||||
for _, server in ipairs(section_servers) do
|
||||
tabdata.lookup[#rows + 1] = server
|
||||
rows[#rows + 1] = render_serverlist_row(server)
|
||||
end
|
||||
|
||||
retval = retval .. render_serverlist_row(server, server.is_favorite)
|
||||
end
|
||||
elseif #menudata.favorites > 0 then
|
||||
local favs = core.get_favorites("local")
|
||||
if #favs > 0 then
|
||||
for i = 1, #favs do
|
||||
for j = 1, #menudata.favorites do
|
||||
if menudata.favorites[j].address == favs[i].address and
|
||||
menudata.favorites[j].port == favs[i].port then
|
||||
table.insert(menudata.favorites, i, table.remove(menudata.favorites, j))
|
||||
end
|
||||
end
|
||||
if favs[i].address ~= menudata.favorites[i].address then
|
||||
table.insert(menudata.favorites, i, favs[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
retval = retval .. render_serverlist_row(menudata.favorites[1], (#favs > 0))
|
||||
for i = 2, #menudata.favorites do
|
||||
retval = retval .. "," .. render_serverlist_row(menudata.favorites[i], (i <= #favs))
|
||||
end
|
||||
end
|
||||
|
||||
if tabdata.fav_selected then
|
||||
retval = retval .. ";" .. tabdata.fav_selected .. "]"
|
||||
retval = retval .. table.concat(rows, ",")
|
||||
|
||||
if tabdata.selected then
|
||||
retval = retval .. ";" .. tabdata.selected .. "]"
|
||||
else
|
||||
retval = retval .. ";0]"
|
||||
end
|
||||
|
||||
return retval
|
||||
return retval, "size[15.5,7,false]real_coordinates[true]"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
local serverlist = menudata.search_result or menudata.favorites
|
||||
|
||||
local function search_server_list(input)
|
||||
menudata.search_result = nil
|
||||
if #serverlistmgr.servers < 2 then
|
||||
return
|
||||
end
|
||||
|
||||
-- setup the keyword list
|
||||
local keywords = {}
|
||||
for word in input:gmatch("%S+") do
|
||||
word = word:gsub("(%W)", "%%%1")
|
||||
table.insert(keywords, word)
|
||||
end
|
||||
|
||||
if #keywords == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
menudata.search_result = {}
|
||||
|
||||
-- Search the serverlist
|
||||
local search_result = {}
|
||||
for i = 1, #serverlistmgr.servers do
|
||||
local server = serverlistmgr.servers[i]
|
||||
local found = 0
|
||||
for k = 1, #keywords do
|
||||
local keyword = keywords[k]
|
||||
if server.name then
|
||||
local sername = server.name:lower()
|
||||
local _, count = sername:gsub(keyword, keyword)
|
||||
found = found + count * 4
|
||||
end
|
||||
|
||||
if server.description then
|
||||
local desc = server.description:lower()
|
||||
local _, count = desc:gsub(keyword, keyword)
|
||||
found = found + count * 2
|
||||
end
|
||||
end
|
||||
if found > 0 then
|
||||
local points = (#serverlistmgr.servers - i) / 5 + found
|
||||
server.points = points
|
||||
table.insert(search_result, server)
|
||||
end
|
||||
end
|
||||
|
||||
if #search_result == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
table.sort(search_result, function(a, b)
|
||||
return a.points > b.points
|
||||
end)
|
||||
menudata.search_result = search_result
|
||||
end
|
||||
|
||||
local function set_selected_server(tabdata, idx, server)
|
||||
-- reset selection
|
||||
if idx == nil or server == nil then
|
||||
tabdata.selected = nil
|
||||
|
||||
core.settings:set("address", "")
|
||||
core.settings:set("remote_port", "30000")
|
||||
return
|
||||
end
|
||||
|
||||
local address = server.address
|
||||
local port = server.port
|
||||
gamedata.serverdescription = server.description
|
||||
|
||||
gamedata.fav = false
|
||||
for _, fav in ipairs(serverlistmgr.get_favorites()) do
|
||||
if address == fav.address and port == fav.port then
|
||||
gamedata.fav = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if address and port then
|
||||
core.settings:set("address", address)
|
||||
core.settings:set("remote_port", port)
|
||||
end
|
||||
tabdata.selected = idx
|
||||
end
|
||||
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
if fields.te_name then
|
||||
gamedata.playername = fields.te_name
|
||||
core.settings:set("name", fields.te_name)
|
||||
end
|
||||
|
||||
if fields.favourites then
|
||||
local event = core.explode_table_event(fields.favourites)
|
||||
local fav = serverlist[event.row]
|
||||
if fields.servers then
|
||||
local event = core.explode_table_event(fields.servers)
|
||||
local server = tabdata.lookup[event.row]
|
||||
|
||||
if event.type == "DCL" then
|
||||
if event.row <= #serverlist then
|
||||
if menudata.favorites_is_public and
|
||||
not is_server_protocol_compat_or_error(
|
||||
fav.proto_min, fav.proto_max) then
|
||||
if server then
|
||||
if event.type == "DCL" then
|
||||
if not is_server_protocol_compat_or_error(
|
||||
server.proto_min, server.proto_max) then
|
||||
return true
|
||||
end
|
||||
|
||||
gamedata.address = fav.address
|
||||
gamedata.port = fav.port
|
||||
gamedata.address = server.address
|
||||
gamedata.port = server.port
|
||||
gamedata.playername = fields.te_name
|
||||
gamedata.selected_world = 0
|
||||
|
||||
@ -163,84 +288,32 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
gamedata.password = fields.te_pwd
|
||||
end
|
||||
|
||||
gamedata.servername = fav.name
|
||||
gamedata.serverdescription = fav.description
|
||||
gamedata.servername = server.name
|
||||
gamedata.serverdescription = server.description
|
||||
|
||||
if gamedata.address and gamedata.port then
|
||||
core.settings:set("address", gamedata.address)
|
||||
core.settings:set("remote_port", gamedata.port)
|
||||
core.start()
|
||||
end
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if event.type == "CHG" then
|
||||
if event.row <= #serverlist then
|
||||
gamedata.fav = false
|
||||
local favs = core.get_favorites("local")
|
||||
local address = fav.address
|
||||
local port = fav.port
|
||||
gamedata.serverdescription = fav.description
|
||||
|
||||
for i = 1, #favs do
|
||||
if fav.address == favs[i].address and
|
||||
fav.port == favs[i].port then
|
||||
gamedata.fav = true
|
||||
end
|
||||
end
|
||||
|
||||
if address and port then
|
||||
core.settings:set("address", address)
|
||||
core.settings:set("remote_port", port)
|
||||
end
|
||||
tabdata.fav_selected = event.row
|
||||
if event.type == "CHG" then
|
||||
set_selected_server(tabdata, event.row, server)
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if fields.key_up or fields.key_down then
|
||||
local fav_idx = core.get_table_index("favourites")
|
||||
local fav = serverlist[fav_idx]
|
||||
|
||||
if fav_idx then
|
||||
if fields.key_up and fav_idx > 1 then
|
||||
fav_idx = fav_idx - 1
|
||||
elseif fields.key_down and fav_idx < #menudata.favorites then
|
||||
fav_idx = fav_idx + 1
|
||||
end
|
||||
else
|
||||
fav_idx = 1
|
||||
end
|
||||
|
||||
if not menudata.favorites or not fav then
|
||||
tabdata.fav_selected = 0
|
||||
return true
|
||||
end
|
||||
|
||||
local address = fav.address
|
||||
local port = fav.port
|
||||
gamedata.serverdescription = fav.description
|
||||
if address and port then
|
||||
core.settings:set("address", address)
|
||||
core.settings:set("remote_port", port)
|
||||
end
|
||||
|
||||
tabdata.fav_selected = fav_idx
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.btn_delete_favorite then
|
||||
local current_favourite = core.get_table_index("favourites")
|
||||
if not current_favourite then return end
|
||||
local idx = core.get_table_index("servers")
|
||||
if not idx then return end
|
||||
local server = tabdata.lookup[idx]
|
||||
if not server then return end
|
||||
|
||||
core.delete_favorite(current_favourite)
|
||||
asyncOnlineFavourites()
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.settings:set("address", "")
|
||||
core.settings:set("remote_port", "30000")
|
||||
serverlistmgr.delete_favorite(server)
|
||||
-- the server at [idx+1] will be at idx once list is refreshed
|
||||
set_selected_server(tabdata, idx, tabdata.lookup[idx+1])
|
||||
return true
|
||||
end
|
||||
|
||||
@ -251,68 +324,18 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
end
|
||||
|
||||
if fields.btn_mp_search or fields.key_enter_field == "te_search" then
|
||||
tabdata.fav_selected = 1
|
||||
local input = fields.te_search:lower()
|
||||
tabdata.search_for = fields.te_search
|
||||
|
||||
if #menudata.favorites < 2 then
|
||||
return true
|
||||
search_server_list(fields.te_search:lower())
|
||||
if menudata.search_result then
|
||||
-- first server in row 2 due to header
|
||||
set_selected_server(tabdata, 2, menudata.search_result[1])
|
||||
end
|
||||
|
||||
menudata.search_result = {}
|
||||
|
||||
-- setup the keyword list
|
||||
local keywords = {}
|
||||
for word in input:gmatch("%S+") do
|
||||
word = word:gsub("(%W)", "%%%1")
|
||||
table.insert(keywords, word)
|
||||
end
|
||||
|
||||
if #keywords == 0 then
|
||||
menudata.search_result = nil
|
||||
return true
|
||||
end
|
||||
|
||||
-- Search the serverlist
|
||||
local search_result = {}
|
||||
for i = 1, #menudata.favorites do
|
||||
local server = menudata.favorites[i]
|
||||
local found = 0
|
||||
for k = 1, #keywords do
|
||||
local keyword = keywords[k]
|
||||
if server.name then
|
||||
local sername = server.name:lower()
|
||||
local _, count = sername:gsub(keyword, keyword)
|
||||
found = found + count * 4
|
||||
end
|
||||
|
||||
if server.description then
|
||||
local desc = server.description:lower()
|
||||
local _, count = desc:gsub(keyword, keyword)
|
||||
found = found + count * 2
|
||||
end
|
||||
end
|
||||
if found > 0 then
|
||||
local points = (#menudata.favorites - i) / 5 + found
|
||||
server.points = points
|
||||
table.insert(search_result, server)
|
||||
end
|
||||
end
|
||||
if #search_result > 0 then
|
||||
table.sort(search_result, function(a, b)
|
||||
return a.points > b.points
|
||||
end)
|
||||
menudata.search_result = search_result
|
||||
local first_server = search_result[1]
|
||||
core.settings:set("address", first_server.address)
|
||||
core.settings:set("remote_port", first_server.port)
|
||||
gamedata.serverdescription = first_server.description
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.btn_mp_refresh then
|
||||
asyncOnlineFavourites()
|
||||
serverlistmgr.sync()
|
||||
return true
|
||||
end
|
||||
|
||||
@ -321,43 +344,51 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
gamedata.playername = fields.te_name
|
||||
gamedata.password = fields.te_pwd
|
||||
gamedata.address = fields.te_address
|
||||
gamedata.port = fields.te_port
|
||||
gamedata.port = tonumber(fields.te_port)
|
||||
gamedata.selected_world = 0
|
||||
local fav_idx = core.get_table_index("favourites")
|
||||
local fav = serverlist[fav_idx]
|
||||
|
||||
if fav_idx and fav_idx <= #serverlist and
|
||||
fav.address == fields.te_address and
|
||||
fav.port == fields.te_port then
|
||||
local idx = core.get_table_index("servers")
|
||||
local server = idx and tabdata.lookup[idx]
|
||||
|
||||
gamedata.servername = fav.name
|
||||
gamedata.serverdescription = fav.description
|
||||
set_selected_server(tabdata)
|
||||
|
||||
if menudata.favorites_is_public and
|
||||
not is_server_protocol_compat_or_error(
|
||||
fav.proto_min, fav.proto_max) then
|
||||
if server and server.address == gamedata.address and
|
||||
server.port == gamedata.port then
|
||||
|
||||
serverlistmgr.add_favorite(server)
|
||||
|
||||
gamedata.servername = server.name
|
||||
gamedata.serverdescription = server.description
|
||||
|
||||
if not is_server_protocol_compat_or_error(
|
||||
server.proto_min, server.proto_max) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
|
||||
serverlistmgr.add_favorite({
|
||||
address = gamedata.address,
|
||||
port = gamedata.port,
|
||||
})
|
||||
end
|
||||
|
||||
core.settings:set("address", fields.te_address)
|
||||
core.settings:set("remote_port", fields.te_port)
|
||||
core.settings:set("address", gamedata.address)
|
||||
core.settings:set("remote_port", gamedata.port)
|
||||
|
||||
core.start()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function on_change(type, old_tab, new_tab)
|
||||
if type == "LEAVE" then return end
|
||||
asyncOnlineFavourites()
|
||||
serverlistmgr.sync()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
return {
|
||||
name = "online",
|
||||
caption = fgettext("Join Game"),
|
||||
|
29
builtin/mainmenu/tests/favorites_wellformed.txt
Normal file
@ -0,0 +1,29 @@
|
||||
[server]
|
||||
|
||||
127.0.0.1
|
||||
30000
|
||||
|
||||
|
||||
[server]
|
||||
|
||||
localhost
|
||||
30000
|
||||
|
||||
|
||||
[server]
|
||||
|
||||
vps.rubenwardy.com
|
||||
30001
|
||||
|
||||
|
||||
[server]
|
||||
|
||||
gundul.ddnss.de
|
||||
39155
|
||||
|
||||
|
||||
[server]
|
||||
VanessaE's Dreambuilder creative Server
|
||||
daconcepts.com
|
||||
30000
|
||||
VanessaE's Dreambuilder creative-mode server. Lots of mods, whitelisted buckets.
|
36
builtin/mainmenu/tests/serverlistmgr_spec.lua
Normal file
@ -0,0 +1,36 @@
|
||||
_G.core = {}
|
||||
_G.unpack = table.unpack
|
||||
_G.serverlistmgr = {}
|
||||
|
||||
dofile("builtin/common/misc_helpers.lua")
|
||||
dofile("builtin/mainmenu/serverlistmgr.lua")
|
||||
|
||||
local base = "builtin/mainmenu/tests/"
|
||||
|
||||
describe("legacy favorites", function()
|
||||
it("loads well-formed correctly", function()
|
||||
local favs = serverlistmgr.read_legacy_favorites(base .. "favorites_wellformed.txt")
|
||||
|
||||
local expected = {
|
||||
{
|
||||
address = "127.0.0.1",
|
||||
port = 30000,
|
||||
},
|
||||
|
||||
{ address = "localhost", port = 30000 },
|
||||
|
||||
{ address = "vps.rubenwardy.com", port = 30001 },
|
||||
|
||||
{ address = "gundul.ddnss.de", port = 39155 },
|
||||
|
||||
{
|
||||
address = "daconcepts.com",
|
||||
port = 30000,
|
||||
name = "VanessaE's Dreambuilder creative Server",
|
||||
description = "VanessaE's Dreambuilder creative-mode server. Lots of mods, whitelisted buckets."
|
||||
},
|
||||
}
|
||||
|
||||
assert.same(expected, favs)
|
||||
end)
|
||||
end)
|
@ -15,6 +15,8 @@
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
local S = core.get_translator("__builtin")
|
||||
|
||||
local function get_bool_default(name, default)
|
||||
local val = core.settings:get_bool(name)
|
||||
if val == nil then
|
||||
@ -40,9 +42,9 @@ function profiler.init_chatcommand()
|
||||
instrumentation.init_chatcommand()
|
||||
end
|
||||
|
||||
local param_usage = "print [filter] | dump [filter] | save [format [filter]] | reset"
|
||||
local param_usage = S("print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset")
|
||||
core.register_chatcommand("profiler", {
|
||||
description = "handle the profiler and profiling data",
|
||||
description = S("Handle the profiler and profiling data"),
|
||||
params = param_usage,
|
||||
privs = { server=true },
|
||||
func = function(name, param)
|
||||
@ -51,21 +53,19 @@ function profiler.init_chatcommand()
|
||||
|
||||
if command == "dump" then
|
||||
core.log("action", reporter.print(sampler.profile, arg0))
|
||||
return true, "Statistics written to action log"
|
||||
return true, S("Statistics written to action log.")
|
||||
elseif command == "print" then
|
||||
return true, reporter.print(sampler.profile, arg0)
|
||||
elseif command == "save" then
|
||||
return reporter.save(sampler.profile, args[1] or "txt", args[2])
|
||||
elseif command == "reset" then
|
||||
sampler.reset()
|
||||
return true, "Statistics were reset"
|
||||
return true, S("Statistics were reset.")
|
||||
end
|
||||
|
||||
return false, string.format(
|
||||
"Usage: %s\n" ..
|
||||
"Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).",
|
||||
param_usage
|
||||
)
|
||||
return false,
|
||||
S("Usage: @1", param_usage) .. "\n" ..
|
||||
S("Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).")
|
||||
end
|
||||
})
|
||||
|
||||
|
@ -15,6 +15,10 @@
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
local S = core.get_translator("__builtin")
|
||||
-- Note: In this file, only messages are translated
|
||||
-- but not the table itself, to keep it simple.
|
||||
|
||||
local DIR_DELIM, LINE_DELIM = DIR_DELIM, "\n"
|
||||
local table, unpack, string, pairs, io, os = table, unpack, string, pairs, io, os
|
||||
local rep, sprintf, tonumber = string.rep, string.format, tonumber
|
||||
@ -104,11 +108,11 @@ local TxtFormatter = Formatter:new {
|
||||
end,
|
||||
format = function(self, filter)
|
||||
local profile = self.profile
|
||||
self:print("Values below show absolute/relative times spend per server step by the instrumented function.")
|
||||
self:print("A total of %d samples were taken", profile.stats_total.samples)
|
||||
self:print(S("Values below show absolute/relative times spend per server step by the instrumented function."))
|
||||
self:print(S("A total of @1 sample(s) were taken.", profile.stats_total.samples))
|
||||
|
||||
if filter then
|
||||
self:print("The output is limited to '%s'", filter)
|
||||
self:print(S("The output is limited to '@1'.", filter))
|
||||
end
|
||||
|
||||
self:print()
|
||||
@ -259,19 +263,18 @@ function reporter.save(profile, format, filter)
|
||||
|
||||
local output, io_err = io.open(path, "w")
|
||||
if not output then
|
||||
return false, "Saving of profile failed with: " .. io_err
|
||||
return false, S("Saving of profile failed: @1", io_err)
|
||||
end
|
||||
local content, err = serialize_profile(profile, format, filter)
|
||||
if not content then
|
||||
output:close()
|
||||
return false, "Saving of profile failed with: " .. err
|
||||
return false, S("Saving of profile failed: @1", err)
|
||||
end
|
||||
output:write(content)
|
||||
output:close()
|
||||
|
||||
local logmessage = "Profile saved to " .. path
|
||||
core.log("action", logmessage)
|
||||
return true, logmessage
|
||||
core.log("action", "Profile saved to " .. path)
|
||||
return true, S("Profile saved to @1", path)
|
||||
end
|
||||
|
||||
return reporter
|
||||
|
@ -75,7 +75,7 @@ free_move (Flying) bool false
|
||||
# If enabled, makes move directions relative to the player's pitch when flying or swimming.
|
||||
pitch_move (Pitch move mode) bool false
|
||||
|
||||
# Fast movement (via the "special" key).
|
||||
# Fast movement (via the "Aux1" key).
|
||||
# This requires the "fast" privilege on the server.
|
||||
fast_move (Fast movement) bool false
|
||||
|
||||
@ -99,14 +99,14 @@ invert_mouse (Invert mouse) bool false
|
||||
# Mouse sensitivity multiplier.
|
||||
mouse_sensitivity (Mouse sensitivity) float 0.2
|
||||
|
||||
# If enabled, "special" key instead of "sneak" key is used for climbing down and
|
||||
# If enabled, "Aux1" key instead of "Sneak" key is used for climbing down and
|
||||
# descending.
|
||||
aux1_descends (Special key for climbing/descending) bool false
|
||||
aux1_descends (Aux1 key for climbing/descending) bool false
|
||||
|
||||
# Double-tapping the jump key toggles fly mode.
|
||||
doubletap_jump (Double tap jump for fly) bool false
|
||||
|
||||
# If disabled, "special" key is used to fly fast if both fly and fast mode are
|
||||
# If disabled, "Aux1" key is used to fly fast if both fly and fast mode are
|
||||
# enabled.
|
||||
always_fly_fast (Always fly and fast) bool true
|
||||
|
||||
@ -135,9 +135,9 @@ touchscreen_threshold (Touch screen threshold) int 20 0 100
|
||||
# If disabled, virtual joystick will center to first-touch's position.
|
||||
fixed_virtual_joystick (Fixed virtual joystick) bool false
|
||||
|
||||
# (Android) Use virtual joystick to trigger "aux" button.
|
||||
# If enabled, virtual joystick will also tap "aux" button when out of main circle.
|
||||
virtual_joystick_triggers_aux (Virtual joystick triggers aux button) bool false
|
||||
# (Android) Use virtual joystick to trigger "Aux1" button.
|
||||
# If enabled, virtual joystick will also tap "Aux1" button when out of main circle.
|
||||
virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool false
|
||||
|
||||
# Enable joysticks
|
||||
enable_joysticks (Enable joysticks) bool false
|
||||
@ -203,7 +203,7 @@ keymap_special_inventory (Special inventory key) key KEY_KEY_O
|
||||
|
||||
# Key for moving fast in fast mode.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_special1 (Special key) key KEY_KEY_E
|
||||
keymap_aux1 (Aux1 key) key KEY_KEY_E
|
||||
|
||||
# Key for opening the chat window.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
@ -463,6 +463,10 @@ keymap_decrease_viewing_range_min (View range decrease key) key -
|
||||
|
||||
[**Basic]
|
||||
|
||||
# Whether nametag backgrounds should be shown by default.
|
||||
# Mods may still set a background.
|
||||
show_nametag_backgrounds (Show nametag backgrounds by default) bool true
|
||||
|
||||
# Enable vertex buffer objects.
|
||||
# This should greatly improve graphics performance.
|
||||
enable_vbo (VBO) bool true
|
||||
@ -512,18 +516,17 @@ bilinear_filter (Bilinear filtering) bool false
|
||||
trilinear_filter (Trilinear filtering) bool false
|
||||
|
||||
# Filtered textures can blend RGB values with fully-transparent neighbors,
|
||||
# which PNG optimizers usually discard, sometimes resulting in a dark or
|
||||
# light edge to transparent textures. Apply this filter to clean that up
|
||||
# at texture load time.
|
||||
# which PNG optimizers usually discard, often resulting in dark or
|
||||
# light edges to transparent textures. Apply a filter to clean that up
|
||||
# at texture load time. This is automatically enabled if mipmapping is enabled.
|
||||
texture_clean_transparent (Clean transparent textures) bool false
|
||||
|
||||
# When using bilinear/trilinear/anisotropic filters, low-resolution textures
|
||||
# can be blurred, so automatically upscale them with nearest-neighbor
|
||||
# interpolation to preserve crisp pixels. This sets the minimum texture size
|
||||
# for the upscaled textures; higher values look sharper, but require more
|
||||
# memory. Powers of 2 are recommended. Setting this higher than 1 may not
|
||||
# have a visible effect unless bilinear/trilinear/anisotropic filtering is
|
||||
# enabled.
|
||||
# memory. Powers of 2 are recommended. This setting is ONLY applies if
|
||||
# bilinear/trilinear/anisotropic filtering is enabled.
|
||||
# This is also used as the base node texture size for world-aligned
|
||||
# texture autoscaling.
|
||||
texture_min_size (Minimum texture size) int 64
|
||||
@ -670,7 +673,7 @@ lighting_boost_spread (Light curve boost spread) float 0.2 0.0 0.4
|
||||
# Path to texture directory. All textures are first searched from here.
|
||||
texture_path (Texture path) path
|
||||
|
||||
# The rendering back-end for Irrlicht.
|
||||
# The rendering back-end.
|
||||
# A restart is required after changing this.
|
||||
# Note: On Android, stick with OGLES1 if unsure! App may fail to start otherwise.
|
||||
# On other platforms, OpenGL is recommended.
|
||||
@ -867,7 +870,7 @@ font_path (Regular font path) filepath fonts/Arimo-Regular.ttf
|
||||
|
||||
font_path_bold (Bold font path) filepath fonts/Arimo-Bold.ttf
|
||||
font_path_italic (Italic font path) filepath fonts/Arimo-Italic.ttf
|
||||
font_path_bolditalic (Bold and italic font path) filepath fonts/Arimo-BoldItalic.ttf
|
||||
font_path_bold_italic (Bold and italic font path) filepath fonts/Arimo-BoldItalic.ttf
|
||||
|
||||
# Font size of the monospace font in point (pt).
|
||||
mono_font_size (Monospace font size) int 15 1
|
||||
@ -880,16 +883,7 @@ mono_font_path (Monospace font path) filepath fonts/Cousine-Regular.ttf
|
||||
|
||||
mono_font_path_bold (Bold monospace font path) filepath fonts/Cousine-Bold.ttf
|
||||
mono_font_path_italic (Italic monospace font path) filepath fonts/Cousine-Italic.ttf
|
||||
mono_font_path_bolditalic (Bold and italic monospace font path) filepath fonts/Cousine-BoldItalic.ttf
|
||||
|
||||
# Font size of the fallback font in point (pt).
|
||||
fallback_font_size (Fallback font size) int 15 1
|
||||
|
||||
# Shadow offset (in pixels) of the fallback font. If 0, then shadow will not be drawn.
|
||||
fallback_font_shadow (Fallback font shadow) int 1
|
||||
|
||||
# Opaqueness (alpha) of the shadow behind the fallback font, between 0 and 255.
|
||||
fallback_font_shadow_alpha (Fallback font shadow alpha) int 128 0 255
|
||||
mono_font_path_bold_italic (Bold and italic monospace font path) filepath fonts/Cousine-BoldItalic.ttf
|
||||
|
||||
# Path of the fallback font.
|
||||
# If “freetype” setting is enabled: Must be a TrueType font.
|
||||
@ -976,7 +970,7 @@ serverlist_url (Serverlist URL) string servers.minetest.net
|
||||
|
||||
# File in client/serverlist/ that contains your favorite servers displayed in the
|
||||
# Multiplayer Tab.
|
||||
serverlist_file (Serverlist file) string favoriteservers.txt
|
||||
serverlist_file (Serverlist file) string favoriteservers.json
|
||||
|
||||
# Maximum size of the out chat queue.
|
||||
# 0 to disable queueing and -1 to make the queue size unlimited.
|
||||
@ -1097,7 +1091,7 @@ default_stack_max (Default stack size) int 99
|
||||
# Enable players getting damage and dying.
|
||||
enable_damage (Damage) bool false
|
||||
|
||||
# Enable creative mode for new created maps.
|
||||
# Enable creative mode for all players
|
||||
creative_mode (Creative) bool false
|
||||
|
||||
# A chosen map seed for a new map, leave empty for random.
|
||||
@ -1144,6 +1138,10 @@ enable_rollback_recording (Rollback recording) bool false
|
||||
# @name, @message, @timestamp (optional)
|
||||
chat_message_format (Chat message format) string <@name> @message
|
||||
|
||||
# If the execution of a chat command takes longer than this specified time in
|
||||
# seconds, add the time information to the chat command message
|
||||
chatcommand_msg_time_threshold (Chat command time message threshold) float 0.1
|
||||
|
||||
# A message to be displayed to all clients when the server shuts down.
|
||||
kick_msg_shutdown (Shutdown message) string Server shutting down.
|
||||
|
||||
@ -1399,7 +1397,7 @@ name (Player name) string
|
||||
|
||||
# Set the language. Leave empty to use the system language.
|
||||
# A restart is required after changing this.
|
||||
language (Language) enum ,ar,ca,cs,da,de,dv,el,en,eo,es,et,eu,fil,fr,hu,id,it,ja,ja_KS,jbo,kk,kn,lo,lt,ms,my,nb,nl,nn,pl,pt,pt_BR,ro,ru,sl,sr_Cyrl,sv,sw,th,tr,uk,vi
|
||||
language (Language) enum ,be,bg,ca,cs,da,de,el,en,eo,es,et,eu,fi,fr,gd,gl,hu,id,it,ja,jbo,kk,ko,lt,lv,ms,nb,nl,nn,pl,pt,pt_BR,ro,ru,sk,sl,sr_Cyrl,sr_Latn,sv,sw,tr,uk,vi,zh_CN,zh_TW
|
||||
|
||||
# Level of logging to be written to debug.txt:
|
||||
# - <nothing> (no logging)
|
||||
@ -1426,9 +1424,8 @@ enable_ipv6 (IPv6) bool true
|
||||
|
||||
[*Advanced]
|
||||
|
||||
# Default timeout for cURL, stated in milliseconds.
|
||||
# Only has an effect if compiled with cURL.
|
||||
curl_timeout (cURL timeout) int 5000
|
||||
# Maximum time an interactive request (e.g. server list fetch) may take, stated in milliseconds.
|
||||
curl_timeout (cURL interactive timeout) int 20000
|
||||
|
||||
# Limits number of parallel HTTP requests. Affects:
|
||||
# - Media fetch if server uses remote_media setting.
|
||||
@ -1437,7 +1434,7 @@ curl_timeout (cURL timeout) int 5000
|
||||
# Only has an effect if compiled with cURL.
|
||||
curl_parallel_limit (cURL parallel limit) int 8
|
||||
|
||||
# Maximum time in ms a file download (e.g. a mod download) may take.
|
||||
# Maximum time a file download (e.g. a mod download) may take, stated in milliseconds.
|
||||
curl_file_download_timeout (cURL file download timeout) int 300000
|
||||
|
||||
# Makes DirectX work with LuaJIT. Disable if it causes troubles.
|
||||
|
@ -6,7 +6,7 @@ uniform sampler2D textureFlags;
|
||||
#define rightImage normalTexture
|
||||
#define maskImage textureFlags
|
||||
|
||||
varying mediump vec2 varTexCoord;
|
||||
varying mediump vec4 varTexCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
varying mediump vec2 varTexCoord;
|
||||
varying mediump vec4 varTexCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
@ -3,5 +3,9 @@ varying lowp vec4 varColor;
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = mWorldViewProj * inVertexPosition;
|
||||
#ifdef GL_ES
|
||||
varColor = inVertexColor.bgra;
|
||||
#else
|
||||
varColor = inVertexColor;
|
||||
#endif
|
||||
}
|
||||
|
@ -7,5 +7,9 @@ void main(void)
|
||||
{
|
||||
varTexCoord = inTexCoord0.st;
|
||||
gl_Position = mWorldViewProj * inVertexPosition;
|
||||
#ifdef GL_ES
|
||||
varColor = inVertexColor.bgra;
|
||||
#else
|
||||
varColor = inVertexColor;
|
||||
#endif
|
||||
}
|
||||
|
@ -146,10 +146,14 @@ void main(void)
|
||||
// the brightness, so now we have to multiply these
|
||||
// colors with the color of the incoming light.
|
||||
// The pre-baked colors are halved to prevent overflow.
|
||||
vec4 color;
|
||||
#ifdef GL_ES
|
||||
vec4 color = inVertexColor.bgra;
|
||||
#else
|
||||
vec4 color = inVertexColor;
|
||||
#endif
|
||||
// The alpha gives the ratio of sunlight in the incoming light.
|
||||
float nightRatio = 1.0 - inVertexColor.a;
|
||||
color.rgb = inVertexColor.rgb * (inVertexColor.a * dayLight.rgb +
|
||||
float nightRatio = 1.0 - color.a;
|
||||
color.rgb = color.rgb * (color.a * dayLight.rgb +
|
||||
nightRatio * artificialLight.rgb) * 2.0;
|
||||
color.a = 1.0;
|
||||
|
||||
|
@ -49,5 +49,9 @@ void main(void)
|
||||
: directional_ambient(normalize(inVertexNormal));
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
varColor = inVertexColor.bgra;
|
||||
#else
|
||||
varColor = inVertexColor;
|
||||
#endif
|
||||
}
|
||||
|
@ -6,5 +6,9 @@ void main(void)
|
||||
varTexCoord = inTexCoord0.st;
|
||||
gl_Position = mWorldViewProj * inVertexPosition;
|
||||
|
||||
#ifdef GL_ES
|
||||
varColor = inVertexColor.bgra;
|
||||
#else
|
||||
varColor = inVertexColor;
|
||||
#endif
|
||||
}
|
||||
|
1
clientmods/preview/mod.conf
Normal file
@ -0,0 +1 @@
|
||||
name = preview
|
@ -12,8 +12,6 @@ if(ENABLE_SYSTEM_GMP)
|
||||
else()
|
||||
message (STATUS "Detecting GMP from system failed.")
|
||||
endif()
|
||||
else()
|
||||
message (STATUS "Detecting GMP from system disabled! (ENABLE_SYSTEM_GMP=0)")
|
||||
endif()
|
||||
|
||||
if(NOT USE_SYSTEM_GMP)
|
||||
|
@ -42,15 +42,6 @@ if(WIN32)
|
||||
NAMES ${GETTEXT_LIB_NAMES}
|
||||
PATHS "${CUSTOM_GETTEXT_PATH}/lib"
|
||||
DOC "GetText library")
|
||||
find_file(GETTEXT_DLL
|
||||
NAMES libintl.dll intl.dll libintl3.dll intl3.dll
|
||||
PATHS "${CUSTOM_GETTEXT_PATH}/bin" "${CUSTOM_GETTEXT_PATH}/lib"
|
||||
DOC "gettext *intl*.dll")
|
||||
find_file(GETTEXT_ICONV_DLL
|
||||
NAMES libiconv2.dll
|
||||
PATHS "${CUSTOM_GETTEXT_PATH}/bin" "${CUSTOM_GETTEXT_PATH}/lib"
|
||||
DOC "gettext *iconv*.lib")
|
||||
set(GETTEXT_REQUIRED_VARS ${GETTEXT_REQUIRED_VARS} GETTEXT_DLL GETTEXT_ICONV_DLL)
|
||||
endif(WIN32)
|
||||
|
||||
|
||||
|
@ -1,73 +1,57 @@
|
||||
|
||||
mark_as_advanced(IRRLICHT_LIBRARY IRRLICHT_INCLUDE_DIR IRRLICHT_DLL)
|
||||
set(IRRLICHT_SOURCE_DIR "" CACHE PATH "Path to irrlicht source directory (optional)")
|
||||
mark_as_advanced(IRRLICHT_DLL)
|
||||
|
||||
# Find include directory and libraries
|
||||
|
||||
# Find include directory
|
||||
|
||||
if(NOT IRRLICHT_SOURCE_DIR STREQUAL "")
|
||||
set(IRRLICHT_SOURCE_DIR_INCLUDE
|
||||
"${IRRLICHT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
set(IRRLICHT_LIBRARY_NAMES libIrrlicht.a Irrlicht Irrlicht.lib)
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
set(IRRLICHT_SOURCE_DIR_LIBS "${IRRLICHT_SOURCE_DIR}/lib/Win32-visualstudio")
|
||||
set(IRRLICHT_LIBRARY_NAMES Irrlicht.lib)
|
||||
else()
|
||||
set(IRRLICHT_SOURCE_DIR_LIBS "${IRRLICHT_SOURCE_DIR}/lib/Win32-gcc")
|
||||
set(IRRLICHT_LIBRARY_NAMES libIrrlicht.a libIrrlicht.dll.a)
|
||||
endif()
|
||||
else()
|
||||
set(IRRLICHT_SOURCE_DIR_LIBS "${IRRLICHT_SOURCE_DIR}/lib/Linux")
|
||||
set(IRRLICHT_LIBRARY_NAMES libIrrlicht.a)
|
||||
endif()
|
||||
# find our fork first, then upstream (TODO: remove this?)
|
||||
foreach(libname IN ITEMS IrrlichtMt Irrlicht)
|
||||
string(TOLOWER "${libname}" libname2)
|
||||
|
||||
find_path(IRRLICHT_INCLUDE_DIR NAMES irrlicht.h
|
||||
DOC "Path to the directory with IrrlichtMt includes"
|
||||
PATHS
|
||||
${IRRLICHT_SOURCE_DIR_INCLUDE}
|
||||
NO_DEFAULT_PATH
|
||||
/usr/local/include/${libname2}
|
||||
/usr/include/${libname2}
|
||||
/system/develop/headers/${libname2} #Haiku
|
||||
PATH_SUFFIXES "include/${libname2}"
|
||||
)
|
||||
|
||||
find_library(IRRLICHT_LIBRARY NAMES ${IRRLICHT_LIBRARY_NAMES}
|
||||
PATHS
|
||||
${IRRLICHT_SOURCE_DIR_LIBS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
else()
|
||||
find_path(IRRLICHT_INCLUDE_DIR NAMES irrlicht.h
|
||||
PATHS
|
||||
/usr/local/include/irrlicht
|
||||
/usr/include/irrlicht
|
||||
/system/develop/headers/irrlicht #Haiku
|
||||
PATH_SUFFIXES "include/irrlicht"
|
||||
)
|
||||
|
||||
find_library(IRRLICHT_LIBRARY NAMES libIrrlicht.so libIrrlicht.a Irrlicht
|
||||
find_library(IRRLICHT_LIBRARY NAMES lib${libname} ${libname}
|
||||
DOC "Path to the IrrlichtMt library file"
|
||||
PATHS
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/system/develop/lib # Haiku
|
||||
)
|
||||
endif()
|
||||
|
||||
if(IRRLICHT_INCLUDE_DIR OR IRRLICHT_LIBRARY)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Handholding for users
|
||||
if(IRRLICHT_INCLUDE_DIR AND (NOT IS_DIRECTORY "${IRRLICHT_INCLUDE_DIR}" OR
|
||||
NOT EXISTS "${IRRLICHT_INCLUDE_DIR}/irrlicht.h"))
|
||||
message(WARNING "IRRLICHT_INCLUDE_DIR was set to ${IRRLICHT_INCLUDE_DIR} "
|
||||
"but irrlicht.h does not exist inside. The path will not be used.")
|
||||
unset(IRRLICHT_INCLUDE_DIR CACHE)
|
||||
endif()
|
||||
if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux" OR APPLE)
|
||||
# (only on systems where we're sure how a valid library looks like)
|
||||
if(IRRLICHT_LIBRARY AND (IS_DIRECTORY "${IRRLICHT_LIBRARY}" OR
|
||||
NOT IRRLICHT_LIBRARY MATCHES "\\.(a|so|dylib|lib)([.0-9]+)?$"))
|
||||
message(WARNING "IRRLICHT_LIBRARY was set to ${IRRLICHT_LIBRARY} "
|
||||
"but is not a valid library file. The path will not be used.")
|
||||
unset(IRRLICHT_LIBRARY CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# On Windows, find the DLL for installation
|
||||
if(WIN32)
|
||||
# If VCPKG_APPLOCAL_DEPS is ON, dll's are automatically handled by VCPKG
|
||||
if(NOT VCPKG_APPLOCAL_DEPS)
|
||||
if(MSVC)
|
||||
set(IRRLICHT_COMPILER "VisualStudio")
|
||||
else()
|
||||
set(IRRLICHT_COMPILER "gcc")
|
||||
endif()
|
||||
find_file(IRRLICHT_DLL NAMES Irrlicht.dll
|
||||
PATHS
|
||||
"${IRRLICHT_SOURCE_DIR}/bin/Win32-${IRRLICHT_COMPILER}"
|
||||
DOC "Path of the Irrlicht dll (for installation)"
|
||||
find_file(IRRLICHT_DLL NAMES IrrlichtMt.dll
|
||||
DOC "Path of the IrrlichtMt dll (for installation)"
|
||||
)
|
||||
endif()
|
||||
endif(WIN32)
|
||||
|
@ -1,26 +1,25 @@
|
||||
# Look for JSONCPP if asked to.
|
||||
# We use a bundled version by default because some distros ship versions of
|
||||
# JSONCPP that cause segfaults and other memory errors when we link with them.
|
||||
# See https://github.com/minetest/minetest/issues/1793
|
||||
# Look for JsonCpp, with fallback to bundeled version
|
||||
|
||||
mark_as_advanced(JSON_LIBRARY JSON_INCLUDE_DIR)
|
||||
option(ENABLE_SYSTEM_JSONCPP "Enable using a system-wide JSONCPP. May cause segfaults and other memory errors!" FALSE)
|
||||
option(ENABLE_SYSTEM_JSONCPP "Enable using a system-wide JsonCpp" TRUE)
|
||||
set(USE_SYSTEM_JSONCPP FALSE)
|
||||
|
||||
if(ENABLE_SYSTEM_JSONCPP)
|
||||
find_library(JSON_LIBRARY NAMES jsoncpp)
|
||||
find_path(JSON_INCLUDE_DIR json/allocator.h PATH_SUFFIXES jsoncpp)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Json DEFAULT_MSG JSON_LIBRARY JSON_INCLUDE_DIR)
|
||||
|
||||
if(JSON_FOUND)
|
||||
message(STATUS "Using system JSONCPP library.")
|
||||
if(JSON_LIBRARY AND JSON_INCLUDE_DIR)
|
||||
message(STATUS "Using JsonCpp provided by system.")
|
||||
set(USE_SYSTEM_JSONCPP TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT JSON_FOUND)
|
||||
message(STATUS "Using bundled JSONCPP library.")
|
||||
if(NOT USE_SYSTEM_JSONCPP)
|
||||
message(STATUS "Using bundled JsonCpp library.")
|
||||
set(JSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/jsoncpp)
|
||||
set(JSON_LIBRARY jsoncpp)
|
||||
add_subdirectory(lib/jsoncpp)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Json DEFAULT_MSG JSON_LIBRARY JSON_INCLUDE_DIR)
|
||||
|
@ -42,7 +42,7 @@ else()
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(OPENGLES2 DEFAULT_MSG OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR)
|
||||
find_package_handle_standard_args(OpenGLES2 DEFAULT_MSG OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR)
|
||||
|
||||
find_path(EGL_INCLUDE_DIR EGL/egl.h
|
||||
PATHS /usr/openwin/share/include
|
||||
@ -59,7 +59,6 @@ else()
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(EGL DEFAULT_MSG EGL_LIBRARY EGL_INCLUDE_DIR)
|
||||
endif()
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
Minetest Lua Client Modding API Reference 5.4.0
|
||||
Minetest Lua Client Modding API Reference 5.5.0
|
||||
================================================
|
||||
* More information at <http://www.minetest.net/>
|
||||
* Developer Wiki: <http://dev.minetest.net/>
|
||||
@ -94,7 +94,7 @@ Mod directory structure
|
||||
|
||||
The format is documented in `builtin/settingtypes.txt`.
|
||||
It is parsed by the main menu settings dialogue to list mod-specific
|
||||
settings in the "Clientmods" category.
|
||||
settings in the "Clientmods" category.
|
||||
|
||||
### modname
|
||||
|
||||
@ -627,7 +627,7 @@ Helper functions
|
||||
* `minetest.is_yes(arg)`
|
||||
* returns whether `arg` can be interpreted as yes
|
||||
* `minetest.is_nan(arg)`
|
||||
* returns true true when the passed number represents NaN.
|
||||
* returns true when the passed number represents NaN.
|
||||
* `table.copy(table)`: returns a table
|
||||
* returns a deep copy of `table`
|
||||
|
||||
@ -658,6 +658,9 @@ Minetest namespace reference
|
||||
* `minetest.sha1(data, [raw])`: returns the sha1 hash of data
|
||||
* `data`: string of data to hash
|
||||
* `raw`: return raw bytes instead of hex digits, default: false
|
||||
* `minetest.colorspec_to_colorstring(colorspec)`: Converts a ColorSpec to a
|
||||
ColorString. If the ColorSpec is invalid, returns `nil`.
|
||||
* `colorspec`: The ColorSpec to convert
|
||||
* `minetest.get_csm_restrictions()`: returns a table of `Flags` indicating the
|
||||
restrictions applied to the current mod.
|
||||
* If a flag in this table is set to true, the feature is RESTRICTED.
|
||||
@ -674,6 +677,11 @@ Minetest namespace reference
|
||||
### Global callback registration functions
|
||||
Call these functions only at load time!
|
||||
|
||||
* `minetest.get_send_speed(speed)`
|
||||
* This function is called every time the player's speed is sent to server
|
||||
* The `speed` argument is the actual speed of the player
|
||||
* If you define it, you can return a modified `speed`. This speed will be
|
||||
sent to server instead.
|
||||
* `minetest.open_enderchest()`
|
||||
* This function is called if the client uses the Keybind for it (by default "O")
|
||||
* You can override it
|
||||
@ -700,7 +708,7 @@ Call these functions only at load time!
|
||||
* Registers a chatcommand `command` to manage a list that takes the args `del | add | list <param>`
|
||||
* The list is stored comma-seperated in `setting`
|
||||
* `desc` is the description
|
||||
* `add` adds something to the list
|
||||
* `add` adds something to the list
|
||||
* `del` del removes something from the list
|
||||
* `list` lists all items on the list
|
||||
* `minetest.register_on_chatcommand(function(command, params))`
|
||||
@ -762,7 +770,14 @@ Call these functions only at load time!
|
||||
* `minetest.register_on_spawn_partice(function(particle definition))`
|
||||
* Called when recieving a spawn particle command from server
|
||||
* Newest functions are called first
|
||||
* If any function returns true, the particel does not spawn
|
||||
* If any function returns true, the particle does not spawn
|
||||
* `minetest.register_on_object_add(function(obj))`
|
||||
* Called every time an object is added
|
||||
* `minetest.register_on_object_properties_change(function(obj))`
|
||||
* Called every time the properties of an object are changed server-side
|
||||
* May modify the object's properties without the fear of infinite recursion
|
||||
* `minetest.register_on_object_hp_change(function(obj))`
|
||||
* Called every time the hp of an object are changes server-side
|
||||
|
||||
### Setting-related
|
||||
* `minetest.settings`: Settings object containing all of the settings from the
|
||||
@ -929,6 +944,8 @@ Call these functions only at load time!
|
||||
* Convert between two privilege representations
|
||||
|
||||
### Client Environment
|
||||
* `minetest.object_refs`
|
||||
* Map of object references, indexed by active object id
|
||||
* `minetest.get_player_names()`
|
||||
* Returns list of player names on server (nil if CSM_RF_READ_PLAYERINFO is enabled by server)
|
||||
* `minetest.get_objects_inside_radius(pos, radius)`: returns a list of
|
||||
@ -946,13 +963,21 @@ Call these functions only at load time!
|
||||
|
||||
### HTTP Requests
|
||||
|
||||
* `minetest.get_http_api()`
|
||||
* returns `HTTPApiTable` containing http functions.
|
||||
* The returned table contains the functions `fetch_sync`, `fetch_async` and
|
||||
* `minetest.request_http_api()`:
|
||||
* returns `HTTPApiTable` containing http functions if the calling mod has
|
||||
been granted access by being listed in the `secure.http_mods` or
|
||||
`secure.trusted_mods` setting, otherwise returns `nil`.
|
||||
* The returned table contains the functions `fetch`, `fetch_async` and
|
||||
`fetch_async_get` described below.
|
||||
* Only works at init time and must be called from the mod's main scope
|
||||
(not from a function).
|
||||
* Function only exists if minetest server was built with cURL support.
|
||||
* `HTTPApiTable.fetch_sync(HTTPRequest req)`: returns HTTPRequestResult
|
||||
* Performs given request synchronously
|
||||
* **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED TABLE, STORE IT IN
|
||||
A LOCAL VARIABLE!**
|
||||
* `HTTPApiTable.fetch(HTTPRequest req, callback)`
|
||||
* Performs given request asynchronously and calls callback upon completion
|
||||
* callback: `function(HTTPRequestResult res)`
|
||||
* Use this HTTP function if you are unsure, the others are for advanced use
|
||||
* `HTTPApiTable.fetch_async(HTTPRequest req)`: returns handle
|
||||
* Performs given request asynchronously and returns handle for
|
||||
`HTTPApiTable.fetch_async_get`
|
||||
@ -1051,7 +1076,7 @@ Passed to `HTTPApiTable.fetch` callback. Returned by
|
||||
* `minetest.register_cheat(name, category, setting | function)`
|
||||
* Register an entry for the cheat menu
|
||||
* If the Category is nonexistant, it will be created
|
||||
* If the 3rd argument is a string it will be interpreted as a setting and toggled
|
||||
* If the 3rd argument is a string it will be interpreted as a setting and toggled
|
||||
when the player selects the entry in the cheat menu
|
||||
* If the 3rd argument is a function it will be called
|
||||
when the player selects the entry in the cheat menu
|
||||
@ -1114,6 +1139,14 @@ Passed to `HTTPApiTable.fetch` callback. Returned by
|
||||
* Checks if a global variable has been set, without triggering a warning.
|
||||
* `minetest.make_screenshot()`
|
||||
* Triggers the MT makeScreenshot functionality
|
||||
* `minetest.request_insecure_environment()`: returns an environment containing
|
||||
insecure functions if the calling mod has been listed as trusted in the
|
||||
`secure.trusted_mods` setting or security is disabled, otherwise returns
|
||||
`nil`.
|
||||
* Only works at init time and must be called from the mod's main scope
|
||||
(ie: the init.lua of the mod, not from another Lua file or within a function).
|
||||
* **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED ENVIRONMENT, STORE
|
||||
IT IN A LOCAL VARIABLE!**
|
||||
|
||||
### UI
|
||||
* `minetest.ui.minimap`
|
||||
@ -1395,12 +1428,16 @@ This is basically a reference to a C++ `GenericCAO`.
|
||||
* `is_player()`: returns true if the object is a player
|
||||
* `is_local_player()`: returns true if the object is the local player
|
||||
* `get_attach()`: returns parent or nil if it isn't attached.
|
||||
* `get_nametag()`: returns the nametag (string)
|
||||
* `get_item_textures()`: returns the textures
|
||||
* `get_max_hp()`: returns the maximum heath
|
||||
* `get_nametag()`: returns the nametag (deprecated, use get_properties().nametag instead)
|
||||
* `get_item_textures()`: returns the textures (deprecated, use get_properties().textures instead)
|
||||
* `get_max_hp()`: returns the maximum heath (deprecated, use get_properties().hp_max instead)
|
||||
* `set_properties(object property table)`
|
||||
* `get_properties()`: returns object property table
|
||||
* `punch()`: punches the object
|
||||
* `rightclick()`: rightclicks the object
|
||||
|
||||
* `remove()`: removes the object permanently
|
||||
* `set_nametag_images(images)`: Provides a list of images to be drawn below the nametag
|
||||
|
||||
### `Raycast`
|
||||
|
||||
A raycast on the map. It works with selection boxes.
|
||||
@ -1429,6 +1466,8 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
|
||||
|
||||
-----------------
|
||||
### Definitions
|
||||
* `minetest.inventorycube(img1, img2, img3)`
|
||||
* Returns a string for making an image of a cube (useful as an item image)
|
||||
* `minetest.get_node_def(nodename)`
|
||||
* Returns [node definition](#node-definition) table of `nodename`
|
||||
* `minetest.get_item_def(itemstring)`
|
||||
@ -1440,10 +1479,67 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
|
||||
{light_source=minetest.LIGHT_MAX})`
|
||||
* Doesnt really work yet an causes strange bugs, I'm working to make is better
|
||||
|
||||
|
||||
#### Tile definition
|
||||
|
||||
* `"image.png"`
|
||||
* `{name="image.png", animation={Tile Animation definition}}`
|
||||
* `{name="image.png", backface_culling=bool, align_style="node"/"world"/"user", scale=int}`
|
||||
* backface culling enabled by default for most nodes
|
||||
* align style determines whether the texture will be rotated with the node
|
||||
or kept aligned with its surroundings. "user" means that client
|
||||
setting will be used, similar to `glasslike_framed_optional`.
|
||||
Note: supported by solid nodes and nodeboxes only.
|
||||
* scale is used to make texture span several (exactly `scale`) nodes,
|
||||
instead of just one, in each direction. Works for world-aligned
|
||||
textures only.
|
||||
Note that as the effect is applied on per-mapblock basis, `16` should
|
||||
be equally divisible by `scale` or you may get wrong results.
|
||||
* `{name="image.png", color=ColorSpec}`
|
||||
* the texture's color will be multiplied with this color.
|
||||
* the tile's color overrides the owning node's color in all cases.
|
||||
|
||||
##### Tile definition
|
||||
|
||||
{
|
||||
type = "vertical_frames",
|
||||
|
||||
aspect_w = 16,
|
||||
-- Width of a frame in pixels
|
||||
|
||||
aspect_h = 16,
|
||||
-- Height of a frame in pixels
|
||||
|
||||
length = 3.0,
|
||||
-- Full loop length
|
||||
}
|
||||
|
||||
{
|
||||
type = "sheet_2d",
|
||||
|
||||
frames_w = 5,
|
||||
-- Width in number of frames
|
||||
|
||||
frames_h = 3,
|
||||
-- Height in number of frames
|
||||
|
||||
frame_length = 0.5,
|
||||
-- Length of a single frame
|
||||
}
|
||||
|
||||
#### Node Definition
|
||||
|
||||
```lua
|
||||
{
|
||||
tiles = {tile definition 1, def2, def3, def4, def5, def6},
|
||||
-- Textures of node; +Y, -Y, +X, -X, +Z, -Z
|
||||
overlay_tiles = {tile definition 1, def2, def3, def4, def5, def6},
|
||||
-- Same as `tiles`, but these textures are drawn on top of the base
|
||||
-- tiles. This is used to colorize only specific parts of the
|
||||
-- texture. If the texture name is an empty string, that overlay is not
|
||||
-- drawn
|
||||
special_tiles = {tile definition 1, Tile definition 2},
|
||||
-- Special textures of node; used rarely.
|
||||
has_on_construct = bool, -- Whether the node has the on_construct callback defined
|
||||
has_on_destruct = bool, -- Whether the node has the on_destruct callback defined
|
||||
has_after_destruct = bool, -- Whether the node has the after_destruct callback defined
|
||||
@ -1605,9 +1701,8 @@ The following functions provide escape sequences:
|
||||
|
||||
Named colors are also supported and are equivalent to
|
||||
[CSS Color Module Level 4](http://dev.w3.org/csswg/css-color/#named-colors).
|
||||
To specify the value of the alpha channel, append `#AA` to the end of the color name
|
||||
(e.g. `colorname#08`). For named colors the hexadecimal string representing the alpha
|
||||
value must (always) be two hexadecimal digits.
|
||||
To specify the value of the alpha channel, append `#A` or `#AA` to the end of
|
||||
the color name (e.g. `colorname#08`).
|
||||
|
||||
`Color`
|
||||
-------------
|
||||
@ -1792,7 +1887,7 @@ A reference to a C++ InventoryAction. You can move, drop and craft items in all
|
||||
* it specifies how many items to drop / craft / move
|
||||
* `0` means move all items
|
||||
* default count: `0`
|
||||
|
||||
|
||||
#### example
|
||||
`local move_act = InventoryAction("move")
|
||||
move_act:from("current_player", "main", 1)
|
||||
@ -1807,7 +1902,7 @@ A reference to a C++ InventoryAction. You can move, drop and craft items in all
|
||||
drop_act:apply()
|
||||
`
|
||||
* e.g. In first hotbar slot there are tree logs: Move one to craft field, then craft wood out of it and immediately drop it
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
258
doc/lua_api.txt
@ -256,6 +256,9 @@ Subfolders with names starting with `_` or `.` are ignored.
|
||||
If a subfolder contains a media file with the same name as a media file
|
||||
in one of its parents, the parent's file is used.
|
||||
|
||||
Although it is discouraged, a mod can overwrite a media file of any mod that it
|
||||
depends on by supplying a file with an equal name.
|
||||
|
||||
Naming conventions
|
||||
------------------
|
||||
|
||||
@ -1045,9 +1048,9 @@ The function of `param2` is determined by `paramtype2` in node definition.
|
||||
* The height of the 'plantlike' section is stored in `param2`.
|
||||
* The height is (`param2` / 16) nodes.
|
||||
* `paramtype2 = "degrotate"`
|
||||
* Only valid for "plantlike" drawtype. The rotation of the node is stored in
|
||||
`param2`.
|
||||
* Values range 0 - 179. The value stored in `param2` is multiplied by two to
|
||||
* Valid for `plantlike` and `mesh` drawtypes. The rotation of the node is
|
||||
stored in `param2`.
|
||||
* Values range 0–239. The value stored in `param2` is multiplied by 1.5 to
|
||||
get the actual rotation in degrees of the node.
|
||||
* `paramtype2 = "meshoptions"`
|
||||
* Only valid for "plantlike" drawtype. `param2` encodes the shape and
|
||||
@ -1085,6 +1088,11 @@ The function of `param2` is determined by `paramtype2` in node definition.
|
||||
* `param2` values 0-63 define 64 levels of internal liquid, 0 being empty
|
||||
and 63 being full.
|
||||
* Liquid texture is defined using `special_tiles = {"modname_tilename.png"}`
|
||||
* `paramtype2 = "colordegrotate"`
|
||||
* Same as `degrotate`, but with colors.
|
||||
* The first (most-significant) three bits of `param2` tells which color
|
||||
is picked from the palette. The palette should have 8 pixels.
|
||||
* Remaining 5 bits store rotation in range 0–23 (i.e. in 15° steps)
|
||||
* `paramtype2 = "none"`
|
||||
* `param2` will not be used by the engine and can be used to store
|
||||
an arbitrary value
|
||||
@ -1104,8 +1112,20 @@ Look for examples in `games/devtest` or `games/minetest_game`.
|
||||
* Invisible, uses no texture.
|
||||
* `liquid`
|
||||
* The cubic source node for a liquid.
|
||||
* Faces bordering to the same node are never rendered.
|
||||
* Connects to node specified in `liquid_alternative_flowing`.
|
||||
* Use `backface_culling = false` for the tiles you want to make
|
||||
visible when inside the node.
|
||||
* `flowingliquid`
|
||||
* The flowing version of a liquid, appears with various heights and slopes.
|
||||
* Faces bordering to the same node are never rendered.
|
||||
* Connects to node specified in `liquid_alternative_source`.
|
||||
* Node textures are defined with `special_tiles` where the first tile
|
||||
is for the top and bottom faces and the second tile is for the side
|
||||
faces.
|
||||
* `tiles` is used for the item/inventory/wield image rendering.
|
||||
* Use `backface_culling = false` for the special tiles you want to make
|
||||
visible when inside the node
|
||||
* `glasslike`
|
||||
* Often used for partially-transparent nodes.
|
||||
* Only external sides of textures are visible.
|
||||
@ -1132,14 +1152,20 @@ Look for examples in `games/devtest` or `games/minetest_game`.
|
||||
used to compensate for how `glasslike` reduces visual thickness.
|
||||
* `torchlike`
|
||||
* A single vertical texture.
|
||||
* If placed on top of a node, uses the first texture specified in `tiles`.
|
||||
* If placed against the underside of a node, uses the second texture
|
||||
specified in `tiles`.
|
||||
* If placed on the side of a node, uses the third texture specified in
|
||||
`tiles` and is perpendicular to that node.
|
||||
* If `paramtype2="[color]wallmounted":
|
||||
* If placed on top of a node, uses the first texture specified in `tiles`.
|
||||
* If placed against the underside of a node, uses the second texture
|
||||
specified in `tiles`.
|
||||
* If placed on the side of a node, uses the third texture specified in
|
||||
`tiles` and is perpendicular to that node.
|
||||
* If `paramtype2="none"`:
|
||||
* Will be rendered as if placed on top of a node (see
|
||||
above) and only the first texture is used.
|
||||
* `signlike`
|
||||
* A single texture parallel to, and mounted against, the top, underside or
|
||||
side of a node.
|
||||
* If `paramtype2="[color]wallmounted", it rotates according to `param2`
|
||||
* If `paramtype2="none"`, it will always be on the floor.
|
||||
* `plantlike`
|
||||
* Two vertical and diagonal textures at right-angles to each other.
|
||||
* See `paramtype2 = "meshoptions"` above for other options.
|
||||
@ -1722,7 +1748,15 @@ to games.
|
||||
* `3`: the node always gets the digging time 0 seconds (torch)
|
||||
* `disable_jump`: Player (and possibly other things) cannot jump from node
|
||||
or if their feet are in the node. Note: not supported for `new_move = false`
|
||||
* `fall_damage_add_percent`: damage speed = `speed * (1 + value/100)`
|
||||
* `fall_damage_add_percent`: modifies the fall damage suffered when hitting
|
||||
the top of this node. There's also an armor group with the same name.
|
||||
The final player damage is determined by the following formula:
|
||||
damage =
|
||||
collision speed
|
||||
* ((node_fall_damage_add_percent + 100) / 100) -- node group
|
||||
* ((player_fall_damage_add_percent + 100) / 100) -- player armor group
|
||||
- (14) -- constant tolerance
|
||||
Negative damage values are discarded as no damage.
|
||||
* `falling_node`: if there is no walkable block under the node it will fall
|
||||
* `float`: the node will not fall through liquids
|
||||
* `level`: Can be used to give an additional sense of progression in the game.
|
||||
@ -1742,11 +1776,15 @@ to games.
|
||||
`"toolrepair"` crafting recipe
|
||||
|
||||
|
||||
### `ObjectRef` groups
|
||||
### `ObjectRef` armor groups
|
||||
|
||||
* `immortal`: Skips all damage and breath handling for an object. This group
|
||||
will also hide the integrated HUD status bars for players, and is
|
||||
automatically set to all players when damage is disabled on the server.
|
||||
will also hide the integrated HUD status bars for players. It is
|
||||
automatically set to all players when damage is disabled on the server and
|
||||
cannot be reset (subject to change).
|
||||
* `fall_damage_add_percent`: Modifies the fall damage suffered by players
|
||||
when they hit the ground. It is analog to the node group with the same
|
||||
name. See the node group above for the exact calculation.
|
||||
* `punch_operable`: For entities; disables the regular damage mechanism for
|
||||
players punching it by hand or a non-tool item, so that it can do something
|
||||
else than take damage.
|
||||
@ -2113,7 +2151,7 @@ Examples
|
||||
list[current_player;main;0,3.5;8,4;]
|
||||
list[current_player;craft;3,0;3,3;]
|
||||
list[current_player;craftpreview;7,1;1,1;]
|
||||
|
||||
|
||||
Version History
|
||||
---------------
|
||||
|
||||
@ -2226,7 +2264,8 @@ Elements
|
||||
* Show an inventory list if it has been sent to the client. Nothing will
|
||||
be shown if the inventory list is of size 0.
|
||||
* **Note**: With the new coordinate system, the spacing between inventory
|
||||
slots is one-fourth the size of an inventory slot.
|
||||
slots is one-fourth the size of an inventory slot by default. Also see
|
||||
[Styling Formspecs] for changing the size of slots and spacing.
|
||||
|
||||
### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
|
||||
|
||||
@ -2294,7 +2333,7 @@ Elements
|
||||
* `frame duration`: Milliseconds between each frame. `0` means the frames don't advance.
|
||||
* `frame start` (Optional): The index of the frame to start on. Default `1`.
|
||||
|
||||
### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>;<frame loop range>]`
|
||||
### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>;<frame loop range>;<animation speed>]`
|
||||
|
||||
* Show a mesh model.
|
||||
* `name`: Element name that can be used for styling
|
||||
@ -2308,6 +2347,7 @@ Elements
|
||||
* `frame loop range` (Optional): Range of the animation frames.
|
||||
* Defaults to the full range of all available frames.
|
||||
* Syntax: `<begin>,<end>`
|
||||
* `animation speed` (Optional): Sets the animation speed. Default 0 FPS.
|
||||
|
||||
### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
|
||||
|
||||
@ -2673,7 +2713,7 @@ Elements
|
||||
* `span=<value>`: number of following columns to affect
|
||||
(default: infinite).
|
||||
|
||||
### `style[<selector 1>,<selector 2>;<prop1>;<prop2>;...]`
|
||||
### `style[<selector 1>,<selector 2>,...;<prop1>;<prop2>;...]`
|
||||
|
||||
* Set the style for the element(s) matching `selector` by name.
|
||||
* `selector` can be one of:
|
||||
@ -2686,7 +2726,7 @@ Elements
|
||||
* See [Styling Formspecs].
|
||||
|
||||
|
||||
### `style_type[<selector 1>,<selector 2>;<prop1>;<prop2>;...]`
|
||||
### `style_type[<selector 1>,<selector 2>,...;<prop1>;<prop2>;...]`
|
||||
|
||||
* Set the style for the element(s) matching `selector` by type.
|
||||
* `selector` can be one of:
|
||||
@ -2759,10 +2799,10 @@ Styling Formspecs
|
||||
|
||||
Formspec elements can be themed using the style elements:
|
||||
|
||||
style[<name 1>,<name 2>;<prop1>;<prop2>;...]
|
||||
style[<name 1>:<state>,<name 2>:<state>;<prop1>;<prop2>;...]
|
||||
style_type[<type 1>,<type 2>;<prop1>;<prop2>;...]
|
||||
style_type[<type 1>:<state>,<type 2>:<state>;<prop1>;<prop2>;...]
|
||||
style[<name 1>,<name 2>,...;<prop1>;<prop2>;...]
|
||||
style[<name 1>:<state>,<name 2>:<state>,...;<prop1>;<prop2>;...]
|
||||
style_type[<type 1>,<type 2>,...;<prop1>;<prop2>;...]
|
||||
style_type[<type 1>:<state>,<type 2>:<state>,...;<prop1>;<prop2>;...]
|
||||
|
||||
Where a prop is:
|
||||
|
||||
@ -2809,6 +2849,7 @@ Some types may inherit styles from parent types.
|
||||
* image_button
|
||||
* item_image_button
|
||||
* label
|
||||
* list
|
||||
* model
|
||||
* pwdfield, inherits from field
|
||||
* scrollbar
|
||||
@ -2869,14 +2910,14 @@ Some types may inherit styles from parent types.
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* padding - rect, adds space between the edges of the button and the content. This value is
|
||||
relative to bgimg_middle.
|
||||
* sound - a sound to be played when clicked.
|
||||
* sound - a sound to be played when triggered.
|
||||
* textcolor - color, default white.
|
||||
* checkbox
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* sound - a sound to be played when clicked.
|
||||
* sound - a sound to be played when triggered.
|
||||
* dropdown
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* sound - a sound to be played when clicked.
|
||||
* sound - a sound to be played when the entry is changed.
|
||||
* field, pwdfield, textarea
|
||||
* border - set to false to hide the textbox background and border. Default true.
|
||||
* font - Sets font type. See button `font` property for more information.
|
||||
@ -2896,6 +2937,10 @@ Some types may inherit styles from parent types.
|
||||
* font - Sets font type. See button `font` property for more information.
|
||||
* font_size - Sets font size. See button `font_size` property for more information.
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* list
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* size - 2d vector, sets the size of inventory slots in coordinates.
|
||||
* spacing - 2d vector, sets the space between inventory slots in coordinates.
|
||||
* image_button (additional properties)
|
||||
* fgimg - standard image. Defaults to none.
|
||||
* fgimg_hovered - image when hovered. Defaults to fgimg when not provided.
|
||||
@ -2903,12 +2948,12 @@ Some types may inherit styles from parent types.
|
||||
* fgimg_pressed - image when pressed. Defaults to fgimg when not provided.
|
||||
* This is deprecated, use states instead.
|
||||
* NOTE: The parameters of any given image_button will take precedence over fgimg/fgimg_pressed
|
||||
* sound - a sound to be played when clicked.
|
||||
* sound - a sound to be played when triggered.
|
||||
* scrollbar
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* tabheader
|
||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||
* sound - a sound to be played when clicked.
|
||||
* sound - a sound to be played when a different tab is selected.
|
||||
* textcolor - color. Default white.
|
||||
* table, textlist
|
||||
* font - Sets font type. See button `font` property for more information.
|
||||
@ -3067,9 +3112,8 @@ Colors
|
||||
|
||||
Named colors are also supported and are equivalent to
|
||||
[CSS Color Module Level 4](http://dev.w3.org/csswg/css-color/#named-colors).
|
||||
To specify the value of the alpha channel, append `#AA` to the end of the color
|
||||
name (e.g. `colorname#08`). For named colors the hexadecimal string
|
||||
representing the alpha value must (always) be two hexadecimal digits.
|
||||
To specify the value of the alpha channel, append `#A` or `#AA` to the end of
|
||||
the color name (e.g. `colorname#08`).
|
||||
|
||||
`ColorSpec`
|
||||
-----------
|
||||
@ -3135,6 +3179,16 @@ For the following functions, `v`, `v1`, `v2` are vectors,
|
||||
* Returns a vector.
|
||||
* A copy of `a` if `a` is a vector.
|
||||
* `{x = a, y = b, z = c}`, if all of `a`, `b`, `c` are defined numbers.
|
||||
* `vector.from_string(s[, init])`:
|
||||
* Returns `v, np`, where `v` is a vector read from the given string `s` and
|
||||
`np` is the next position in the string after the vector.
|
||||
* Returns `nil` on failure.
|
||||
* `s`: Has to begin with a substring of the form `"(x, y, z)"`. Additional
|
||||
spaces, leaving away commas and adding an additional comma to the end
|
||||
is allowed.
|
||||
* `init`: If given starts looking for the vector at this string index.
|
||||
* `vector.to_string(v)`:
|
||||
* Returns a string of the form `"(x, y, z)"`.
|
||||
* `vector.direction(p1, p2)`:
|
||||
* Returns a vector of length 1 with direction `p1` to `p2`.
|
||||
* If `p1` and `p2` are identical, returns `{x = 0, y = 0, z = 0}`.
|
||||
@ -3149,6 +3203,7 @@ For the following functions, `v`, `v1`, `v2` are vectors,
|
||||
* Returns a vector, each dimension rounded down.
|
||||
* `vector.round(v)`:
|
||||
* Returns a vector, each dimension rounded to nearest integer.
|
||||
* At a multiple of 0.5, rounds away from zero.
|
||||
* `vector.apply(v, func)`:
|
||||
* Returns a vector where the function `func` has been applied to each
|
||||
component.
|
||||
@ -3223,6 +3278,8 @@ Helper functions
|
||||
* If the absolute value of `x` is within the `tolerance` or `x` is NaN,
|
||||
`0` is returned.
|
||||
* `math.factorial(x)`: returns the factorial of `x`
|
||||
* `math.round(x)`: Returns `x` rounded to the nearest integer.
|
||||
* At a multiple of 0.5, rounds away from zero.
|
||||
* `string.split(str, separator, include_empty, max_splits, sep_is_pattern)`
|
||||
* `separator`: string, default: `","`
|
||||
* `include_empty`: boolean, default: `false`
|
||||
@ -3260,7 +3317,6 @@ Helper functions
|
||||
* returns true when the passed number represents NaN.
|
||||
* `minetest.get_us_time()`
|
||||
* returns time with microsecond precision. May not return wall time.
|
||||
* This value might overflow on certain 32-bit systems!
|
||||
* `table.copy(table)`: returns a table
|
||||
* returns a deep copy of `table`
|
||||
* `table.indexof(list, val)`: returns the smallest numerical index containing
|
||||
@ -3271,7 +3327,8 @@ Helper functions
|
||||
* Appends all values in `other_table` to `table` - uses `#table + 1` to
|
||||
find new indices.
|
||||
* `table.key_value_swap(t)`: returns a table with keys and values swapped
|
||||
* If multiple keys in `t` map to the same value, the result is undefined.
|
||||
* If multiple keys in `t` map to the same value, it is unspecified which
|
||||
value maps to that key.
|
||||
* `table.shuffle(table, [from], [to], [random_func])`:
|
||||
* Shuffles elements `from` to `to` in `table` in place
|
||||
* `from` defaults to `1`
|
||||
@ -4381,6 +4438,11 @@ Utilities
|
||||
object_step_has_moveresult = true,
|
||||
-- Whether get_velocity() and add_velocity() can be used on players (5.4.0)
|
||||
direct_velocity_on_players = true,
|
||||
-- nodedef's use_texture_alpha accepts new string modes (5.4.0)
|
||||
use_texture_alpha_string_modes = true,
|
||||
-- degrotate param2 rotates in units of 1.5° instead of 2°
|
||||
-- thus changing the range of values from 0-179 to 0-240 (5.5.0)
|
||||
degrotate_240_steps = true,
|
||||
}
|
||||
|
||||
* `minetest.has_feature(arg)`: returns `boolean, missing_features`
|
||||
@ -4440,6 +4502,9 @@ Utilities
|
||||
* `minetest.sha1(data, [raw])`: returns the sha1 hash of data
|
||||
* `data`: string of data to hash
|
||||
* `raw`: return raw bytes instead of hex digits, default: false
|
||||
* `minetest.colorspec_to_colorstring(colorspec)`: Converts a ColorSpec to a
|
||||
ColorString. If the ColorSpec is invalid, returns `nil`.
|
||||
* `colorspec`: The ColorSpec to convert
|
||||
|
||||
Logging
|
||||
-------
|
||||
@ -4589,6 +4654,10 @@ Call these functions only at load time!
|
||||
the puncher to the punched.
|
||||
* `damage`: Number that represents the damage calculated by the engine
|
||||
* should return `true` to prevent the default damage mechanism
|
||||
* `minetest.register_on_rightclickplayer(function(player, clicker))`
|
||||
* Called when a player is right-clicked
|
||||
* `player`: ObjectRef - Player that was right-clicked
|
||||
* `clicker`: ObjectRef - Object that right-clicked, may or may not be a player
|
||||
* `minetest.register_on_player_hpchange(function(player, hp_change, reason), modifier)`
|
||||
* Called when the player gets damaged or healed
|
||||
* `player`: ObjectRef of the player
|
||||
@ -4639,6 +4708,7 @@ Call these functions only at load time!
|
||||
* `cheat`: `{type=<cheat_type>}`, where `<cheat_type>` is one of:
|
||||
* `moved_too_fast`
|
||||
* `interacted_too_far`
|
||||
* `interacted_with_self`
|
||||
* `interacted_while_dead`
|
||||
* `finished_unknown_dig`
|
||||
* `dug_unbreakable`
|
||||
@ -4879,7 +4949,7 @@ Environment access
|
||||
* Punch node with the same effects that a player would cause
|
||||
* `minetest.spawn_falling_node(pos)`
|
||||
* Change node into falling node
|
||||
* Returns `true` if successful, `false` on failure
|
||||
* Returns `true` and the ObjectRef of the spawned entity if successful, `false` on failure
|
||||
|
||||
* `minetest.find_nodes_with_meta(pos1, pos2)`
|
||||
* Get a table of positions of nodes that have metadata within a region
|
||||
@ -5434,20 +5504,22 @@ Server
|
||||
* Returns a code (0: successful, 1: no such player, 2: player is connected)
|
||||
* `minetest.remove_player_auth(name)`: remove player authentication data
|
||||
* Returns boolean indicating success (false if player nonexistant)
|
||||
* `minetest.dynamic_add_media(filepath)`
|
||||
* Adds the file at the given path to the media sent to clients by the server
|
||||
on startup and also pushes this file to already connected clients.
|
||||
* `minetest.dynamic_add_media(filepath, callback)`
|
||||
* `filepath`: path to a media file on the filesystem
|
||||
* `callback`: function with arguments `name`, where name is a player name
|
||||
(previously there was no callback argument; omitting it is deprecated)
|
||||
* Adds the file to the media sent to clients by the server on startup
|
||||
and also pushes this file to already connected clients.
|
||||
The file must be a supported image, sound or model format. It must not be
|
||||
modified, deleted, moved or renamed after calling this function.
|
||||
The list of dynamically added media is not persisted.
|
||||
* Returns boolean indicating success (duplicate files count as error)
|
||||
* The media will be ready to use (in e.g. entity textures, sound_play)
|
||||
immediately after calling this function.
|
||||
* Returns false on error, true if the request was accepted
|
||||
* The given callback will be called for every player as soon as the
|
||||
media is available on the client.
|
||||
Old clients that lack support for this feature will not see the media
|
||||
unless they reconnect to the server.
|
||||
* Since media transferred this way does not use client caching or HTTP
|
||||
transfers, dynamic media should not be used with big files or performance
|
||||
will suffer.
|
||||
unless they reconnect to the server. (callback won't be called)
|
||||
* Since media transferred this way currently does not use client caching
|
||||
or HTTP transfers, dynamic media should not be used with big files.
|
||||
|
||||
Bans
|
||||
----
|
||||
@ -6025,18 +6097,18 @@ an itemstring, a table or `nil`.
|
||||
stack).
|
||||
* `set_metadata(metadata)`: (DEPRECATED) Returns true.
|
||||
* `get_description()`: returns the description shown in inventory list tooltips.
|
||||
* The engine uses the same as this function for item descriptions.
|
||||
* The engine uses this when showing item descriptions in tooltips.
|
||||
* Fields for finding the description, in order:
|
||||
* `description` in item metadata (See [Item Metadata].)
|
||||
* `description` in item definition
|
||||
* item name
|
||||
* `get_short_description()`: returns the short description.
|
||||
* `get_short_description()`: returns the short description or nil.
|
||||
* Unlike the description, this does not include new lines.
|
||||
* The engine uses the same as this function for short item descriptions.
|
||||
* Fields for finding the short description, in order:
|
||||
* `short_description` in item metadata (See [Item Metadata].)
|
||||
* `short_description` in item definition
|
||||
* first line of the description (See `get_description()`.)
|
||||
* first line of the description (From item meta or def, see `get_description()`.)
|
||||
* Returns nil if none of the above are set
|
||||
* `clear()`: removes all items from the stack, making it empty.
|
||||
* `replace(item)`: replace the contents of this stack.
|
||||
* `item` can also be an itemstring or table.
|
||||
@ -6213,8 +6285,8 @@ object you are working with still exists.
|
||||
* `time_from_last_punch` = time since last punch action of the puncher
|
||||
* `direction`: can be `nil`
|
||||
* `right_click(clicker)`; `clicker` is another `ObjectRef`
|
||||
* `get_hp()`: returns number of hitpoints (2 * number of hearts)
|
||||
* `set_hp(hp, reason)`: set number of hitpoints (2 * number of hearts).
|
||||
* `get_hp()`: returns number of health points
|
||||
* `set_hp(hp, reason)`: set number of health points
|
||||
* See reason in register_on_player_hpchange
|
||||
* Is limited to the range of 0 ... 65535 (2^16 - 1)
|
||||
* For players: HP are also limited by `hp_max` specified in the player's
|
||||
@ -6237,21 +6309,22 @@ object you are working with still exists.
|
||||
`frame_loop`.
|
||||
* `set_animation_frame_speed(frame_speed)`
|
||||
* `frame_speed`: number, default: `15.0`
|
||||
* `set_attach(parent, bone, position, rotation, forced_visible)`
|
||||
* `bone`: string
|
||||
* `position`: `{x=num, y=num, z=num}` (relative)
|
||||
* `rotation`: `{x=num, y=num, z=num}` = Rotation on each axis, in degrees
|
||||
* `set_attach(parent[, bone, position, rotation, forced_visible])`
|
||||
* `bone`: string. Default is `""`, the root bone
|
||||
* `position`: `{x=num, y=num, z=num}`, relative, default `{x=0, y=0, z=0}`
|
||||
* `rotation`: `{x=num, y=num, z=num}` = Rotation on each axis, in degrees.
|
||||
Default `{x=0, y=0, z=0}`
|
||||
* `forced_visible`: Boolean to control whether the attached entity
|
||||
should appear in first person.
|
||||
should appear in first person. Default `false`.
|
||||
* `get_attach()`: returns parent, bone, position, rotation, forced_visible,
|
||||
or nil if it isn't attached.
|
||||
* `get_children()`: returns a list of ObjectRefs that are attached to the
|
||||
object.
|
||||
* `set_detach()`
|
||||
* `set_bone_position(bone, position, rotation)`
|
||||
* `bone`: string
|
||||
* `position`: `{x=num, y=num, z=num}` (relative)
|
||||
* `rotation`: `{x=num, y=num, z=num}`
|
||||
* `set_bone_position([bone, position, rotation])`
|
||||
* `bone`: string. Default is `""`, the root bone
|
||||
* `position`: `{x=num, y=num, z=num}`, relative, `default {x=0, y=0, z=0}`
|
||||
* `rotation`: `{x=num, y=num, z=num}`, default `{x=0, y=0, z=0}`
|
||||
* `get_bone_position(bone)`: returns position and rotation of the bone
|
||||
* `set_properties(object property table)`
|
||||
* `get_properties()`: returns object property table
|
||||
@ -6259,15 +6332,21 @@ object you are working with still exists.
|
||||
* `get_nametag_attributes()`
|
||||
* returns a table with the attributes of the nametag of an object
|
||||
* {
|
||||
color = {a=0..255, r=0..255, g=0..255, b=0..255},
|
||||
text = "",
|
||||
color = {a=0..255, r=0..255, g=0..255, b=0..255},
|
||||
bgcolor = {a=0..255, r=0..255, g=0..255, b=0..255},
|
||||
}
|
||||
* `set_nametag_attributes(attributes)`
|
||||
* sets the attributes of the nametag of an object
|
||||
* `attributes`:
|
||||
{
|
||||
color = ColorSpec,
|
||||
text = "My Nametag",
|
||||
color = ColorSpec,
|
||||
-- ^ Text color
|
||||
bgcolor = ColorSpec or false,
|
||||
-- ^ Sets background color of nametag
|
||||
-- `false` will cause the background to be set automatically based on user settings
|
||||
-- Default: false
|
||||
}
|
||||
|
||||
#### Lua entity only (no-op for other objects)
|
||||
@ -6579,8 +6658,8 @@ object you are working with still exists.
|
||||
* `frame_speed` sets the animations frame speed. Default is 30.
|
||||
* `get_local_animation()`: returns idle, walk, dig, walk_while_dig tables and
|
||||
`frame_speed`.
|
||||
* `set_eye_offset(firstperson, thirdperson)`: defines offset vectors for camera
|
||||
per player.
|
||||
* `set_eye_offset([firstperson, thirdperson])`: defines offset vectors for
|
||||
camera per player. An argument defaults to `{x=0, y=0, z=0}` if unspecified.
|
||||
* in first person view
|
||||
* in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`)
|
||||
* `get_eye_offset()`: returns first and third person offsets.
|
||||
@ -6936,10 +7015,18 @@ Player properties need to be saved manually.
|
||||
-- in mods.
|
||||
|
||||
nametag = "",
|
||||
-- By default empty, for players their name is shown if empty
|
||||
-- The name to display on the head of the object. By default empty.
|
||||
-- If the object is a player, a nil or empty nametag is replaced by the player's name.
|
||||
-- For all other objects, a nil or empty string removes the nametag.
|
||||
-- To hide a nametag, set its color alpha to zero. That will disable it entirely.
|
||||
|
||||
nametag_color = <ColorSpec>,
|
||||
-- Sets color of nametag
|
||||
-- Sets text color of nametag
|
||||
|
||||
nametag_bgcolor = <ColorSpec>,
|
||||
-- Sets background color of nametag
|
||||
-- `false` will cause the background to be set automatically based on user settings.
|
||||
-- Default: false
|
||||
|
||||
infotext = "",
|
||||
-- By default empty, text to be shown when pointed at object
|
||||
@ -7152,8 +7239,9 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
|
||||
|
||||
short_description = "Steel Axe",
|
||||
-- Must not contain new lines.
|
||||
-- Defaults to the first line of description.
|
||||
-- See also: `get_short_description` in [`ItemStack`]
|
||||
-- Defaults to nil.
|
||||
-- Use an [`ItemStack`] to get the short description, eg:
|
||||
-- ItemStack(itemname):get_short_description()
|
||||
|
||||
groups = {},
|
||||
-- key = name, value = rating; rating = 1..3.
|
||||
@ -7326,10 +7414,18 @@ Used by `minetest.register_node`.
|
||||
-- If the node has a palette, then this setting only has an effect in
|
||||
-- the inventory and on the wield item.
|
||||
|
||||
use_texture_alpha = false,
|
||||
-- Use texture's alpha channel
|
||||
-- If this is set to false, the node will be rendered fully opaque
|
||||
-- regardless of any texture transparency.
|
||||
use_texture_alpha = ...,
|
||||
-- Specifies how the texture's alpha channel will be used for rendering.
|
||||
-- possible values:
|
||||
-- * "opaque": Node is rendered opaque regardless of alpha channel
|
||||
-- * "clip": A given pixel is either fully see-through or opaque
|
||||
-- depending on the alpha channel being below/above 50% in value
|
||||
-- * "blend": The alpha channel specifies how transparent a given pixel
|
||||
-- of the rendered node is
|
||||
-- The default is "opaque" for drawtypes normal, liquid and flowingliquid;
|
||||
-- "clip" otherwise.
|
||||
-- If set to a boolean value (deprecated): true either sets it to blend
|
||||
-- or clip, false sets it to clip or opaque mode depending on the drawtype.
|
||||
|
||||
palette = "palette.png",
|
||||
-- The node's `param2` is used to select a pixel from the image.
|
||||
@ -7371,7 +7467,16 @@ Used by `minetest.register_node`.
|
||||
-- If true, liquids flow into and replace this node.
|
||||
-- Warning: making a liquid node 'floodable' will cause problems.
|
||||
|
||||
liquidtype = "none", -- "none" / "source" / "flowing"
|
||||
liquidtype = "none", -- specifies liquid physics
|
||||
-- * "none": no liquid physics
|
||||
-- * "source": spawns flowing liquid nodes at all 4 sides and below;
|
||||
-- recommended drawtype: "liquid".
|
||||
-- * "flowing": spawned from source, spawns more flowing liquid nodes
|
||||
-- around it until `liquid_range` is reached;
|
||||
-- will drain out without a source;
|
||||
-- recommended drawtype: "flowingliquid".
|
||||
-- If it's "source" or "flowing" and `liquid_range > 0`, then
|
||||
-- both `liquid_alternative_*` fields must be specified
|
||||
|
||||
liquid_alternative_flowing = "", -- Flowing version of source liquid
|
||||
|
||||
@ -7394,7 +7499,10 @@ Used by `minetest.register_node`.
|
||||
-- `minetest.set_node_level` and `minetest.add_node_level`.
|
||||
-- Values above 124 might causes collision detection issues.
|
||||
|
||||
liquid_range = 8, -- Number of flowing nodes around source (max. 8)
|
||||
liquid_range = 8,
|
||||
-- Maximum distance that flowing liquid nodes can spread around
|
||||
-- source on flat land;
|
||||
-- maximum = 8; set to 0 to disable liquid flow
|
||||
|
||||
drowning = 0,
|
||||
-- Player will take this amount of damage if no bubbles are left
|
||||
@ -7604,6 +7712,8 @@ Used by `minetest.register_node`.
|
||||
on_dig = function(pos, node, digger),
|
||||
-- default: minetest.node_dig
|
||||
-- By default checks privileges, wears out tool and removes node.
|
||||
-- return true if the node was dug successfully, false otherwise.
|
||||
-- Deprecated: returning nil is the same as returning true.
|
||||
|
||||
on_timer = function(pos, elapsed),
|
||||
-- default: nil
|
||||
@ -7643,12 +7753,12 @@ Used by `minetest.register_node`.
|
||||
-- intensity: 1.0 = mid range of regular TNT.
|
||||
-- If defined, called when an explosion touches the node, instead of
|
||||
-- removing the node.
|
||||
|
||||
|
||||
mod_origin = "modname",
|
||||
-- stores which mod actually registered a node
|
||||
-- if it can not find a source, returns "??"
|
||||
-- useful for getting what mod truly registered something
|
||||
-- example: if a node is registered as ":othermodname:nodename",
|
||||
-- example: if a node is registered as ":othermodname:nodename",
|
||||
-- nodename will show "othermodname", but mod_orgin will say "modname"
|
||||
}
|
||||
|
||||
@ -8339,7 +8449,7 @@ Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`.
|
||||
url = "http://example.org",
|
||||
|
||||
timeout = 10,
|
||||
-- Timeout for connection in seconds. Default is 3 seconds.
|
||||
-- Timeout for request to be completed in seconds. Default depends on engine settings.
|
||||
|
||||
method = "GET", "POST", "PUT" or "DELETE"
|
||||
-- The http method to use. Defaults to "GET".
|
||||
|
@ -1,4 +1,4 @@
|
||||
Minetest Lua Mainmenu API Reference 5.4.0
|
||||
Minetest Lua Mainmenu API Reference 5.5.0
|
||||
=========================================
|
||||
|
||||
Introduction
|
||||
@ -85,6 +85,7 @@ core.get_video_drivers()
|
||||
core.get_mapgen_names([include_hidden=false]) -> table of map generator algorithms
|
||||
registered in the core (possible in async calls)
|
||||
core.get_cache_path() -> path of cache
|
||||
core.get_temp_path() -> path of temp folder
|
||||
|
||||
|
||||
HTTP Requests
|
||||
@ -203,7 +204,8 @@ core.get_screen_info()
|
||||
display_width = <width of display>,
|
||||
display_height = <height of display>,
|
||||
window_width = <current window width>,
|
||||
window_height = <current window height>
|
||||
window_height = <current window height>,
|
||||
render_info = <active render information>
|
||||
}
|
||||
|
||||
|
||||
@ -253,32 +255,6 @@ Package - content which is downloadable from the content db, may or may not be i
|
||||
}
|
||||
|
||||
|
||||
Favorites
|
||||
---------
|
||||
|
||||
core.get_favorites(location) -> list of favorites (possible in async calls)
|
||||
^ location: "local" or "online"
|
||||
^ returns {
|
||||
[1] = {
|
||||
clients = <number of clients/nil>,
|
||||
clients_max = <maximum number of clients/nil>,
|
||||
version = <server version/nil>,
|
||||
password = <true/nil>,
|
||||
creative = <true/nil>,
|
||||
damage = <true/nil>,
|
||||
pvp = <true/nil>,
|
||||
description = <server description/nil>,
|
||||
name = <server name/nil>,
|
||||
address = <address of server/nil>,
|
||||
port = <port>
|
||||
clients_list = <array of clients/nil>
|
||||
mods = <array of mods/nil>
|
||||
},
|
||||
...
|
||||
}
|
||||
core.delete_favorite(id, location) -> success
|
||||
|
||||
|
||||
Logging
|
||||
-------
|
||||
|
||||
|
@ -493,19 +493,8 @@ Static objects are persistent freely moving objects in the world.
|
||||
|
||||
Object types:
|
||||
1: Test object
|
||||
2: Item
|
||||
3: Rat (obsolete)
|
||||
4: Oerkki (obsolete)
|
||||
5: Firefly (obsolete)
|
||||
6: MobV2 (obsolete)
|
||||
7: LuaEntity
|
||||
|
||||
1: Item:
|
||||
u8 version
|
||||
version 0:
|
||||
u16 len
|
||||
u8[len] itemstring
|
||||
|
||||
7: LuaEntity:
|
||||
u8 compatibility_byte (always 1)
|
||||
u16 len
|
||||
|
@ -1,4 +1,4 @@
|
||||
local WATER_ALPHA = 160
|
||||
local WATER_ALPHA = "^[opacity:" .. 160
|
||||
local WATER_VISC = 1
|
||||
local LAVA_VISC = 7
|
||||
|
||||
@ -128,12 +128,12 @@ minetest.register_node("basenodes:water_source", {
|
||||
"Drowning damage: 1",
|
||||
drawtype = "liquid",
|
||||
waving = 3,
|
||||
tiles = {"default_water.png"},
|
||||
tiles = {"default_water.png"..WATER_ALPHA},
|
||||
special_tiles = {
|
||||
{name = "default_water.png", backface_culling = false},
|
||||
{name = "default_water.png", backface_culling = true},
|
||||
{name = "default_water.png"..WATER_ALPHA, backface_culling = false},
|
||||
{name = "default_water.png"..WATER_ALPHA, backface_culling = true},
|
||||
},
|
||||
alpha = WATER_ALPHA,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
@ -156,10 +156,12 @@ minetest.register_node("basenodes:water_flowing", {
|
||||
waving = 3,
|
||||
tiles = {"default_water_flowing.png"},
|
||||
special_tiles = {
|
||||
{name = "default_water_flowing.png", backface_culling = false},
|
||||
{name = "default_water_flowing.png", backface_culling = false},
|
||||
{name = "default_water_flowing.png"..WATER_ALPHA,
|
||||
backface_culling = false},
|
||||
{name = "default_water_flowing.png"..WATER_ALPHA,
|
||||
backface_culling = false},
|
||||
},
|
||||
alpha = WATER_ALPHA,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
walkable = false,
|
||||
@ -181,12 +183,12 @@ minetest.register_node("basenodes:river_water_source", {
|
||||
"Drowning damage: 1",
|
||||
drawtype = "liquid",
|
||||
waving = 3,
|
||||
tiles = { "default_river_water.png" },
|
||||
tiles = { "default_river_water.png"..WATER_ALPHA },
|
||||
special_tiles = {
|
||||
{name = "default_river_water.png", backface_culling = false},
|
||||
{name = "default_river_water.png", backface_culling = true},
|
||||
{name = "default_river_water.png"..WATER_ALPHA, backface_culling = false},
|
||||
{name = "default_river_water.png"..WATER_ALPHA, backface_culling = true},
|
||||
},
|
||||
alpha = WATER_ALPHA,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
@ -209,12 +211,14 @@ minetest.register_node("basenodes:river_water_flowing", {
|
||||
"Drowning damage: 1",
|
||||
drawtype = "flowingliquid",
|
||||
waving = 3,
|
||||
tiles = {"default_river_water_flowing.png"},
|
||||
tiles = {"default_river_water_flowing.png"..WATER_ALPHA},
|
||||
special_tiles = {
|
||||
{name = "default_river_water_flowing.png", backface_culling = false},
|
||||
{name = "default_river_water_flowing.png", backface_culling = false},
|
||||
{name = "default_river_water_flowing.png"..WATER_ALPHA,
|
||||
backface_culling = false},
|
||||
{name = "default_river_water_flowing.png"..WATER_ALPHA,
|
||||
backface_culling = false},
|
||||
},
|
||||
alpha = WATER_ALPHA,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
walkable = false,
|
||||
|
Before Width: | Height: | Size: 790 B After Width: | Height: | Size: 7.1 KiB |
@ -1,3 +0,0 @@
|
||||
This is for testing loading textures from subfolders.
|
||||
If it works correctly, the default_grass_side.png file in this folder is used but
|
||||
default_grass.png is not overwritten by the file in this folder.
|
7
games/devtest/mods/basenodes/textures/info.txt
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
The dirt_with_grass folder is for testing loading textures from subfolders.
|
||||
If it works correctly, the default_grass_side.png file in the folder is used but
|
||||
default_grass.png is not overwritten by the file in the folder.
|
||||
|
||||
default_dirt.png should be overwritten by the default_dirt.png in the unittests
|
||||
mod which depends on basenodes.
|
@ -23,6 +23,18 @@ minetest.register_node("chest:chest", {
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main")
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
minetest.chat_send_player(player:get_player_name(), "Allow put: " .. stack:to_string())
|
||||
return stack:get_count()
|
||||
end,
|
||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
minetest.chat_send_player(player:get_player_name(), "Allow take: " .. stack:to_string())
|
||||
return stack:get_count()
|
||||
end,
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
minetest.chat_send_player(player:get_player_name(), "On put: " .. stack:to_string())
|
||||
end,
|
||||
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
minetest.chat_send_player(player:get_player_name(), "On take: " .. stack:to_string())
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
|
@ -131,10 +131,11 @@ local function place_nodes(param)
|
||||
p2_max = 63
|
||||
elseif def.paramtype2 == "leveled" then
|
||||
p2_max = 127
|
||||
elseif def.paramtype2 == "degrotate" and def.drawtype == "plantlike" then
|
||||
p2_max = 179
|
||||
elseif def.paramtype2 == "degrotate" and (def.drawtype == "plantlike" or def.drawtype == "mesh") then
|
||||
p2_max = 239
|
||||
elseif def.paramtype2 == "colorfacedir" or
|
||||
def.paramtype2 == "colorwallmounted" or
|
||||
def.paramtype2 == "colordegrotate" or
|
||||
def.paramtype2 == "color" then
|
||||
p2_max = 255
|
||||
end
|
||||
@ -143,7 +144,8 @@ local function place_nodes(param)
|
||||
-- Skip undefined param2 values
|
||||
if not ((def.paramtype2 == "meshoptions" and p2 % 8 > 4) or
|
||||
(def.paramtype2 == "colorwallmounted" and p2 % 8 > 5) or
|
||||
(def.paramtype2 == "colorfacedir" and p2 % 32 > 23)) then
|
||||
((def.paramtype2 == "colorfacedir" or def.paramtype2 == "colordegrotate")
|
||||
and p2 % 32 > 23)) then
|
||||
|
||||
minetest.set_node(pos, { name = itemstring, param2 = p2 })
|
||||
nodes_placed = nodes_placed + 1
|
||||
@ -215,5 +217,5 @@ minetest.register_chatcommand("test_place_nodes", {
|
||||
})
|
||||
|
||||
core.register_on_chatcommand(function(name, command, params)
|
||||
minetest.log("caught command '"..command.."', issued by '"..name.."'. Parameters: '"..params.."'")
|
||||
minetest.log("action", "caught command '"..command.."', issued by '"..name.."'. Parameters: '"..params.."'")
|
||||
end)
|
||||
|
@ -60,11 +60,13 @@ minetest.register_node("soundstuff:footstep_liquid", {
|
||||
description = "Liquid Footstep Sound Node",
|
||||
drawtype = "liquid",
|
||||
tiles = {
|
||||
"soundstuff_node_sound.png^[colorize:#0000FF:127",
|
||||
"soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190",
|
||||
},
|
||||
special_tiles = {
|
||||
{name = "soundstuff_node_sound.png^[colorize:#0000FF:127", backface_culling = false},
|
||||
{name = "soundstuff_node_sound.png^[colorize:#0000FF:127", backface_culling = true},
|
||||
{name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190",
|
||||
backface_culling = false},
|
||||
{name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190",
|
||||
backface_culling = true},
|
||||
},
|
||||
liquids_pointable = true,
|
||||
liquidtype = "source",
|
||||
@ -73,7 +75,7 @@ minetest.register_node("soundstuff:footstep_liquid", {
|
||||
liquid_renewable = false,
|
||||
liquid_range = 0,
|
||||
liquid_viscosity = 0,
|
||||
alpha = 190,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
@ -92,7 +94,6 @@ minetest.register_node("soundstuff:footstep_climbable", {
|
||||
tiles = {
|
||||
"soundstuff_node_climbable.png",
|
||||
},
|
||||
alpha = 120,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
|
@ -103,23 +103,35 @@ minetest.register_entity("testentities:nametag", {
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
if staticdata ~= "" then
|
||||
self.color = minetest.deserialize(staticdata).color
|
||||
local data = minetest.deserialize(staticdata)
|
||||
self.color = data.color
|
||||
self.bgcolor = data.bgcolor
|
||||
else
|
||||
self.color = {
|
||||
r = math.random(0, 255),
|
||||
g = math.random(0, 255),
|
||||
b = math.random(0, 255),
|
||||
}
|
||||
|
||||
if math.random(0, 10) > 5 then
|
||||
self.bgcolor = {
|
||||
r = math.random(0, 255),
|
||||
g = math.random(0, 255),
|
||||
b = math.random(0, 255),
|
||||
a = math.random(0, 255),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
assert(self.color)
|
||||
self.object:set_properties({
|
||||
nametag = tostring(math.random(1000, 10000)),
|
||||
nametag_color = self.color,
|
||||
nametag_bgcolor = self.bgcolor,
|
||||
})
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
return minetest.serialize({ color = self.color })
|
||||
return minetest.serialize({ color = self.color, bgcolor = self.bgcolor })
|
||||
end,
|
||||
})
|
||||
|
@ -33,6 +33,34 @@ local tabheaders_fs = [[
|
||||
tabheader[8,6;10,1.5;tabs_size2;Height=1.5;1;false;false]
|
||||
]]
|
||||
|
||||
local inv_style_fs = [[
|
||||
style_type[list;noclip=true]
|
||||
list[current_player;main;-0.75,0.75;2,2]
|
||||
|
||||
real_coordinates[false]
|
||||
list[current_player;main;1.5,0;3,2]
|
||||
real_coordinates[true]
|
||||
|
||||
real_coordinates[false]
|
||||
style_type[list;size=1.1;spacing=0.1]
|
||||
list[current_player;main;5,0;3,2]
|
||||
real_coordinates[true]
|
||||
|
||||
style_type[list;size=.001;spacing=0]
|
||||
list[current_player;main;7,3.5;8,4]
|
||||
|
||||
box[3,3.5;1,1;#000000]
|
||||
box[5,3.5;1,1;#000000]
|
||||
box[4,4.5;1,1;#000000]
|
||||
box[3,5.5;1,1;#000000]
|
||||
box[5,5.5;1,1;#000000]
|
||||
style_type[list;spacing=.25,.125;size=.75,.875]
|
||||
list[current_player;main;3,3.5;3,3]
|
||||
|
||||
style_type[list;spacing=0;size=1.1]
|
||||
list[current_player;main;.5,7;8,4]
|
||||
]]
|
||||
|
||||
local hypertext_basic = [[
|
||||
<bigger>Normal test</bigger>
|
||||
This is a normal text.
|
||||
@ -199,6 +227,7 @@ local scroll_fs =
|
||||
"box[1,1;8,6;#00aa]"..
|
||||
"scroll_container[1,1;8,6;scrbar;vertical]"..
|
||||
"button[0,1;1,1;lorem;Lorem]"..
|
||||
"animated_image[0,1;4.5,1;clip_animated_image;testformspec_animation.png;4;100]" ..
|
||||
"button[0,10;1,1;ipsum;Ipsum]"..
|
||||
"pwdfield[2,2;1,1;lorem2;Lorem]"..
|
||||
"list[current_player;main;4,4;1,5;]"..
|
||||
@ -211,6 +240,8 @@ local scroll_fs =
|
||||
"tooltip[0,11;3,2;Buz;#f00;#000]"..
|
||||
"box[0,11;3,2;#00ff00]"..
|
||||
"hypertext[3,13;3,3;;" .. hypertext_basic .. "]" ..
|
||||
"hypertext[3,17;3,3;;Hypertext with no scrollbar\\; the scroll container should scroll.]" ..
|
||||
"textarea[3,21;3,1;textarea;;More scroll within scroll]" ..
|
||||
"container[0,18]"..
|
||||
"box[1,2;3,2;#0a0a]"..
|
||||
"scroll_container[1,2;3,2;scrbar2;horizontal;0.06]"..
|
||||
@ -310,6 +341,9 @@ local pages = {
|
||||
"size[12,13]real_coordinates[true]" ..
|
||||
"container[0.5,1.5]" .. tabheaders_fs .. "container_end[]",
|
||||
|
||||
-- Inv
|
||||
"size[12,13]real_coordinates[true]" .. inv_style_fs,
|
||||
|
||||
-- Animation
|
||||
[[
|
||||
formspec_version[3]
|
||||
@ -328,20 +362,51 @@ Number]
|
||||
animated_image[5.5,0.5;5,2;;testformspec_animation.png;4;100]
|
||||
animated_image[5.5,2.75;5,2;;testformspec_animation.jpg;4;100]
|
||||
|
||||
]],
|
||||
|
||||
-- Model
|
||||
[[
|
||||
formspec_version[3]
|
||||
size[12,13]
|
||||
style[m1;bgcolor=black]
|
||||
model[0.5,6;4,4;m1;testformspec_character.b3d;testformspec_character.png]
|
||||
model[5,6;4,4;m2;testformspec_chest.obj;default_chest_top.png,default_chest_top.png,default_chest_side.png,default_chest_side.png,default_chest_front.png,default_chest_inside.png;30,1;true;true]
|
||||
style[m2;bgcolor=black]
|
||||
label[5,1;all defaults]
|
||||
label[5,5.1;angle = 0, 180
|
||||
continuous = false
|
||||
mouse control = false
|
||||
frame loop range = 0,30]
|
||||
label[5,9.2;continuous = true
|
||||
mouse control = true]
|
||||
model[0.5,0.1;4,4;m1;testformspec_character.b3d;testformspec_character.png]
|
||||
model[0.5,4.2;4,4;m2;testformspec_character.b3d;testformspec_character.png;0,180;false;false;0,30]
|
||||
model[0.5,8.3;4,4;m3;testformspec_chest.obj;default_chest_top.png,default_chest_top.png,default_chest_side.png,default_chest_side.png,default_chest_front.png,default_chest_inside.png;30,1;true;true]
|
||||
]],
|
||||
|
||||
-- Scroll containers
|
||||
"formspec_version[3]size[12,13]" ..
|
||||
scroll_fs,
|
||||
|
||||
-- Sound
|
||||
[[
|
||||
formspec_version[3]
|
||||
size[12,13]
|
||||
style[snd_btn;sound=soundstuff_mono]
|
||||
style[snd_ibtn;sound=soundstuff_mono]
|
||||
style[snd_drp;sound=soundstuff_mono]
|
||||
style[snd_chk;sound=soundstuff_mono]
|
||||
style[snd_tab;sound=soundstuff_mono]
|
||||
button[0.5,0.5;2,1;snd_btn;Sound]
|
||||
image_button[0.5,2;2,1;testformspec_item.png;snd_ibtn;Sound]
|
||||
dropdown[0.5,4;4;snd_drp;Sound,Two,Three;]
|
||||
checkbox[0.5,5.5.5;snd_chk;Sound;]
|
||||
tabheader[0.5,7;8,0.65;snd_tab;Soundtab1,Soundtab2,Soundtab3;1;false;false]
|
||||
]],
|
||||
}
|
||||
|
||||
local function show_test_formspec(pname, page_id)
|
||||
page_id = page_id or 2
|
||||
|
||||
local fs = pages[page_id] .. "tabheader[0,0;8,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Anim,ScrollC;" .. page_id .. ";false;false]"
|
||||
local fs = pages[page_id] .. "tabheader[0,0;8,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Anim,Model,ScrollC,Sound;" .. page_id .. ";false;false]"
|
||||
|
||||
minetest.show_formspec(pname, "testformspec:formspec", fs)
|
||||
end
|
||||
|
@ -15,22 +15,6 @@ testing this node easier and more convenient.
|
||||
|
||||
local S = minetest.get_translator("testnodes")
|
||||
|
||||
-- If set to true, will show an inventory image for nodes that have no inventory image as of Minetest 5.1.0.
|
||||
-- This is due to <https://github.com/minetest/minetest/issues/9209>.
|
||||
-- This is only added to make the items more visible to avoid confusion, but you will no longer see
|
||||
-- the default inventory images for these items. When you want to test the default inventory image of drawtypes,
|
||||
-- this should be turned off.
|
||||
-- TODO: Remove support for fallback inventory image as soon #9209 is fixed.
|
||||
local SHOW_FALLBACK_IMAGE = minetest.settings:get_bool("testnodes_show_fallback_image", false)
|
||||
|
||||
local fallback_image = function(img)
|
||||
if SHOW_FALLBACK_IMAGE then
|
||||
return img
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- A regular cube
|
||||
minetest.register_node("testnodes:normal", {
|
||||
description = S("Normal Drawtype Test Node"),
|
||||
@ -145,20 +129,15 @@ minetest.register_node("testnodes:fencelike", {
|
||||
})
|
||||
|
||||
minetest.register_node("testnodes:torchlike", {
|
||||
description = S("Torchlike Drawtype Test Node"),
|
||||
description = S("Floor Torchlike Drawtype Test Node"),
|
||||
drawtype = "torchlike",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"testnodes_torchlike_floor.png",
|
||||
"testnodes_torchlike_ceiling.png",
|
||||
"testnodes_torchlike_wall.png",
|
||||
},
|
||||
tiles = { "testnodes_torchlike_floor.png^[colorize:#FF0000:64" },
|
||||
|
||||
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
groups = { dig_immediate = 3 },
|
||||
inventory_image = fallback_image("testnodes_torchlike_floor.png"),
|
||||
})
|
||||
|
||||
minetest.register_node("testnodes:torchlike_wallmounted", {
|
||||
@ -176,12 +155,22 @@ minetest.register_node("testnodes:torchlike_wallmounted", {
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
groups = { dig_immediate = 3 },
|
||||
inventory_image = fallback_image("testnodes_torchlike_floor.png"),
|
||||
})
|
||||
|
||||
minetest.register_node("testnodes:signlike", {
|
||||
description = S("Floor Signlike Drawtype Test Node"),
|
||||
drawtype = "signlike",
|
||||
paramtype = "light",
|
||||
tiles = { "testnodes_signlike.png^[colorize:#FF0000:64" },
|
||||
|
||||
|
||||
walkable = false,
|
||||
groups = { dig_immediate = 3 },
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("testnodes:signlike", {
|
||||
minetest.register_node("testnodes:signlike_wallmounted", {
|
||||
description = S("Wallmounted Signlike Drawtype Test Node"),
|
||||
drawtype = "signlike",
|
||||
paramtype = "light",
|
||||
@ -192,7 +181,6 @@ minetest.register_node("testnodes:signlike", {
|
||||
walkable = false,
|
||||
groups = { dig_immediate = 3 },
|
||||
sunlight_propagates = true,
|
||||
inventory_image = fallback_image("testnodes_signlike.png"),
|
||||
})
|
||||
|
||||
minetest.register_node("testnodes:plantlike", {
|
||||
@ -223,6 +211,30 @@ minetest.register_node("testnodes:plantlike_waving", {
|
||||
|
||||
|
||||
-- param2 will rotate
|
||||
local function rotate_on_rightclick(pos, node, clicker)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local aux1 = clicker:get_player_control().aux1
|
||||
|
||||
local deg, deg_max
|
||||
local color, color_mult = 0, 0
|
||||
if def.paramtype2 == "degrotate" then
|
||||
deg = node.param2
|
||||
deg_max = 240
|
||||
elseif def.paramtype2 == "colordegrotate" then
|
||||
-- MSB [3x color, 5x rotation] LSB
|
||||
deg = node.param2 % 2^5
|
||||
deg_max = 24
|
||||
color_mult = 2^5
|
||||
color = math.floor(node.param2 / color_mult)
|
||||
end
|
||||
|
||||
deg = (deg + (aux1 and 10 or 1)) % deg_max
|
||||
node.param2 = color * color_mult + deg
|
||||
minetest.swap_node(pos, node)
|
||||
minetest.chat_send_player(clicker:get_player_name(),
|
||||
"Rotation is now " .. deg .. " / " .. deg_max)
|
||||
end
|
||||
|
||||
minetest.register_node("testnodes:plantlike_degrotate", {
|
||||
description = S("Degrotate Plantlike Drawtype Test Node"),
|
||||
drawtype = "plantlike",
|
||||
@ -230,12 +242,43 @@ minetest.register_node("testnodes:plantlike_degrotate", {
|
||||
paramtype2 = "degrotate",
|
||||
tiles = { "testnodes_plantlike_degrotate.png" },
|
||||
|
||||
|
||||
on_rightclick = rotate_on_rightclick,
|
||||
place_param2 = 7,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
|
||||
minetest.register_node("testnodes:mesh_degrotate", {
|
||||
description = S("Degrotate Mesh Drawtype Test Node"),
|
||||
drawtype = "mesh",
|
||||
paramtype = "light",
|
||||
paramtype2 = "degrotate",
|
||||
mesh = "testnodes_ocorner.obj",
|
||||
tiles = { "testnodes_mesh_stripes2.png" },
|
||||
|
||||
on_rightclick = rotate_on_rightclick,
|
||||
place_param2 = 10, -- 15°
|
||||
sunlight_propagates = true,
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
|
||||
minetest.register_node("testnodes:mesh_colordegrotate", {
|
||||
description = S("Color Degrotate Mesh Drawtype Test Node"),
|
||||
drawtype = "mesh",
|
||||
paramtype = "light",
|
||||
paramtype2 = "colordegrotate",
|
||||
palette = "testnodes_palette_facedir.png",
|
||||
mesh = "testnodes_ocorner.obj",
|
||||
tiles = { "testnodes_mesh_stripes3.png" },
|
||||
|
||||
on_rightclick = rotate_on_rightclick,
|
||||
-- color index 1, 1 step (=15°) rotated
|
||||
place_param2 = 1 * 2^5 + 1,
|
||||
sunlight_propagates = true,
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
|
||||
-- param2 will change height
|
||||
minetest.register_node("testnodes:plantlike_leveled", {
|
||||
description = S("Leveled Plantlike Drawtype Test Node"),
|
||||
@ -350,68 +393,72 @@ minetest.register_node("testnodes:plantlike_rooted_degrotate", {
|
||||
})
|
||||
|
||||
-- Demonstrative liquid nodes, source and flowing form.
|
||||
minetest.register_node("testnodes:liquid", {
|
||||
description = S("Source Liquid Drawtype Test Node"),
|
||||
drawtype = "liquid",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"testnodes_liquidsource.png",
|
||||
},
|
||||
special_tiles = {
|
||||
{name="testnodes_liquidsource.png", backface_culling=false},
|
||||
{name="testnodes_liquidsource.png", backface_culling=true},
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
-- DRAWTYPE ONLY, NO LIQUID PHYSICS!
|
||||
-- Liquid ranges 0 to 8
|
||||
for r = 0, 8 do
|
||||
minetest.register_node("testnodes:liquid_"..r, {
|
||||
description = S("Source Liquid Drawtype Test Node, Range @1", r),
|
||||
drawtype = "liquid",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100",
|
||||
},
|
||||
special_tiles = {
|
||||
{name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false},
|
||||
{name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=true},
|
||||
},
|
||||
use_texture_alpha = "blend",
|
||||
|
||||
|
||||
walkable = false,
|
||||
liquidtype = "source",
|
||||
liquid_range = 1,
|
||||
liquid_viscosity = 0,
|
||||
liquid_alternative_flowing = "testnodes:liquid_flowing",
|
||||
liquid_alternative_source = "testnodes:liquid",
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
minetest.register_node("testnodes:liquid_flowing", {
|
||||
description = S("Flowing Liquid Drawtype Test Node"),
|
||||
drawtype = "flowingliquid",
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
tiles = {
|
||||
"testnodes_liquidflowing.png",
|
||||
},
|
||||
special_tiles = {
|
||||
{name="testnodes_liquidflowing.png", backface_culling=false},
|
||||
{name="testnodes_liquidflowing.png", backface_culling=false},
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
liquid_range = r,
|
||||
liquid_viscosity = 0,
|
||||
liquid_alternative_flowing = "testnodes:liquid_flowing_"..r,
|
||||
liquid_alternative_source = "testnodes:liquid_"..r,
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
minetest.register_node("testnodes:liquid_flowing_"..r, {
|
||||
description = S("Flowing Liquid Drawtype Test Node, Range @1", r),
|
||||
drawtype = "flowingliquid",
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
tiles = {
|
||||
"testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100",
|
||||
},
|
||||
special_tiles = {
|
||||
{name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false},
|
||||
{name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false},
|
||||
},
|
||||
use_texture_alpha = "blend",
|
||||
|
||||
|
||||
walkable = false,
|
||||
liquidtype = "flowing",
|
||||
liquid_range = 1,
|
||||
liquid_viscosity = 0,
|
||||
liquid_alternative_flowing = "testnodes:liquid_flowing",
|
||||
liquid_alternative_source = "testnodes:liquid",
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
walkable = false,
|
||||
liquid_range = r,
|
||||
liquid_viscosity = 0,
|
||||
liquid_alternative_flowing = "testnodes:liquid_flowing_"..r,
|
||||
liquid_alternative_source = "testnodes:liquid_"..r,
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
-- Waving liquid test (drawtype only)
|
||||
minetest.register_node("testnodes:liquid_waving", {
|
||||
description = S("Waving Source Liquid Drawtype Test Node"),
|
||||
drawtype = "liquid",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"testnodes_liquidsource.png^[brighten",
|
||||
"testnodes_liquidsource.png^[colorize:#0000FF:127",
|
||||
},
|
||||
special_tiles = {
|
||||
{name="testnodes_liquidsource.png^[brighten", backface_culling=false},
|
||||
{name="testnodes_liquidsource.png^[brighten", backface_culling=true},
|
||||
{name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=false},
|
||||
{name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=true},
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
use_texture_alpha = "blend",
|
||||
waving = 3,
|
||||
|
||||
|
||||
walkable = false,
|
||||
liquidtype = "source",
|
||||
liquid_range = 1,
|
||||
liquid_viscosity = 0,
|
||||
liquid_alternative_flowing = "testnodes:liquid_flowing_waving",
|
||||
@ -424,18 +471,17 @@ minetest.register_node("testnodes:liquid_flowing_waving", {
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
tiles = {
|
||||
"testnodes_liquidflowing.png^[brighten",
|
||||
"testnodes_liquidflowing.png^[colorize:#0000FF:127",
|
||||
},
|
||||
special_tiles = {
|
||||
{name="testnodes_liquidflowing.png^[brighten", backface_culling=false},
|
||||
{name="testnodes_liquidflowing.png^[brighten", backface_culling=false},
|
||||
{name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false},
|
||||
{name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false},
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
use_texture_alpha = "blend",
|
||||
waving = 3,
|
||||
|
||||
|
||||
walkable = false,
|
||||
liquidtype = "flowing",
|
||||
liquid_range = 1,
|
||||
liquid_viscosity = 0,
|
||||
liquid_alternative_flowing = "testnodes:liquid_flowing_waving",
|
||||
@ -443,8 +489,6 @@ minetest.register_node("testnodes:liquid_flowing_waving", {
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
|
||||
|
||||
|
||||
-- Invisible node
|
||||
minetest.register_node("testnodes:airlike", {
|
||||
description = S("Airlike Drawtype Test Node"),
|
||||
@ -455,7 +499,6 @@ minetest.register_node("testnodes:airlike", {
|
||||
walkable = false,
|
||||
groups = { dig_immediate = 3 },
|
||||
sunlight_propagates = true,
|
||||
inventory_image = fallback_image("testnodes_airlike.png"),
|
||||
})
|
||||
|
||||
-- param2 changes liquid height
|
||||
@ -548,7 +591,7 @@ scale("plantlike",
|
||||
scale("torchlike_wallmounted",
|
||||
S("Double-sized Wallmounted Torchlike Drawtype Test Node"),
|
||||
S("Half-sized Wallmounted Torchlike Drawtype Test Node"))
|
||||
scale("signlike",
|
||||
scale("signlike_wallmounted",
|
||||
S("Double-sized Wallmounted Signlike Drawtype Test Node"),
|
||||
S("Half-sized Wallmounted Signlike Drawtype Test Node"))
|
||||
scale("firelike",
|
||||
|
@ -9,11 +9,9 @@ for d=0, 8 do
|
||||
{name = "testnodes_liquidsource_r"..d..".png", backface_culling = false},
|
||||
{name = "testnodes_liquidsource_r"..d..".png", backface_culling = true},
|
||||
},
|
||||
alpha = 192,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
liquidtype = "source",
|
||||
@ -30,12 +28,10 @@ for d=0, 8 do
|
||||
{name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false},
|
||||
{name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false},
|
||||
},
|
||||
alpha = 192,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
liquidtype = "flowing",
|
||||
@ -53,11 +49,9 @@ for d=0, 8 do
|
||||
{name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false},
|
||||
{name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true},
|
||||
},
|
||||
alpha = 192,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
liquidtype = "source",
|
||||
@ -74,12 +68,10 @@ for d=0, 8 do
|
||||
{name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
|
||||
{name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
|
||||
},
|
||||
alpha = 192,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
liquidtype = "flowing",
|
||||
|
@ -114,11 +114,10 @@ minetest.register_node("testnodes:liquid_nojump", {
|
||||
{name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = false},
|
||||
{name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = true},
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
pointable = false,
|
||||
liquids_pointable = true,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
post_effect_color = {a = 70, r = 255, g = 0, b = 200},
|
||||
@ -143,12 +142,11 @@ minetest.register_node("testnodes:liquidflowing_nojump", {
|
||||
{name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false},
|
||||
{name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false},
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
use_texture_alpha = "blend",
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
pointable = false,
|
||||
liquids_pointable = true,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
post_effect_color = {a = 70, r = 255, g = 0, b = 200},
|
||||
|
@ -1,4 +0,0 @@
|
||||
# If set to true, will show an inventory image for nodes that have no inventory image as of Minetest 5.1.0.
|
||||
# This is due to <https://github.com/minetest/minetest/issues/9209>.
|
||||
# This is only added to make the items more visible to avoid confusion, but you will no longer see the default inventory images for these items. When you want to test the default inventory image of drawtypes, this should be turned off.
|
||||
testnodes_show_fallback_image (Use fallback inventory images) bool false
|
@ -46,77 +46,22 @@ for a=1,#alphas do
|
||||
tiles = {
|
||||
"testnodes_alpha"..alpha..".png",
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
use_texture_alpha = "blend",
|
||||
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
|
||||
-- Transparency set via "alpha" parameter
|
||||
-- Transparency set via texture modifier
|
||||
minetest.register_node("testnodes:alpha_"..alpha, {
|
||||
description = S("Alpha Test Node (@1)", alpha),
|
||||
-- It seems that only the liquid drawtype supports the alpha parameter
|
||||
drawtype = "liquid",
|
||||
drawtype = "glasslike",
|
||||
paramtype = "light",
|
||||
tiles = {
|
||||
"testnodes_alpha.png",
|
||||
"testnodes_alpha.png^[opacity:" .. alpha,
|
||||
},
|
||||
alpha = alpha,
|
||||
use_texture_alpha = "blend",
|
||||
|
||||
|
||||
liquidtype = "source",
|
||||
liquid_range = 0,
|
||||
liquid_viscosity = 0,
|
||||
liquid_alternative_source = "testnodes:alpha_"..alpha,
|
||||
liquid_alternative_flowing = "testnodes:alpha_"..alpha,
|
||||
groups = { dig_immediate = 3 },
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-- Bumpmapping and Parallax Occlusion
|
||||
|
||||
-- This node has a normal map which corresponds to a pyramid with sides tilted
|
||||
-- by an angle of 45°, i.e. the normal map contains four vectors which point
|
||||
-- diagonally away from the surface (e.g. (0.7, 0.7, 0)),
|
||||
-- and the heights in the height map linearly increase towards the centre,
|
||||
-- so that the surface corresponds to a simple pyramid.
|
||||
-- The node can help to determine if e.g. tangent space transformations work
|
||||
-- correctly.
|
||||
-- If, for example, the light comes from above, then the (tilted) pyramids
|
||||
-- should look like they're lit from this light direction on all node faces.
|
||||
-- The white albedo texture has small black indicators which can be used to see
|
||||
-- how it is transformed ingame (and thus see if there's rotation around the
|
||||
-- normal vector).
|
||||
minetest.register_node("testnodes:height_pyramid", {
|
||||
description = "Bumpmapping and Parallax Occlusion Tester (height pyramid)",
|
||||
tiles = {"testnodes_height_pyramid.png"},
|
||||
groups = {dig_immediate = 3},
|
||||
})
|
||||
|
||||
-- The stairs nodes should help to validate if shading works correctly for
|
||||
-- rotated nodes (which have rotated textures).
|
||||
stairs.register_stair_and_slab("height_pyramid", "experimantal:height_pyramid",
|
||||
{dig_immediate = 3},
|
||||
{"testnodes_height_pyramid.png"},
|
||||
"Bumpmapping and Parallax Occlusion Tester Stair (height pyramid)",
|
||||
"Bumpmapping and Parallax Occlusion Tester Slab (height pyramid)")
|
||||
|
||||
-- This node has a simple heightmap for parallax occlusion testing and flat
|
||||
-- normalmap.
|
||||
-- When parallax occlusion is enabled, the yellow scrawl should stick out of
|
||||
-- the texture when viewed at an angle.
|
||||
minetest.register_node("testnodes:parallax_extruded", {
|
||||
description = "Parallax Occlusion Tester",
|
||||
tiles = {"testnodes_parallax_extruded.png"},
|
||||
groups = {dig_immediate = 3},
|
||||
})
|
||||
|
||||
-- Analogously to the height pyramid stairs nodes,
|
||||
-- these nodes should help to validate if parallax occlusion works correctly for
|
||||
-- rotated nodes (which have rotated textures).
|
||||
stairs.register_stair_and_slab("parallax_extruded",
|
||||
"experimantal:parallax_extruded",
|
||||
{dig_immediate = 3},
|
||||
{"testnodes_parallax_extruded.png"},
|
||||
"Parallax Occlusion Tester Stair",
|
||||
"Parallax Occlusion Tester Slab")
|
||||
|
Before Width: | Height: | Size: 90 B |
Before Width: | Height: | Size: 239 B |
Before Width: | Height: | Size: 591 B |
Before Width: | Height: | Size: 143 B |
@ -33,6 +33,13 @@ Usage:
|
||||
* Punch node: Make it fall
|
||||
* Place: Try to teleport up to 2 units upwards, then make it fall
|
||||
|
||||
## Node Meta Editor
|
||||
Edit and view metadata of nodes.
|
||||
|
||||
Usage:
|
||||
|
||||
* Punch: Open node metadata editor
|
||||
|
||||
## Entity Rotator
|
||||
Changes the entity rotation (with `set_rotation`).
|
||||
|
||||
@ -90,6 +97,13 @@ Usage:
|
||||
* Place: Increase move distance
|
||||
* Sneak+place: Decrease move distance
|
||||
|
||||
## Children Getter
|
||||
Shows list of objects that are attached to an object (aka "children") in chat.
|
||||
|
||||
Usage:
|
||||
* Punch object: Show children of punched object
|
||||
* Punch air: Show your own children
|
||||
|
||||
## Entity Visual Scaler
|
||||
Change visual size of entities
|
||||
|
||||
@ -97,3 +111,10 @@ Usage:
|
||||
|
||||
* Punch entity to increase visual size
|
||||
* Sneak+punch entity to decrease visual size
|
||||
|
||||
## Light Tool
|
||||
Show light level of node.
|
||||
|
||||
Usage:
|
||||
* Punch: Show light info of node in front of the punched node's side
|
||||
* Place: Show light info of the node that you touched
|
||||
|
@ -3,8 +3,6 @@ local F = minetest.formspec_escape
|
||||
|
||||
dofile(minetest.get_modpath("testtools") .. "/light.lua")
|
||||
|
||||
-- TODO: Add a Node Metadata tool
|
||||
|
||||
minetest.register_tool("testtools:param2tool", {
|
||||
description = S("Param2 Tool") .."\n"..
|
||||
S("Modify param2 value of nodes") .."\n"..
|
||||
@ -111,25 +109,6 @@ minetest.register_tool("testtools:node_setter", {
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname == "testtools:node_setter" then
|
||||
local playername = player:get_player_name()
|
||||
local witem = player:get_wielded_item()
|
||||
if witem:get_name() == "testtools:node_setter" then
|
||||
if fields.nodename and fields.param2 then
|
||||
local param2 = tonumber(fields.param2)
|
||||
if not param2 then
|
||||
return
|
||||
end
|
||||
local meta = witem:get_meta()
|
||||
meta:set_string("node", fields.nodename)
|
||||
meta:set_int("node_param2", param2)
|
||||
player:set_wielded_item(witem)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_tool("testtools:remover", {
|
||||
description = S("Remover") .."\n"..
|
||||
S("Punch: Remove pointed node or object"),
|
||||
@ -634,6 +613,54 @@ minetest.register_tool("testtools:object_attacher", {
|
||||
end,
|
||||
})
|
||||
|
||||
local function print_object(obj)
|
||||
if obj:is_player() then
|
||||
return "player '"..obj:get_player_name().."'"
|
||||
elseif obj:get_luaentity() then
|
||||
return "LuaEntity '"..obj:get_luaentity().name.."'"
|
||||
else
|
||||
return "object"
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_tool("testtools:children_getter", {
|
||||
description = S("Children Getter") .."\n"..
|
||||
S("Shows list of objects attached to object") .."\n"..
|
||||
S("Punch object to show its 'children'") .."\n"..
|
||||
S("Punch air to show your own 'children'"),
|
||||
inventory_image = "testtools_children_getter.png",
|
||||
groups = { testtool = 1, disable_repair = 1 },
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if user and user:is_player() then
|
||||
local name = user:get_player_name()
|
||||
local selected_object
|
||||
local self_name
|
||||
if pointed_thing.type == "object" then
|
||||
selected_object = pointed_thing.ref
|
||||
elseif pointed_thing.type == "nothing" then
|
||||
selected_object = user
|
||||
else
|
||||
return
|
||||
end
|
||||
self_name = print_object(selected_object)
|
||||
local children = selected_object:get_children()
|
||||
local ret = ""
|
||||
for c=1, #children do
|
||||
ret = ret .. "* " .. print_object(children[c])
|
||||
if c < #children then
|
||||
ret = ret .. "\n"
|
||||
end
|
||||
end
|
||||
if ret == "" then
|
||||
ret = S("No children attached to @1.", self_name)
|
||||
else
|
||||
ret = S("Children of @1:", self_name) .. "\n" .. ret
|
||||
end
|
||||
minetest.chat_send_player(user:get_player_name(), ret)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Use loadstring to parse param as a Lua value
|
||||
local function use_loadstring(param, player)
|
||||
-- For security reasons, require 'server' priv, just in case
|
||||
@ -666,6 +693,68 @@ local function use_loadstring(param, player)
|
||||
return true, errOrResult
|
||||
end
|
||||
|
||||
-- Node Meta Editor
|
||||
local node_meta_posses = {}
|
||||
local node_meta_latest_keylist = {}
|
||||
|
||||
local function show_node_meta_formspec(user, pos, key, value, keylist)
|
||||
local textlist
|
||||
if keylist then
|
||||
textlist = "textlist[0,0.5;2.5,6.5;keylist;"..keylist.."]"
|
||||
else
|
||||
textlist = ""
|
||||
end
|
||||
minetest.show_formspec(user:get_player_name(),
|
||||
"testtools:node_meta_editor",
|
||||
"size[15,9]"..
|
||||
"label[0,0;"..F(S("Current keys:")).."]"..
|
||||
textlist..
|
||||
"field[3,0.5;12,1;key;"..F(S("Key"))..";"..F(key).."]"..
|
||||
"textarea[3,1.5;12,6;value;"..F(S("Value (use empty value to delete key)"))..";"..F(value).."]"..
|
||||
"button[0,8;3,1;get;"..F(S("Get value")).."]"..
|
||||
"button[4,8;3,1;set;"..F(S("Set value")).."]"..
|
||||
"label[0,7.2;"..F(S("pos = @1", minetest.pos_to_string(pos))).."]")
|
||||
end
|
||||
|
||||
local function get_node_meta_keylist(meta, playername, escaped)
|
||||
local keys = {}
|
||||
local ekeys = {}
|
||||
local mtable = meta:to_table()
|
||||
for k,_ in pairs(mtable.fields) do
|
||||
table.insert(keys, k)
|
||||
if escaped then
|
||||
table.insert(ekeys, F(k))
|
||||
else
|
||||
table.insert(ekeys, k)
|
||||
end
|
||||
end
|
||||
if playername then
|
||||
node_meta_latest_keylist[playername] = keys
|
||||
end
|
||||
return table.concat(ekeys, ",")
|
||||
end
|
||||
|
||||
minetest.register_tool("testtools:node_meta_editor", {
|
||||
description = S("Node Meta Editor") .. "\n" ..
|
||||
S("Place: Edit node metadata"),
|
||||
inventory_image = "testtools_node_meta_editor.png",
|
||||
groups = { testtool = 1, disable_repair = 1 },
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return itemstack
|
||||
end
|
||||
if not user:is_player() then
|
||||
return itemstack
|
||||
end
|
||||
local pos = pointed_thing.under
|
||||
node_meta_posses[user:get_player_name()] = pos
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
show_node_meta_formspec(user, pos, "", "", get_node_meta_keylist(meta, user:get_player_name(), true))
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if not (player and player:is_player()) then
|
||||
return
|
||||
@ -728,5 +817,70 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
editor_formspec(name, selected_objects[name], prop_to_string(props[key]), sel)
|
||||
return
|
||||
end
|
||||
elseif formname == "testtools:node_setter" then
|
||||
local playername = player:get_player_name()
|
||||
local witem = player:get_wielded_item()
|
||||
if witem:get_name() == "testtools:node_setter" then
|
||||
if fields.nodename and fields.param2 then
|
||||
local param2 = tonumber(fields.param2)
|
||||
if not param2 then
|
||||
return
|
||||
end
|
||||
local meta = witem:get_meta()
|
||||
meta:set_string("node", fields.nodename)
|
||||
meta:set_int("node_param2", param2)
|
||||
player:set_wielded_item(witem)
|
||||
end
|
||||
end
|
||||
elseif formname == "testtools:node_meta_editor" then
|
||||
local name = player:get_player_name()
|
||||
local pos = node_meta_posses[name]
|
||||
if fields.keylist then
|
||||
local evnt = minetest.explode_textlist_event(fields.keylist)
|
||||
if evnt.type == "DCL" or evnt.type == "CHG" then
|
||||
local keylist_table = node_meta_latest_keylist[name]
|
||||
if not pos then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if not keylist_table then
|
||||
return
|
||||
end
|
||||
if #keylist_table == 0 then
|
||||
return
|
||||
end
|
||||
local key = keylist_table[evnt.index]
|
||||
local value = meta:get_string(key)
|
||||
local keylist_escaped = {}
|
||||
for k,v in pairs(keylist_table) do
|
||||
keylist_escaped[k] = F(v)
|
||||
end
|
||||
local keylist = table.concat(keylist_escaped, ",")
|
||||
show_node_meta_formspec(player, pos, key, value, keylist)
|
||||
return
|
||||
end
|
||||
elseif fields.key and fields.key ~= "" and fields.value then
|
||||
if not pos then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if fields.get then
|
||||
local value = meta:get_string(fields.key)
|
||||
show_node_meta_formspec(player, pos, fields.key, value,
|
||||
get_node_meta_keylist(meta, name, true))
|
||||
return
|
||||
elseif fields.set then
|
||||
meta:set_string(fields.key, fields.value)
|
||||
show_node_meta_formspec(player, pos, fields.key, fields.value,
|
||||
get_node_meta_keylist(meta, name, true))
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
node_meta_latest_keylist[name] = nil
|
||||
node_meta_posses[name] = nil
|
||||
end)
|
||||
|
@ -1,22 +1,37 @@
|
||||
|
||||
local S = minetest.get_translator("testtools")
|
||||
|
||||
minetest.register_tool("testtools:lighttool", {
|
||||
description = S("Light tool"),
|
||||
inventory_image = "testtools_lighttool.png",
|
||||
groups = { testtool = 1, disable_repair = 1 },
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
local pos = pointed_thing.above
|
||||
local function get_func(is_place)
|
||||
return function(itemstack, user, pointed_thing)
|
||||
local pos
|
||||
if is_place then
|
||||
pos = pointed_thing.under
|
||||
else
|
||||
pos = pointed_thing.above
|
||||
end
|
||||
if pointed_thing.type ~= "node" or not pos then
|
||||
return
|
||||
end
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
local pstr = minetest.pos_to_string(pos)
|
||||
local time = minetest.get_timeofday()
|
||||
local sunlight = minetest.get_natural_light(pos)
|
||||
local artificial = minetest.get_artificial_light(node.param1)
|
||||
local message = ("param1 0x%02x | time %.5f | sunlight %d | artificial %d")
|
||||
:format(node.param1, time, sunlight, artificial)
|
||||
local message = ("pos=%s | param1=0x%02x | " ..
|
||||
"sunlight=%d | artificial=%d | timeofday=%.5f" )
|
||||
:format(pstr, node.param1, sunlight, artificial, time)
|
||||
minetest.chat_send_player(user:get_player_name(), message)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_tool("testtools:lighttool", {
|
||||
description = S("Light Tool") .. "\n" ..
|
||||
S("Show light values of node") .. "\n" ..
|
||||
S("Punch: Light of node above touched node") .. "\n" ..
|
||||
S("Place: Light of touched node itself"),
|
||||
inventory_image = "testtools_lighttool.png",
|
||||
groups = { testtool = 1, disable_repair = 1 },
|
||||
on_use = get_func(false),
|
||||
on_place = get_func(true),
|
||||
})
|
||||
|
After Width: | Height: | Size: 281 B |