Merge 0.4.16 into stable-0.4

This commit is contained in:
ShadowNinja 2017-06-03 14:55:10 -04:00
commit caecdb681c
637 changed files with 95690 additions and 40930 deletions

28
.clang-format Normal file

@ -0,0 +1,28 @@
BasedOnStyle: LLVM
IndentWidth: 8
UseTab: Always
BreakBeforeBraces: Custom
Standard: Cpp03
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
BeforeCatch: false
BeforeElse: false
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
AccessModifierOffset: -8
ColumnLimit: 90
AllowShortFunctionsOnASingleLine: Inline
SortIncludes: false
IncludeCategories:
- Regex: '^".*'
Priority: 2
- Regex: '^<.*'
Priority: 1
AlignAfterOpenBracket: DontAlign
ContinuationIndentWidth: 16

14
.gitignore vendored

@ -22,9 +22,12 @@ tags
!tags/
gtags.files
.idea/*
# Codelite
*.project
## Files related to minetest development cycle
/*.patch
*.diff
# GNU Patch reject file
*.rej
@ -43,11 +46,17 @@ gtags.files
!/mods/minetest/mods_here.txt
/worlds
/world/
/clientmods/*
!/clientmods/preview/
/client/mod_storage/
## Configuration/log files
minetest.conf
debug.txt
## Other files generated by minetest
screenshot_*.png
## Doxygen files
doc/Doxyfile
doc/html/
@ -74,16 +83,19 @@ locale/
*.a
*.ninja
.ninja*
*.gch
cmake-build-debug/
cmake-build-release/
## Android build files
build/android/src/main/assets
build/android/build
build/android/deps
build/android/libs
build/android/jni/lib
build/android/jni/src
build/android/src/main/jniLibs
build/android/obj
build/android/local.properties
build/android/.gradle
timestamp

223
.gitlab-ci.yml Normal file

@ -0,0 +1,223 @@
---
# Github repository is cloned every day on Gitlab.com
# https://gitlab.com/minetest/minetest
# Pipelines URL: https://gitlab.com/minetest/minetest/pipelines
stages:
- build
- package
- deploy
variables:
MINETEST_GAME_REPO: "https://github.com/minetest/minetest_game.git"
.build_template: &build_definition
stage: build
script:
- 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 -DBUILD_SERVER=TRUE ..
- make -j2
- make install
artifacts:
when: on_success
expire_in: 1h
paths:
- artifact/*
.debpkg_template: &debpkg_template
stage: package
before_script:
- apt-get update -y
- apt-get install -y git
- mkdir -p build/deb/minetest/DEBIAN/
- cp misc/debpkg-control build/deb/minetest/DEBIAN/control
- cp -Rp artifact/minetest/usr build/deb/minetest/
script:
- git clone $MINETEST_GAME_REPO build/deb/minetest/usr/share/minetest/games/minetest
- 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/LEVELDB_PLACEHOLDER/'$LEVELDB_PKG'/g' build/deb/minetest/DEBIAN/control
- cd build/deb/ && dpkg-deb -b minetest/
artifacts:
when: on_success
expire_in: 30 day
paths:
- build/deb/*.deb
.debpkg_install: &debpkg_install
stage: deploy
before_script:
- apt-get update -y
- apt-get install -y libc6 libcurl3-gnutls libfreetype6 libirrlicht1.8 $LEVELDB_PKG liblua5.1-0 libluajit-5.1-2 libopenal1 libstdc++6 libvorbisfile3 libx11-6 zlib1g
script:
- dpkg -i build/deb/*.deb
##
## Debian
##
# Jessie
build:debian-8:
<<: *build_definition
image: debian:8
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-8:
image: debian:8
dependencies:
- build:debian-8
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_template
deploy:debian-8:
image: debian:8
dependencies:
- package:debian-8
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_install
# Stretch
build:debian-9:
<<: *build_definition
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:
image: debian:9
dependencies:
- build:debian-9
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_template
deploy:debian-9:
image: debian:9
dependencies:
- package:debian-9
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_install
##
## Ubuntu
##
# Trusty
build:ubuntu-14.04:
<<: *build_definition
image: ubuntu:trusty
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-14.04:
image: ubuntu:trusty
dependencies:
- build:ubuntu-14.04
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_template
deploy:ubuntu-14.04:
image: ubuntu:trusty
dependencies:
- package:ubuntu-14.04
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_install
# Xenial
build:ubuntu-16.04:
<<: *build_definition
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:
image: ubuntu:xenial
dependencies:
- build:ubuntu-16.04
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_template
deploy:ubuntu-16.04:
image: ubuntu:xenial
dependencies:
- package:ubuntu-16.04
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_install
# Yakkety
build:ubuntu-16.10:
<<: *build_definition
image: ubuntu:yakkety
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.10:
image: ubuntu:yakkety
dependencies:
- build:ubuntu-16.10
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_template
deploy:ubuntu-16.10:
image: ubuntu:yakkety
dependencies:
- package:ubuntu-16.10
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_install
# Zesty
build:ubuntu-17.04:
<<: *build_definition
image: ubuntu:zesty
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-17.04:
image: ubuntu:zesty
dependencies:
- build:ubuntu-17.04
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_template
deploy:ubuntu-17.04:
image: ubuntu:zesty
dependencies:
- package:ubuntu-17.04
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_install
##
## Fedora
##
build:fedora-24:
<<: *build_definition
image: fedora:24
before_script:
- dnf -y install make automake gcc gcc-c++ kernel-devel cmake libcurl* openal* libvorbis* 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

@ -22,6 +22,14 @@ matrix:
- env: PLATFORM=Unix COMPILER=clang
compiler: clang
os: linux
- env: PLATFORM=Unix COMPILER=clang VALGRIND=1
compiler: clang
os: linux
dist: trusty
- env: COMPILER=none LINT=1
compiler: clang
os: linux
dist: trusty
- env: PLATFORM=Unix COMPILER=g++-6
compiler: gcc
os: linux

@ -13,7 +13,7 @@ set(PROJECT_NAME_CAPITALIZED "Minetest")
# Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing
set(VERSION_MAJOR 0)
set(VERSION_MINOR 4)
set(VERSION_PATCH 15)
set(VERSION_PATCH 16)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
# Change to false for releases
@ -26,6 +26,11 @@ elseif(DEVELOPMENT_BUILD)
set(VERSION_STRING "${VERSION_STRING}-dev")
endif()
if (CMAKE_BUILD_TYPE STREQUAL Debug)
# Append "-debug" to version string
set(VERSION_STRING "${VERSION_STRING}-debug")
endif()
message(STATUS "*** Will build version ${VERSION_STRING} ***")
@ -49,7 +54,6 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE)
endif()
# Included stuff
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
@ -82,7 +86,7 @@ elseif(UNIX) # Linux, BSD etc
set(EXAMPLE_CONF_DIR ".")
set(MANDIR "unix/man")
set(XDG_APPS_DIR "unix/applications")
set(APPDATADIR "unix/appdata")
set(APPDATADIR "unix/metainfo")
set(ICONDIR "unix/icons")
set(LOCALEDIR "locale")
else()
@ -92,7 +96,7 @@ elseif(UNIX) # Linux, BSD etc
set(MANDIR "${CMAKE_INSTALL_PREFIX}/share/man")
set(EXAMPLE_CONF_DIR ${DOCDIR})
set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/appdata")
set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/metainfo")
set(ICONDIR "${CMAKE_INSTALL_PREFIX}/share/icons")
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/locale")
endif()
@ -152,6 +156,7 @@ endif()
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client" DESTINATION "${SHAREDIR}")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/clientmods" DESTINATION "${SHAREDIR}")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games" DESTINATION "${SHAREDIR}" PATTERN ".git*" EXCLUDE)
if(BUILD_CLIENT)
@ -173,8 +178,8 @@ install(FILES "minetest.conf.example" DESTINATION "${EXAMPLE_CONF_DIR}")
if(UNIX AND NOT APPLE)
install(FILES "doc/minetest.6" "doc/minetestserver.6" DESTINATION "${MANDIR}/man6")
install(FILES "misc/minetest.desktop" DESTINATION "${XDG_APPS_DIR}")
install(FILES "misc/minetest.appdata.xml" DESTINATION "${APPDATADIR}")
install(FILES "misc/net.minetest.minetest.desktop" DESTINATION "${XDG_APPS_DIR}")
install(FILES "misc/net.minetest.minetest.appdata.xml" DESTINATION "${APPDATADIR}")
install(FILES "misc/minetest.svg" DESTINATION "${ICONDIR}/hicolor/scalable/apps")
install(FILES "misc/minetest-xorg-icon-128.png"
DESTINATION "${ICONDIR}/hicolor/128x128/apps"
@ -186,6 +191,10 @@ if(APPLE)
install(FILES "misc/Info.plist" DESTINATION "${BUNDLE_PATH}/Contents")
endif()
# Library pack
find_package(GMP REQUIRED)
find_package(Json REQUIRED)
find_package(Lua REQUIRED)
# Subdirectories
# Be sure to add all relevant definitions above this

@ -25,7 +25,6 @@ If you are planning to start some significant coding, you would benefit from ask
- Have a title which begins with a capital letter
- Be descriptive. (e.g. no `Update init.lua` or `Fix a problem`)
- Have a first line with less than *80 characters* and have a second line that is *empty*
- Do **not** [sign your commits](https://git-scm.com/book/uz/v2/Git-Tools-Signing-Your-Work), as Minetest offers automatically built ppas over launchpad and it [would break](https://bugs.launchpad.net/bzr-git/+bug/1084403) if there were signed commits in master
4. Once you are happy with your changes, submit a pull request.
- Open the [pull-request form](https://github.com/minetest/minetest/pull/new/master)

@ -3,7 +3,7 @@ Minetest
An InfiniMiner/Minecraft inspired game.
Copyright (c) 2010-2013 Perttu Ahola <celeron55@gmail.com>
Copyright (c) 2010-2017 Perttu Ahola <celeron55@gmail.com>
and contributors (see source file comments and the version control log)
In case you downloaded the source code:
@ -43,7 +43,7 @@ Default controls
- 0-9: Select item
- Z: Zoom (needs zoom privilege)
- T: Chat
- /: Commad
- /: Command
- Esc: Pause menu/abort/exit (pauses only singleplayer game)
- R: Enable/disable full range view
@ -85,7 +85,7 @@ $bin = /usr/bin
$share = /usr/share/minetest
$user = ~/.minetest
OS X:
macOS:
$bin = Contents/MacOS
$share = Contents/Resources
$user = Contents/User OR ~/Library/Application Support/minetest
@ -101,7 +101,9 @@ Configuration file:
$user/minetest.conf
- It is created by Minetest when it is ran the first time.
- A specific file can be specified on the command line:
--config <path-to-file>
--config <path-to-file>
- A run-in-place build will look for the configuration file in
$location_of_exe/../minetest.conf and also $location_of_exe/../../minetest.conf
Command-line options:
---------------------
@ -117,7 +119,7 @@ For Fedora users:
$ sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl* openal* libvorbis* 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
You can install git for easily keeping your copy up to date.
If you dont want git, read below on how to get the source without git.
If you dont want git, read below on how to get the source without git.
This is an example for installing git on Debian/Ubuntu:
$ sudo apt-get install git
@ -178,7 +180,7 @@ ENABLE_FREETYPE - Build with FreeType2; Allows using TTF fonts
ENABLE_GETTEXT - Build with Gettext; Allows using translations
ENABLE_GLES - Search for Open GLES headers & libraries and use them
ENABLE_LEVELDB - Build with LevelDB; Enables use of LevelDB map backend
ENABLE_POSTGRESQL - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater required)
ENABLE_POSTGRESQL - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
ENABLE_REDIS - Build with libhiredis; Enables use of Redis map backend
ENABLE_SPATIAL - Build with LibSpatial; Speeds up AreaStores
ENABLE_SOUND - Build with OpenAL, libogg & libvorbis; in-game Sounds
@ -212,7 +214,7 @@ IRRLICHT_LIBRARY - Path to libIrrlicht.a/libIrrlicht.so/libIrrlic
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
POSTGRESQL_INCLUDE_DIR - Only when building with PostgreSQL; directory that contains libpq-fe.h
PostgreSQL_INCLUDE_DIR - Only when building with PostgreSQL; directory that contains libpq-fe.h
POSTGRESQL_LIBRARY - Only when building with PostgreSQL; path to libpq.a/libpq.so
REDIS_INCLUDE_DIR - Only when building with Redis; directory that contains hiredis.h
REDIS_LIBRARY - Only when building with Redis; path to libhiredis.a/libhiredis.so
@ -427,7 +429,7 @@ License of Minetest source code
-------------------------------
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2017 celeron55, Perttu Ahola <celeron55@gmail.com>
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
@ -502,7 +504,7 @@ Lua is licensed under the terms of the MIT license reproduced below.
This means that Lua is free software and can be used for both academic
and commercial purposes at absolutely no cost.
For details and rationale, see http://www.lua.org/license.html .
For details and rationale, see https://www.lua.org/license.html .
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
@ -527,25 +529,18 @@ THE SOFTWARE.
Fonts
---------------
DejaVu Sans Mono:
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
Bitstream Vera Fonts Copyright:
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
a trademark of Bitstream, Inc.
Arev Fonts Copyright:
Arimo - Apache License, version 2.0
Digitized data copyright (c) 2010-2012 Google Corporation.
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
Cousine - Apache License, version 2.0
Digitized data copyright (c) 2010-2012 Google Corporation.
Liberation Fonts Copyright:
Copyright (c) 2007 Red Hat, Inc. All rights reserved. LIBERATION is a trademark of Red Hat, Inc.
DroidSansFallback:
DroidSansFallBackFull:
Copyright (C) 2008 The Android Open Source Project

@ -35,7 +35,7 @@ TARGET_CXXFLAGS_ADDON = $(TARGET_CFLAGS_ADDON)
TARGET_ARCH = armv7
CROSS_PREFIX = arm-linux-androideabi-
COMPILER_VERSION = 4.9
HAVE_LEVELDB = 1
HAVE_LEVELDB = 0
################################################################################
# toolchain config for little endian mips
@ -59,7 +59,7 @@ HAVE_LEVELDB = 1
#CROSS_PREFIX = i686-linux-android-
#TARGET_ARCH = x86
#COMPILER_VERSION = 4.9
#HAVE_LEVELDB = 1
#HAVE_LEVELDB = 0
################################################################################
ASSETS_TIMESTAMP = deps/assets_timestamp
@ -84,14 +84,14 @@ OGG_TIMESTAMP = $(OGG_DIR)timestamp
OGG_TIMESTAMP_INT = $(ANDR_ROOT)/deps/ogg_timestamp
OGG_URL_GIT = https://github.com/vincentjames501/libvorbis-libogg-android
IRRLICHT_REVISION = 5122
IRRLICHT_REVISION = 5145
IRRLICHT_DIR = $(ANDR_ROOT)/deps/irrlicht/
IRRLICHT_LIB = $(IRRLICHT_DIR)lib/Android/libIrrlicht.a
IRRLICHT_TIMESTAMP = $(IRRLICHT_DIR)timestamp
IRRLICHT_TIMESTAMP_INT = $(ANDR_ROOT)/deps/irrlicht_timestamp
IRRLICHT_URL_SVN = https://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@$(IRRLICHT_REVISION)
OPENSSL_VERSION = 1.0.2j
OPENSSL_VERSION = 1.0.2k
OPENSSL_BASEDIR = openssl-$(OPENSSL_VERSION)
OPENSSL_DIR = $(ANDR_ROOT)/deps/$(OPENSSL_BASEDIR)/
OPENSSL_LIB = $(OPENSSL_DIR)/libssl.so.1.0.0
@ -99,7 +99,7 @@ OPENSSL_TIMESTAMP = $(OPENSSL_DIR)timestamp
OPENSSL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openssl_timestamp
OPENSSL_URL = https://www.openssl.org/source/openssl-$(OPENSSL_VERSION).tar.gz
CURL_VERSION = 7.52.0
CURL_VERSION = 7.54.0
CURL_DIR = $(ANDR_ROOT)/deps/curl-$(CURL_VERSION)
CURL_LIB = $(CURL_DIR)/lib/.libs/libcurl.a
CURL_TIMESTAMP = $(CURL_DIR)/timestamp
@ -126,8 +126,8 @@ ICONV_TIMESTAMP = $(ICONV_DIR)timestamp
ICONV_TIMESTAMP_INT = $(ANDR_ROOT)/deps/iconv_timestamp
ICONV_URL_HTTP = https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz
SQLITE3_FOLDER = sqlite-amalgamation-3150200
SQLITE3_URL = https://www.sqlite.org/2016/$(SQLITE3_FOLDER).zip
SQLITE3_FOLDER = sqlite-amalgamation-3180000
SQLITE3_URL = https://www.sqlite.org/2017/$(SQLITE3_FOLDER).zip
ANDROID_SDK = $(shell grep '^sdk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
ANDROID_NDK = $(shell grep '^ndk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
@ -352,7 +352,7 @@ leveldb_download :
fi
leveldb : $(LEVELDB_LIB)
ifeq ($(HAVE_LEVELDB),1)
$(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
@REFRESH=0; \
if [ ! -e ${LEVELDB_TIMESTAMP_INT} ] ; then \
@ -384,6 +384,7 @@ $(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
else \
echo "nothing to be done for leveldb"; \
fi
endif
clean_leveldb :
$(RM) -rf deps/leveldb
@ -679,8 +680,7 @@ deps/${SQLITE3_FOLDER}/sqlite3.c :
wget ${SQLITE3_URL}; \
unzip ${SQLITE3_FOLDER}.zip; \
ln -s ${SQLITE3_FOLDER} sqlite; \
cd ${SQLITE3_FOLDER}; \
patch sqlite3.c < ${ANDR_ROOT}/patches/sqlite3-readonly-fix.patch
cd ${SQLITE3_FOLDER};
clean_sqlite3:
cd deps && $(RM) -rf ${SQLITE3_FOLDER} && $(RM) -f ${SQLITE3_FOLDER}.zip && \
@ -781,7 +781,7 @@ apk: local.properties assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(GMP_LIB)
fi; \
export VERSION_STR="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" && \
export BUILD_TYPE_C=$$(echo "$${BUILD_TYPE}" | sed 's/./\U&/') && \
gradle assemble$$BUILD_TYPE_C && \
./gradlew assemble$$BUILD_TYPE_C && \
echo "APK stored at: build/outputs/apk/Minetest-$$BUILD_TYPE.apk" && \
echo "You can install it with \`make install_$$BUILD_TYPE\`"
@ -795,11 +795,14 @@ install_release:
prep_srcdir :
@if [ ! -e ${ANDR_ROOT}/jni/src ]; then \
ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \
ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \
fi; \
if [ ! -e ${ANDR_ROOT}/jni/lib ]; then \
ln -s ${PROJ_ROOT}/lib ${ANDR_ROOT}/jni/lib; \
fi
clean_apk :
gradle clean
./gradlew clean
clean_all :
@$(MAKE) clean_apk; \

@ -10,11 +10,11 @@ buildscript {
apply plugin: "com.android.application"
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
versionCode 16
versionCode 17
versionName "${System.env.VERSION_STR}.${versionCode}"
minSdkVersion 9
targetSdkVersion 9
@ -46,4 +46,3 @@ android {
}
}
}

Binary file not shown.

@ -0,0 +1,6 @@
#Sat Aug 27 20:10:09 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

164
build/android/gradlew vendored Executable file

@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
build/android/gradlew.bat vendored Normal file

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

@ -98,8 +98,8 @@ endif
LOCAL_C_INCLUDES := \
jni/src \
jni/src/script \
jni/src/lua/src \
jni/src/jsoncpp \
jni/lib/lua/src \
jni/lib/jsoncpp \
jni/src/cguittfont \
deps/irrlicht/include \
deps/libiconv/include \
@ -117,6 +117,7 @@ LOCAL_SRC_FILES := \
jni/src/cavegen.cpp \
jni/src/chat.cpp \
jni/src/client.cpp \
jni/src/clientenvironment.cpp \
jni/src/clientiface.cpp \
jni/src/clientmap.cpp \
jni/src/clientmedia.cpp \
@ -133,6 +134,7 @@ LOCAL_SRC_FILES := \
jni/src/convert_json.cpp \
jni/src/craftdef.cpp \
jni/src/database-dummy.cpp \
jni/src/database-files.cpp \
jni/src/database-sqlite3.cpp \
jni/src/database.cpp \
jni/src/debug.cpp \
@ -141,6 +143,7 @@ LOCAL_SRC_FILES := \
jni/src/dungeongen.cpp \
jni/src/emerge.cpp \
jni/src/environment.cpp \
jni/src/face_position_cache.cpp \
jni/src/filecache.cpp \
jni/src/filesys.cpp \
jni/src/fontengine.cpp \
@ -163,6 +166,7 @@ LOCAL_SRC_FILES := \
jni/src/inventory.cpp \
jni/src/inventorymanager.cpp \
jni/src/itemdef.cpp \
jni/src/itemstackmetadata.cpp \
jni/src/keycode.cpp \
jni/src/light.cpp \
jni/src/localplayer.cpp \
@ -183,6 +187,8 @@ LOCAL_SRC_FILES := \
jni/src/mapnode.cpp \
jni/src/mapsector.cpp \
jni/src/mesh.cpp \
jni/src/mesh_generator_thread.cpp \
jni/src/metadata.cpp \
jni/src/mg_biome.cpp \
jni/src/mg_decoration.cpp \
jni/src/mg_ore.cpp \
@ -203,12 +209,14 @@ LOCAL_SRC_FILES := \
jni/src/porting.cpp \
jni/src/profiler.cpp \
jni/src/quicktune.cpp \
jni/src/raycast.cpp \
jni/src/reflowscan.cpp \
jni/src/remoteplayer.cpp \
jni/src/rollback.cpp \
jni/src/rollback_interface.cpp \
jni/src/serialization.cpp \
jni/src/server.cpp \
jni/src/serverenvironment.cpp \
jni/src/serverlist.cpp \
jni/src/serverobject.cpp \
jni/src/shader.cpp \
@ -218,6 +226,7 @@ LOCAL_SRC_FILES := \
jni/src/sound_openal.cpp \
jni/src/staticobject.cpp \
jni/src/subgame.cpp \
jni/src/tileanimation.cpp \
jni/src/tool.cpp \
jni/src/treegen.cpp \
jni/src/version.cpp \
@ -261,6 +270,7 @@ LOCAL_SRC_FILES := \
jni/src/settings.cpp \
jni/src/wieldmesh.cpp \
jni/src/client/clientlauncher.cpp \
jni/src/client/inputhandler.cpp \
jni/src/client/tile.cpp \
jni/src/client/joystick_controller.cpp \
jni/src/irrlicht_changes/static_text.cpp
@ -284,6 +294,7 @@ LOCAL_SRC_FILES += \
jni/src/script/common/c_types.cpp \
jni/src/script/cpp_api/s_async.cpp \
jni/src/script/cpp_api/s_base.cpp \
jni/src/script/cpp_api/s_client.cpp \
jni/src/script/cpp_api/s_entity.cpp \
jni/src/script/cpp_api/s_env.cpp \
jni/src/script/cpp_api/s_inventory.cpp \
@ -296,12 +307,18 @@ LOCAL_SRC_FILES += \
jni/src/script/cpp_api/s_server.cpp \
jni/src/script/lua_api/l_areastore.cpp \
jni/src/script/lua_api/l_base.cpp \
jni/src/script/lua_api/l_camera.cpp \
jni/src/script/lua_api/l_client.cpp \
jni/src/script/lua_api/l_craft.cpp \
jni/src/script/lua_api/l_env.cpp \
jni/src/script/lua_api/l_inventory.cpp \
jni/src/script/lua_api/l_item.cpp \
jni/src/script/lua_api/l_itemstackmeta.cpp\
jni/src/script/lua_api/l_localplayer.cpp \
jni/src/script/lua_api/l_mainmenu.cpp \
jni/src/script/lua_api/l_mapgen.cpp \
jni/src/script/lua_api/l_metadata.cpp \
jni/src/script/lua_api/l_minimap.cpp \
jni/src/script/lua_api/l_nodemeta.cpp \
jni/src/script/lua_api/l_nodetimer.cpp \
jni/src/script/lua_api/l_noise.cpp \
@ -310,10 +327,13 @@ LOCAL_SRC_FILES += \
jni/src/script/lua_api/l_rollback.cpp \
jni/src/script/lua_api/l_server.cpp \
jni/src/script/lua_api/l_settings.cpp \
jni/src/script/lua_api/l_sound.cpp \
jni/src/script/lua_api/l_http.cpp \
jni/src/script/lua_api/l_storage.cpp \
jni/src/script/lua_api/l_util.cpp \
jni/src/script/lua_api/l_vmanip.cpp \
jni/src/script/scripting_game.cpp \
jni/src/script/scripting_client.cpp \
jni/src/script/scripting_server.cpp \
jni/src/script/scripting_mainmenu.cpp
#freetype2 support
@ -321,36 +341,36 @@ LOCAL_SRC_FILES += jni/src/cguittfont/xCGUITTFont.cpp
# Lua
LOCAL_SRC_FILES += \
jni/src/lua/src/lapi.c \
jni/src/lua/src/lauxlib.c \
jni/src/lua/src/lbaselib.c \
jni/src/lua/src/lcode.c \
jni/src/lua/src/ldblib.c \
jni/src/lua/src/ldebug.c \
jni/src/lua/src/ldo.c \
jni/src/lua/src/ldump.c \
jni/src/lua/src/lfunc.c \
jni/src/lua/src/lgc.c \
jni/src/lua/src/linit.c \
jni/src/lua/src/liolib.c \
jni/src/lua/src/llex.c \
jni/src/lua/src/lmathlib.c \
jni/src/lua/src/lmem.c \
jni/src/lua/src/loadlib.c \
jni/src/lua/src/lobject.c \
jni/src/lua/src/lopcodes.c \
jni/src/lua/src/loslib.c \
jni/src/lua/src/lparser.c \
jni/src/lua/src/lstate.c \
jni/src/lua/src/lstring.c \
jni/src/lua/src/lstrlib.c \
jni/src/lua/src/ltable.c \
jni/src/lua/src/ltablib.c \
jni/src/lua/src/ltm.c \
jni/src/lua/src/lundump.c \
jni/src/lua/src/lvm.c \
jni/src/lua/src/lzio.c \
jni/src/lua/src/print.c
jni/lib/lua/src/lapi.c \
jni/lib/lua/src/lauxlib.c \
jni/lib/lua/src/lbaselib.c \
jni/lib/lua/src/lcode.c \
jni/lib/lua/src/ldblib.c \
jni/lib/lua/src/ldebug.c \
jni/lib/lua/src/ldo.c \
jni/lib/lua/src/ldump.c \
jni/lib/lua/src/lfunc.c \
jni/lib/lua/src/lgc.c \
jni/lib/lua/src/linit.c \
jni/lib/lua/src/liolib.c \
jni/lib/lua/src/llex.c \
jni/lib/lua/src/lmathlib.c \
jni/lib/lua/src/lmem.c \
jni/lib/lua/src/loadlib.c \
jni/lib/lua/src/lobject.c \
jni/lib/lua/src/lopcodes.c \
jni/lib/lua/src/loslib.c \
jni/lib/lua/src/lparser.c \
jni/lib/lua/src/lstate.c \
jni/lib/lua/src/lstring.c \
jni/lib/lua/src/lstrlib.c \
jni/lib/lua/src/ltable.c \
jni/lib/lua/src/ltablib.c \
jni/lib/lua/src/ltm.c \
jni/lib/lua/src/lundump.c \
jni/lib/lua/src/lvm.c \
jni/lib/lua/src/lzio.c \
jni/lib/lua/src/print.c
# SQLite3
LOCAL_SRC_FILES += deps/sqlite/sqlite3.c
@ -363,7 +383,7 @@ LOCAL_SRC_FILES += \
jni/src/threading/thread.cpp
# JSONCPP
LOCAL_SRC_FILES += jni/src/jsoncpp/json/jsoncpp.cpp
LOCAL_SRC_FILES += jni/lib/jsoncpp/jsoncpp.cpp
LOCAL_SHARED_LIBRARIES := iconv openal ogg vorbis gmp
LOCAL_STATIC_LIBRARIES := Irrlicht freetype curl ssl crypto android_native_app_glue $(PROFILER_LIBS)
@ -380,4 +400,3 @@ ifdef GPROF
$(call import-module,android-ndk-profiler)
endif
$(call import-module,android/native_app_glue)

@ -1,17 +0,0 @@
--- sqlite3.c 2016-11-29 02:29:24.000000000 +0000
+++ sqlite3.c 2016-12-08 22:54:54.206465377 +0000
@@ -30445,7 +30445,14 @@
#if OS_VXWORKS
struct vxworksFileId *pId; /* Unique file ID for vxworks. */
#else
- ino_t ino; /* Inode number */
+ #ifdef ANDROID
+ // Bionic's struct stat has a 64 bit st_ino on both 32 and
+ // 64 bit architectures. ino_t remains 32 bits wide on 32 bit
+ // architectures and can lead to inode truncation.
+ unsigned long long ino; /* Inode number */
+ #else
+ ino_t ino; /* Inode number */
+ #endif
#endif
};

@ -0,0 +1,65 @@
-- Minetest: builtin/client/chatcommands.lua
core.register_on_sending_chat_messages(function(message)
if message:sub(1,2) == ".." then
return false
end
local first_char = message:sub(1,1)
if first_char == "/" or first_char == "." then
core.display_chat_message(core.gettext("issued command: ") .. message)
end
if first_char ~= "." then
return false
end
local cmd, param = string.match(message, "^%.([^ ]+) *(.*)")
param = param or ""
if not cmd then
core.display_chat_message(core.gettext("-!- Empty command"))
return true
end
local cmd_def = core.registered_chatcommands[cmd]
if cmd_def then
core.set_last_run_mod(cmd_def.mod_origin)
local _, message = cmd_def.func(param)
if message then
core.display_chat_message(message)
end
else
core.display_chat_message(core.gettext("-!- Invalid command: ") .. cmd)
end
return true
end)
core.register_chatcommand("list_players", {
description = core.gettext("List online players"),
func = function(param)
local players = table.concat(core.get_player_names(), ", ")
core.display_chat_message(core.gettext("Online players: ") .. players)
end
})
core.register_chatcommand("disconnect", {
description = core.gettext("Exit to main menu"),
func = function(param)
core.disconnect()
end,
})
core.register_chatcommand("clear_chat_queue", {
description = core.gettext("Clear the out chat queue"),
func = function(param)
core.clear_out_chat_queue()
return true, core.gettext("The out chat queue is now empty")
end,
})
function core.run_server_chatcommand(cmd, param)
core.send_chat_message("/" .. cmd .. " " .. param)
end

23
builtin/client/init.lua Normal file

@ -0,0 +1,23 @@
-- Minetest: builtin/client/init.lua
local scriptpath = core.get_builtin_path()..DIR_DELIM
local clientpath = scriptpath.."client"..DIR_DELIM
local commonpath = scriptpath.."common"..DIR_DELIM
dofile(clientpath .. "register.lua")
dofile(commonpath .. "after.lua")
dofile(commonpath .. "chatcommands.lua")
dofile(clientpath .. "chatcommands.lua")
dofile(commonpath .. "vector.lua")
core.register_on_death(function()
core.display_chat_message("You died.")
local formspec = "size[11,5.5]bgcolor[#320000b4;true]" ..
"label[4.85,1.35;" .. fgettext("You died.") .. "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]"
core.show_formspec("bultin:death", formspec)
end)
core.register_on_formspec_input(function(formname, fields)
if formname == "bultin:death" then
core.send_respawn()
end
end)

@ -0,0 +1,73 @@
core.callback_origins = {}
local getinfo = debug.getinfo
debug.getinfo = nil
function core.run_callbacks(callbacks, mode, ...)
assert(type(callbacks) == "table")
local cb_len = #callbacks
if cb_len == 0 then
if mode == 2 or mode == 3 then
return true
elseif mode == 4 or mode == 5 then
return false
end
end
local ret
for i = 1, cb_len do
local cb_ret = callbacks[i](...)
if mode == 0 and i == 1 or mode == 1 and i == cb_len then
ret = cb_ret
elseif mode == 2 then
if not cb_ret or i == 1 then
ret = cb_ret
end
elseif mode == 3 then
if cb_ret then
return cb_ret
end
ret = cb_ret
elseif mode == 4 then
if (cb_ret and not ret) or i == 1 then
ret = cb_ret
end
elseif mode == 5 and cb_ret then
return cb_ret
end
end
return ret
end
--
-- Callback registration
--
local function make_registration()
local t = {}
local registerfunc = function(func)
t[#t + 1] = func
core.callback_origins[func] = {
mod = core.get_current_modname() or "??",
name = getinfo(1, "n").name or "??"
}
--local origin = core.callback_origins[func]
--print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
end
return t, registerfunc
end
core.registered_globalsteps, core.register_globalstep = make_registration()
core.registered_on_shutdown, core.register_on_shutdown = make_registration()
core.registered_on_connect, core.register_on_connect = make_registration()
core.registered_on_receiving_chat_messages, core.register_on_receiving_chat_messages = make_registration()
core.registered_on_sending_chat_messages, core.register_on_sending_chat_messages = make_registration()
core.registered_on_death, core.register_on_death = make_registration()
core.registered_on_hp_modification, core.register_on_hp_modification = make_registration()
core.registered_on_damage_taken, core.register_on_damage_taken = make_registration()
core.registered_on_formspec_input, core.register_on_formspec_input = make_registration()
core.registered_on_dignode, core.register_on_dignode = make_registration()
core.registered_on_punchnode, core.register_on_punchnode = make_registration()
core.registered_on_placenode, core.register_on_placenode = make_registration()
core.registered_on_item_use, core.register_on_item_use = make_registration()

33
builtin/common/after.lua Normal file

@ -0,0 +1,33 @@
local jobs = {}
local time = 0.0
core.register_globalstep(function(dtime)
time = time + dtime
if #jobs < 1 then
return
end
-- Iterate backwards so that we miss any new timers added by
-- a timer callback, and so that we don't skip the next timer
-- in the list if we remove one.
for i = #jobs, 1, -1 do
local job = jobs[i]
if time >= job.expire then
core.set_last_run_mod(job.mod_origin)
job.func(unpack(job.arg))
table.remove(jobs, i)
end
end
end)
function core.after(after, func, ...)
assert(tonumber(after) and type(func) == "function",
"Invalid core.after invocation")
jobs[#jobs + 1] = {
func = func,
expire = time + after,
arg = {...},
mod_origin = core.get_last_run_mod()
}
end

@ -0,0 +1,112 @@
-- Minetest: builtin/common/chatcommands.lua
core.registered_chatcommands = {}
function core.register_chatcommand(cmd, def)
def = def or {}
def.params = def.params or ""
def.description = def.description or ""
def.privs = def.privs or {}
def.mod_origin = core.get_current_modname() or "??"
core.registered_chatcommands[cmd] = def
end
function core.unregister_chatcommand(name)
if core.registered_chatcommands[name] then
core.registered_chatcommands[name] = nil
else
core.log("warning", "Not unregistering chatcommand " ..name..
" because it doesn't exist.")
end
end
function core.override_chatcommand(name, redefinition)
local chatcommand = core.registered_chatcommands[name]
assert(chatcommand, "Attempt to override non-existent chatcommand "..name)
for k, v in pairs(redefinition) do
rawset(chatcommand, k, v)
end
core.registered_chatcommands[name] = chatcommand
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 msg = core.colorize("#00ffff", cmd_marker .. cmd)
if def.params and def.params ~= "" then
msg = msg .. " " .. def.params
end
if def.description and def.description ~= "" then
msg = msg .. ": " .. def.description
end
return msg
end
if param == "" then
local cmds = {}
for cmd, def in pairs(core.registered_chatcommands) do
if INIT == "client" or core.check_player_privs(name, def.privs) then
cmds[#cmds + 1] = cmd
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)
elseif param == "all" then
local cmds = {}
for cmd, def in pairs(core.registered_chatcommands) do
if INIT == "client" or core.check_player_privs(name, def.privs) then
cmds[#cmds + 1] = format_help_line(cmd, def)
end
end
table.sort(cmds)
return true, gettext("Available commands:").."\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")
else
local cmd = param
local def = core.registered_chatcommands[cmd]
if not def then
return false, gettext("Command not available: ")..cmd
else
return true, format_help_line(cmd, def)
end
end
end
if INIT == "client" then
core.register_chatcommand("help", {
params = gettext("[all/<cmd>]"),
description = 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",
func = do_help_cmd,
})
end

@ -289,6 +289,9 @@ function sort_mod_list(self)
table.sort(self.m_processed_list, function(a, b)
-- Show game mods at bottom
if a.typ ~= b.typ then
if b.typ == "game" then
return a.typ ~= "game_mod"
end
return b.typ == "game_mod"
end
-- If in same or no modpack, sort by name

@ -197,16 +197,17 @@ assert(table.indexof({"foo", "bar"}, "foo") == 1)
assert(table.indexof({"foo", "bar"}, "baz") == -1)
--------------------------------------------------------------------------------
function file_exists(filename)
local f = io.open(filename, "r")
if f == nil then
return false
else
f:close()
return true
if INIT ~= "client" then
function file_exists(filename)
local f = io.open(filename, "r")
if f == nil then
return false
else
f:close()
return true
end
end
end
--------------------------------------------------------------------------------
function string:trim()
return (self:gsub("^%s*(.-)%s*$", "%1"))
@ -307,7 +308,7 @@ function core.formspec_escape(text)
end
function core.splittext(text,charlimit)
function core.wrap_text(text, charlimit)
local retval = {}
local current_idx = 1
@ -462,7 +463,7 @@ if INIT == "game" then
core.rotate_node = function(itemstack, placer, pointed_thing)
core.rotate_and_place(itemstack, placer, pointed_thing,
core.setting_getbool("creative_mode"),
core.settings:get_bool("creative_mode"),
{invert_wall = placer:get_player_control().sneak})
return itemstack
end
@ -606,7 +607,9 @@ if INIT == "mainmenu" then
return nil
end
end
if INIT == "client" or INIT == "mainmenu" then
function fgettext_ne(text, ...)
text = core.gettext(text)
local arg = {n=select('#', ...), ...}
@ -637,3 +640,86 @@ if INIT == "mainmenu" then
end
end
local ESCAPE_CHAR = string.char(0x1b)
-- Client-side mods don't have access to settings
if core.settings and core.settings:get_bool("disable_escape_sequences") then
function core.get_color_escape_sequence(color)
return ""
end
function core.get_background_escape_sequence(color)
return ""
end
function core.colorize(color, message)
return message
end
else
function core.get_color_escape_sequence(color)
return ESCAPE_CHAR .. "(c@" .. color .. ")"
end
function core.get_background_escape_sequence(color)
return ESCAPE_CHAR .. "(b@" .. color .. ")"
end
function core.colorize(color, message)
local lines = tostring(message):split("\n", true)
local color_code = core.get_color_escape_sequence(color)
for i, line in ipairs(lines) do
lines[i] = color_code .. line
end
return table.concat(lines, "\n") .. core.get_color_escape_sequence("#ffffff")
end
end
function core.strip_foreground_colors(str)
return (str:gsub(ESCAPE_CHAR .. "%(c@[^)]+%)", ""))
end
function core.strip_background_colors(str)
return (str:gsub(ESCAPE_CHAR .. "%(b@[^)]+%)", ""))
end
function core.strip_colors(str)
return (str:gsub(ESCAPE_CHAR .. "%([bc]@[^)]+%)", ""))
end
--------------------------------------------------------------------------------
-- Returns the exact coordinate of a pointed surface
--------------------------------------------------------------------------------
function core.pointed_thing_to_face_pos(placer, pointed_thing)
local eye_offset_first = placer:get_eye_offset()
local node_pos = pointed_thing.under
local camera_pos = placer:get_pos()
local pos_off = vector.multiply(
vector.subtract(pointed_thing.above, node_pos), 0.5)
local look_dir = placer:get_look_dir()
local offset, nc
local oc = {}
for c, v in pairs(pos_off) do
if nc or v == 0 then
oc[#oc + 1] = c
else
offset = v
nc = c
end
end
local fine_pos = {[nc] = node_pos[nc] + offset}
camera_pos.y = camera_pos.y + 1.625 + eye_offset_first.y / 10
local f = (node_pos[nc] + offset - camera_pos[nc]) / look_dir[nc]
for i = 1, #oc do
fine_pos[oc[i]] = camera_pos[oc[i]] + look_dir[oc[i]] * f
end
return fine_pos
end

@ -186,6 +186,10 @@ local safe_env = {
}
function core.deserialize(str, safe)
if type(str) ~= "string" then
return nil, "Cannot deserialize type '"..type(str)
.."'. Argument must be a string."
end
if str:byte(1) == 0x1B then
return nil, "Bytecode prohibited"
end

@ -3,6 +3,7 @@
-- This ignores mod namespaces (variables with the same name as the current mod).
local WARN_INIT = false
local getinfo = debug.getinfo
function core.global_exists(name)
if type(name) ~= "string" then
@ -18,7 +19,7 @@ local declared = {}
local warned = {}
function meta:__newindex(name, value)
local info = debug.getinfo(2, "Sl")
local info = getinfo(2, "Sl")
local desc = ("%s:%d"):format(info.short_src, info.currentline)
if not declared[name] then
local warn_key = ("%s\0%d\0%s"):format(info.source,
@ -42,7 +43,7 @@ end
function meta:__index(name)
local info = debug.getinfo(2, "Sl")
local info = getinfo(2, "Sl")
local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
if not declared[name] and not warned[warn_key] and info.what ~= "C" then
core.log("warning", ("Undeclared global variable %q accessed at %s:%s")

@ -138,3 +138,8 @@ function vector.divide(a, b)
z = a.z / b}
end
end
function vector.sort(a, b)
return {x = math.min(a.x, b.x), y = math.min(a.y, b.y), z = math.min(a.z, b.z)},
{x = math.max(a.x, b.x), y = math.max(a.y, b.y), z = math.max(a.z, b.z)}
end

@ -167,7 +167,7 @@ local function switch_to_tab(self, index)
self.current_tab = self.tablist[index].name
if (self.autosave_tab) then
core.setting_set(self.name .. "_LAST",self.current_tab)
core.settings:set(self.name .. "_LAST",self.current_tab)
end
-- call for tab to enter

@ -106,7 +106,7 @@ core.builtin_auth_handler = {
end
end
-- For the admin, give everything
elseif name == core.setting_get("name") then
elseif name == core.settings:get("name") then
for priv, def in pairs(core.registered_privileges) do
privileges[priv] = true
end
@ -125,7 +125,7 @@ core.builtin_auth_handler = {
core.log('info', "Built-in authentication handler adding player '"..name.."'")
core.auth_table[name] = {
password = password,
privileges = core.string_to_privs(core.setting_get("default_privs")),
privileges = core.string_to_privs(core.settings:get("default_privs")),
last_login = os.time(),
}
save_auth_file()
@ -148,7 +148,7 @@ core.builtin_auth_handler = {
if not core.auth_table[name] then
core.builtin_auth_handler.create_auth(name,
core.get_password_hash(name,
core.setting_get("default_password")))
core.settings:get("default_password")))
end
core.auth_table[name].privileges = privileges
core.notify_authentication_modified(name)

@ -1,27 +1,28 @@
-- Minetest: builtin/chatcommands.lua
-- Minetest: builtin/game/chatcommands.lua
--
-- Chat command handler
--
core.chatcommands = {}
function core.register_chatcommand(cmd, def)
def = def or {}
def.params = def.params or ""
def.description = def.description or ""
def.privs = def.privs or {}
def.mod_origin = core.get_current_modname() or "??"
core.chatcommands[cmd] = def
end
core.chatcommands = core.registered_chatcommands -- BACKWARDS COMPATIBILITY
core.register_on_chat_message(function(name, message)
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
if not param then
param = ""
if message:sub(1,1) ~= "/" then
return
end
local cmd_def = core.chatcommands[cmd]
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
if not cmd then
core.chat_send_player(name, "-!- Empty command")
return true
end
param = param or ""
local cmd_def = core.registered_chatcommands[cmd]
if not cmd_def then
return false
core.chat_send_player(name, "-!- Invalid command: " .. cmd)
return true
end
local has_privs, missing_privs = core.check_player_privs(name, cmd_def.privs)
if has_privs then
@ -38,7 +39,7 @@ core.register_on_chat_message(function(name, message)
return true -- Handled chat message
end)
if core.setting_getbool("profiler.load") then
if core.settings:get_bool("profiler.load") then
-- Run after register_chatcommand and its register_on_chat_message
-- Before any chattcommands that should be profiled
profiler.init_chatcommand()
@ -70,7 +71,8 @@ end
--
core.register_chatcommand("me", {
params = "<action>",
description = "chat action (eg. /me orders a pizza)",
description = "Display chat action (e.g., '/me orders a pizza' displays"
.. " '<player name> orders a pizza')",
privs = {shout=true},
func = function(name, param)
core.chat_send_all("* " .. name .. " " .. param)
@ -80,7 +82,7 @@ core.register_chatcommand("me", {
core.register_chatcommand("admin", {
description = "Show the name of the server owner",
func = function(name)
local admin = minetest.setting_get("name")
local admin = minetest.settings:get("name")
if admin then
return true, "The administrator of this server is "..admin.."."
else
@ -89,64 +91,9 @@ core.register_chatcommand("admin", {
end,
})
core.register_chatcommand("help", {
privs = {},
params = "[all/privs/<cmd>]",
description = "Get help for commands or list privileges",
func = function(name, param)
local function format_help_line(cmd, def)
local msg = core.colorize("#00ffff", "/"..cmd)
if def.params and def.params ~= "" then
msg = msg .. " " .. def.params
end
if def.description and def.description ~= "" then
msg = msg .. ": " .. def.description
end
return msg
end
if param == "" then
local msg = ""
local cmds = {}
for cmd, def in pairs(core.chatcommands) do
if core.check_player_privs(name, def.privs) then
cmds[#cmds + 1] = cmd
end
end
table.sort(cmds)
return true, "Available commands: " .. table.concat(cmds, " ") .. "\n"
.. "Use '/help <cmd>' to get more information,"
.. " or '/help all' to list everything."
elseif param == "all" then
local cmds = {}
for cmd, def in pairs(core.chatcommands) do
if core.check_player_privs(name, def.privs) then
cmds[#cmds + 1] = format_help_line(cmd, def)
end
end
table.sort(cmds)
return true, "Available commands:\n"..table.concat(cmds, "\n")
elseif 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")
else
local cmd = param
local def = core.chatcommands[cmd]
if not def then
return false, "Command not available: "..cmd
else
return true, format_help_line(cmd, def)
end
end
end,
})
core.register_chatcommand("privs", {
params = "<name>",
description = "print out privileges of player",
description = "Print privileges of player",
func = function(caller, param)
param = param:trim()
local name = (param ~= "" and param or caller)
@ -161,8 +108,8 @@ local function handle_grant_command(caller, grantname, grantprivstr)
if not (caller_privs.privs or caller_privs.basic_privs) then
return false, "Your privileges are insufficient."
end
if not core.auth_table[grantname] then
if not core.get_auth_handler().get_auth(grantname) then
return false, "Player " .. grantname .. " does not exist."
end
local grantprivs = core.string_to_privs(grantprivstr)
@ -172,7 +119,7 @@ local function handle_grant_command(caller, grantname, grantprivstr)
local privs = core.get_player_privs(grantname)
local privs_unknown = ""
local basic_privs =
core.string_to_privs(core.setting_get("basic_privs") or "interact,shout")
core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
for priv, _ in pairs(grantprivs) do
if not basic_privs[priv] and not caller_privs.privs then
return false, "Your privileges are insufficient."
@ -204,7 +151,7 @@ core.register_chatcommand("grant", {
local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
if not grantname or not grantprivstr then
return false, "Invalid parameters (see /help grant)"
end
end
return handle_grant_command(name, grantname, grantprivstr)
end,
})
@ -215,7 +162,7 @@ core.register_chatcommand("grantme", {
func = function(name, param)
if param == "" then
return false, "Invalid parameters (see /help grantme)"
end
end
return handle_grant_command(name, name, param)
end,
})
@ -232,13 +179,13 @@ core.register_chatcommand("revoke", {
local revoke_name, revoke_priv_str = string.match(param, "([^ ]+) (.+)")
if not revoke_name or not revoke_priv_str then
return false, "Invalid parameters (see /help revoke)"
elseif not core.auth_table[revoke_name] then
elseif not core.get_auth_handler().get_auth(revoke_name) then
return false, "Player " .. revoke_name .. " does not exist."
end
local revoke_privs = core.string_to_privs(revoke_priv_str)
local privs = core.get_player_privs(revoke_name)
local basic_privs =
core.string_to_privs(core.setting_get("basic_privs") or "interact,shout")
core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
for priv, _ in pairs(revoke_privs) do
if not basic_privs[priv] and
not core.check_player_privs(name, {privs=true}) then
@ -269,7 +216,7 @@ core.register_chatcommand("revoke", {
core.register_chatcommand("setpassword", {
params = "<name> <password>",
description = "set given password",
description = "Set player's password",
privs = {password=true},
func = function(name, param)
local toname, raw_password = string.match(param, "^([^ ]+) +(.+)$")
@ -307,7 +254,7 @@ core.register_chatcommand("setpassword", {
core.register_chatcommand("clearpassword", {
params = "<name>",
description = "set empty password",
description = "Set empty password",
privs = {password=true},
func = function(name, param)
local toname = param
@ -324,7 +271,7 @@ core.register_chatcommand("clearpassword", {
core.register_chatcommand("auth_reload", {
params = "",
description = "reload authentication data",
description = "Reload authentication data",
privs = {server=true},
func = function(name, param)
local done = core.auth_reload()
@ -332,9 +279,34 @@ core.register_chatcommand("auth_reload", {
end,
})
core.register_chatcommand("remove_player", {
params = "<name>",
description = "Remove player data",
privs = {server=true},
func = function(name, param)
local toname = param
if toname == "" then
return false, "Name field required"
end
local rc = core.remove_player(toname)
if rc == 0 then
core.log("action", name .. " removed player data of " .. toname .. ".")
return true, "Player \"" .. toname .. "\" removed."
elseif rc == 1 then
return true, "No such player \"" .. toname .. "\" to remove."
elseif rc == 2 then
return true, "Player \"" .. toname .. "\" is connected, cannot remove."
end
return false, "Unhandled remove_player return code " .. rc .. ""
end,
})
core.register_chatcommand("teleport", {
params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
description = "teleport to given position",
description = "Teleport to player or position",
privs = {teleport=true},
func = function(name, param)
-- Returns (pos, true) if found, otherwise (pos, false)
@ -365,7 +337,7 @@ core.register_chatcommand("teleport", {
p.y = tonumber(p.y)
p.z = tonumber(p.z)
if p.x and p.y and p.z then
local lm = tonumber(minetest.setting_get("map_generation_limit") or 31000)
local lm = 31000
if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then
return false, "Cannot teleport out of map bounds!"
end
@ -442,25 +414,25 @@ core.register_chatcommand("teleport", {
core.register_chatcommand("set", {
params = "[-n] <name> <value> | <name>",
description = "set or read server configuration setting",
description = "Set or read server configuration setting",
privs = {server=true},
func = function(name, param)
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
if arg and arg == "-n" and setname and setvalue then
core.setting_set(setname, setvalue)
core.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
if setname and setvalue then
if not core.setting_get(setname) then
if not core.settings:get(setname) then
return false, "Failed. Use '/set -n <name> <value>' to create a new setting."
end
core.setting_set(setname, setvalue)
core.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
local setname = string.match(param, "([^ ]+)")
if setname then
local setvalue = core.setting_get(setname)
local setvalue = core.settings:get(setname)
if not setvalue then
setvalue = "<not set>"
end
@ -497,7 +469,7 @@ end
core.register_chatcommand("emergeblocks", {
params = "(here [radius]) | (<pos1> <pos2>)",
description = "starts loading (or generating, if inexistent) map blocks "
description = "Load (or, if nonexistent, generate) map blocks "
.. "contained in area pos1 to pos2",
privs = {server=true},
func = function(name, param)
@ -523,7 +495,7 @@ core.register_chatcommand("emergeblocks", {
core.register_chatcommand("deleteblocks", {
params = "(here [radius]) | (<pos1> <pos2>)",
description = "delete map blocks contained in area pos1 to pos2",
description = "Delete map blocks contained in area pos1 to pos2",
privs = {server=true},
func = function(name, param)
local p1, p2 = parse_range_str(name, param)
@ -540,6 +512,25 @@ core.register_chatcommand("deleteblocks", {
end,
})
core.register_chatcommand("fixlight", {
params = "(here [radius]) | (<pos1> <pos2>)",
description = "Resets lighting in the area between pos1 and pos2",
privs = {server = true},
func = function(name, param)
local p1, p2 = parse_range_str(name, param)
if p1 == false then
return false, p2
end
if core.fix_light(p1, p2) then
return true, "Successfully reset light in the area ranging from " ..
core.pos_to_string(p1, 1) .. " to " .. core.pos_to_string(p2, 1)
else
return false, "Failed to load one or more blocks in area"
end
end,
})
core.register_chatcommand("mods", {
params = "",
description = "List mods installed on the server",
@ -587,7 +578,7 @@ end
core.register_chatcommand("give", {
params = "<name> <ItemString>",
description = "give item to player",
description = "Give item to player",
privs = {give=true},
func = function(name, param)
local toname, itemstring = string.match(param, "^([^ ]+) +(.+)$")
@ -600,7 +591,7 @@ core.register_chatcommand("give", {
core.register_chatcommand("giveme", {
params = "<ItemString>",
description = "give item to yourself",
description = "Give item to yourself",
privs = {give=true},
func = function(name, param)
local itemstring = string.match(param, "(.+)$")
@ -671,12 +662,12 @@ end)
core.register_chatcommand("rollback_check", {
params = "[<range>] [<seconds>] [limit]",
description = "Check who has last touched a node or near it,"
.. " max. <seconds> ago (default range=0,"
.. " seconds=86400=24h, limit=5)",
description = "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",
privs = {rollback=true},
func = function(name, param)
if not core.setting_getbool("enable_rollback_recording") then
if not core.settings:get_bool("enable_rollback_recording") then
return false, "Rollback functions are disabled."
end
local range, seconds, limit =
@ -724,10 +715,10 @@ core.register_chatcommand("rollback_check", {
core.register_chatcommand("rollback", {
params = "<player name> [<seconds>] | :<actor> [<seconds>]",
description = "revert actions of a player; default for <seconds> is 60",
description = "Revert actions of a player. Default for <seconds> is 60",
privs = {rollback=true},
func = function(name, param)
if not core.setting_getbool("enable_rollback_recording") then
if not core.settings:get_bool("enable_rollback_recording") then
return false, "Rollback functions are disabled."
end
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
@ -769,7 +760,7 @@ core.register_chatcommand("status", {
core.register_chatcommand("time", {
params = "<0..23>:<0..59> | <0..24000>",
description = "set time of day",
description = "Set time of day",
privs = {},
func = function(name, param)
if param == "" then
@ -815,12 +806,21 @@ core.register_chatcommand("days", {
})
core.register_chatcommand("shutdown", {
description = "shutdown server",
description = "Shutdown server",
params = "[delay_in_seconds (non-negative number, or -1 to cancel)] [reconnect] [message]",
privs = {server=true},
func = function(name, param)
core.log("action", name .. " shuts down server")
core.request_shutdown()
core.chat_send_all("*** Server shutting down (operator request).")
local delay, reconnect, message = param:match("([^ ][-]?[0-9]+)([^ ]+)(.*)")
message = message or ""
if delay ~= "" then
delay = tonumber(param) or 0
else
delay = 0
core.log("action", name .. " shuts down server")
core.chat_send_all("*** Server shutting down (operator request).")
end
core.request_shutdown(message:trim(), core.is_yes(reconnect), delay)
end,
})
@ -846,7 +846,7 @@ core.register_chatcommand("ban", {
core.register_chatcommand("unban", {
params = "<name/ip>",
description = "remove IP ban",
description = "Remove IP ban",
privs = {ban=true},
func = function(name, param)
if not core.unban_player_or_ip(param) then
@ -859,7 +859,7 @@ core.register_chatcommand("unban", {
core.register_chatcommand("kick", {
params = "<name> [reason]",
description = "kick a player",
description = "Kick a player",
privs = {kick=true},
func = function(name, param)
local tokick, reason = param:match("([^ ]+) (.+)")
@ -878,7 +878,7 @@ core.register_chatcommand("kick", {
core.register_chatcommand("clearobjects", {
params = "[full|quick]",
description = "clear all objects in world",
description = "Clear all objects in world",
privs = {server=true},
func = function(name, param)
local options = {}
@ -938,3 +938,31 @@ core.register_chatcommand("last-login", {
return false, "Last login time is unknown"
end,
})
core.register_chatcommand("clearinv", {
params = "[name]",
description = "Clear the inventory of yourself or another player",
func = function(name, param)
local player
if param and param ~= "" and param ~= name then
if not core.check_player_privs(name, {server=true}) then
return false, "You don't have permission"
.. " to run this command (missing privilege: server)"
end
player = core.get_player_by_name(param)
core.chat_send_player(param, name.." cleared your inventory.")
else
player = core.get_player_by_name(name)
end
if player then
player:get_inventory():set_list("main", {})
player:get_inventory():set_list("craft", {})
player:get_inventory():set_list("craftpreview", {})
core.log("action", name.." clears "..player:get_player_name().."'s inventory")
return true, "Cleared "..player:get_player_name().."'s inventory."
else
return false, "Player must be online to clear inventory!"
end
end,
})

@ -49,3 +49,24 @@ setmetatable(core.env, {
function core.rollback_get_last_node_actor(pos, range, seconds)
return core.rollback_get_node_actions(pos, range, seconds, 1)[1]
end
--
-- core.setting_*
--
local settings = core.settings
local function setting_proxy(name)
return function(...)
core.log("deprecated", "WARNING: minetest.setting_* "..
"functions are deprecated. "..
"Use methods on the minetest.settings object.")
return settings[name](settings, ...)
end
end
core.setting_set = setting_proxy("set")
core.setting_get = setting_proxy("get")
core.setting_setbool = setting_proxy("set_bool")
core.setting_getbool = setting_proxy("get_bool")
core.setting_save = setting_proxy("write")

@ -18,9 +18,11 @@ core.register_entity(":__builtin:falling_node", {
},
node = {},
meta = {},
set_node = function(self, node)
set_node = function(self, node, meta)
self.node = node
self.meta = meta or {}
self.object:set_properties({
is_visible = true,
textures = {node.name},
@ -28,15 +30,21 @@ core.register_entity(":__builtin:falling_node", {
end,
get_staticdata = function(self)
return core.serialize(self.node)
local ds = {
node = self.node,
meta = self.meta,
}
return core.serialize(ds)
end,
on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1})
local node = core.deserialize(staticdata)
if node then
self:set_node(node)
local ds = core.deserialize(staticdata)
if ds and ds.node then
self:set_node(ds.node, ds.meta)
elseif ds then
self:set_node(ds)
elseif staticdata ~= "" then
self:set_node({name = staticdata})
end
@ -83,7 +91,7 @@ core.register_entity(":__builtin:falling_node", {
-- it's drops
if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
core.remove_node(np)
if nd.buildable_to == false then
if nd and nd.buildable_to == false then
-- Add dropped items
local drops = core.get_node_drops(n2.name, "")
for _, dropped_item in pairs(drops) do
@ -98,6 +106,10 @@ core.register_entity(":__builtin:falling_node", {
-- Create node and remove entity
if core.registered_nodes[self.node.name] then
core.add_node(np, self.node)
if self.meta then
local meta = core.get_meta(np)
meta:from_table(self.meta)
end
end
self.object:remove()
core.check_for_falling(np)
@ -111,13 +123,27 @@ core.register_entity(":__builtin:falling_node", {
end
})
local function spawn_falling_node(p, node)
local function spawn_falling_node(p, node, meta)
local obj = core.add_entity(p, "__builtin:falling_node")
if obj then
obj:get_luaentity():set_node(node)
obj:get_luaentity():set_node(node, meta)
end
end
function core.spawn_falling_node(pos)
local node = core.get_node(pos)
if node.name == "air" or node.name == "ignore" then
return false
end
local obj = core.add_entity(pos, "__builtin:falling_node")
if obj then
obj:get_luaentity():set_node(node)
core.remove_node(pos)
return true
end
return false
end
local function drop_attached_node(p)
local nn = core.get_node(p).name
core.remove_node(p)
@ -134,7 +160,8 @@ end
function builtin_shared.check_attached_node(p, n)
local def = core.registered_nodes[n.name]
local d = {x = 0, y = 0, z = 0}
if def.paramtype2 == "wallmounted" then
if def.paramtype2 == "wallmounted" or
def.paramtype2 == "colorwallmounted" then
-- The fallback vector here is in case 'wallmounted to dir' is nil due
-- to voxelmanip placing a wallmounted node without resetting a
-- pre-existing param2 value that is out-of-range for wallmounted.
@ -174,8 +201,13 @@ function core.check_single_for_falling(p)
(not d_bottom.walkable or d_bottom.buildable_to) then
n.level = core.get_node_level(p)
local meta = core.get_meta(p)
local metatable = {}
if meta ~= nil then
metatable = meta:to_table()
end
core.remove_node(p)
spawn_falling_node(p, n)
spawn_falling_node(p, n, metatable)
return true
end
end

@ -9,6 +9,8 @@ core.features = {
no_legacy_abms = true,
texture_names_parens = true,
area_store_custom_ids = true,
add_entity_with_staticdata = true,
no_chat_message_prediction = true,
}
function core.has_feature(arg)

@ -40,7 +40,7 @@ function core.forceload_block(pos, transient)
elseif other_table[hash] ~= nil then
relevant_table[hash] = 1
else
if total_forceloaded >= (tonumber(core.setting_get("max_forceloaded_blocks")) or 16) then
if total_forceloaded >= (tonumber(core.settings:get("max_forceloaded_blocks")) or 16) then
return false
end
total_forceloaded = total_forceloaded+1

@ -13,15 +13,17 @@ dofile(gamepath.."constants.lua")
assert(loadfile(gamepath.."item.lua"))(builtin_shared)
dofile(gamepath.."register.lua")
if core.setting_getbool("profiler.load") then
if core.settings:get_bool("profiler.load") then
profiler = dofile(scriptpath.."profiler"..DIR_DELIM.."init.lua")
end
dofile(commonpath .. "after.lua")
dofile(gamepath.."item_entity.lua")
dofile(gamepath.."deprecated.lua")
dofile(gamepath.."misc.lua")
dofile(gamepath.."privileges.lua")
dofile(gamepath.."auth.lua")
dofile(commonpath .. "chatcommands.lua")
dofile(gamepath.."chatcommands.lua")
dofile(gamepath.."static_spawn.lua")
dofile(gamepath.."detached_inventory.lua")

@ -109,7 +109,7 @@ local facedir_to_dir_map = {
1, 4, 3, 2,
}
function core.facedir_to_dir(facedir)
return facedir_to_dir[facedir_to_dir_map[facedir]]
return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
end
function core.dir_to_wallmounted(dir)
@ -144,11 +144,20 @@ local wallmounted_to_dir = {
{x = 0, y = 0, z = -1},
}
function core.wallmounted_to_dir(wallmounted)
return wallmounted_to_dir[wallmounted]
return wallmounted_to_dir[wallmounted % 8]
end
function core.dir_to_yaw(dir)
return -math.atan2(dir.x, dir.z)
end
function core.yaw_to_dir(yaw)
return {x = -math.sin(yaw), y = 0, z = math.cos(yaw)}
end
function core.get_node_drops(nodename, toolname)
local drop = ItemStack({name=nodename}):get_definition().drop
local def = core.registered_nodes[nodename]
local drop = def and def.drop
if drop == nil then
-- default drop
return {nodename}
@ -197,7 +206,6 @@ function core.get_node_drops(nodename, toolname)
end
function core.item_place_node(itemstack, placer, pointed_thing, param2)
local item = itemstack:peek_item()
local def = itemstack:get_definition()
if def.type ~= "node" or pointed_thing.type ~= "node" then
return itemstack, false
@ -207,20 +215,21 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
local oldnode_under = core.get_node_or_nil(under)
local above = pointed_thing.above
local oldnode_above = core.get_node_or_nil(above)
local playername = placer:get_player_name()
if not oldnode_under or not oldnode_above then
core.log("info", placer:get_player_name() .. " tried to place"
core.log("info", playername .. " tried to place"
.. " node in unloaded position " .. core.pos_to_string(above))
return itemstack, false
end
local olddef_under = ItemStack({name=oldnode_under.name}):get_definition()
local olddef_under = core.registered_nodes[oldnode_under.name]
olddef_under = olddef_under or core.nodedef_default
local olddef_above = ItemStack({name=oldnode_above.name}):get_definition()
local olddef_above = core.registered_nodes[oldnode_above.name]
olddef_above = olddef_above or core.nodedef_default
if not olddef_above.buildable_to and not olddef_under.buildable_to then
core.log("info", placer:get_player_name() .. " tried to place"
core.log("info", playername .. " tried to place"
.. " node in invalid position " .. core.pos_to_string(above)
.. ", replacing " .. oldnode_above.name)
return itemstack, false
@ -235,17 +244,17 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
place_to = {x = under.x, y = under.y, z = under.z}
end
if core.is_protected(place_to, placer:get_player_name()) and
if core.is_protected(place_to, playername) and
not minetest.check_player_privs(placer, "protection_bypass") then
core.log("action", placer:get_player_name()
core.log("action", playername
.. " tried to place " .. def.name
.. " at protected position "
.. core.pos_to_string(place_to))
core.record_protection_violation(place_to, placer:get_player_name())
core.record_protection_violation(place_to, playername)
return itemstack
end
core.log("action", placer:get_player_name() .. " places node "
core.log("action", playername .. " places node "
.. def.name .. " at " .. core.pos_to_string(place_to))
local oldnode = core.get_node(place_to)
@ -254,7 +263,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
-- Calculate direction for wall mounted stuff like torches and signs
if def.place_param2 ~= nil then
newnode.param2 = def.place_param2
elseif def.paramtype2 == 'wallmounted' and not param2 then
elseif (def.paramtype2 == "wallmounted" or
def.paramtype2 == "colorwallmounted") and not param2 then
local dir = {
x = under.x - above.x,
y = under.y - above.y,
@ -262,7 +272,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
}
newnode.param2 = core.dir_to_wallmounted(dir)
-- Calculate the direction for furnaces and chests and stuff
elseif def.paramtype2 == 'facedir' and not param2 then
elseif (def.paramtype2 == "facedir" or
def.paramtype2 == "colorfacedir") and not param2 then
local placer_pos = placer:getpos()
if placer_pos then
local dir = {
@ -300,7 +311,6 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
end
-- Run script hook
local _, callback
for _, callback in ipairs(core.registered_on_placenodes) do
-- Deepcopy pos, node and pointed_thing because callback can modify them
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
@ -441,8 +451,9 @@ function core.handle_node_drops(pos, drops, digger)
end
function core.node_dig(pos, node, digger)
local def = ItemStack({name=node.name}):get_definition()
if not def.diggable or (def.can_dig and not def.can_dig(pos,digger)) then
local def = core.registered_nodes[node.name]
if def and (not def.diggable or
(def.can_dig and not def.can_dig(pos, digger))) then
core.log("info", digger:get_player_name() .. " tried to dig "
.. node.name .. " which is not diggable "
.. core.pos_to_string(pos))
@ -467,12 +478,12 @@ function core.node_dig(pos, node, digger)
local wdef = wielded:get_definition()
local tp = wielded:get_tool_capabilities()
local dp = core.get_dig_params(def.groups, tp)
local dp = core.get_dig_params(def and def.groups, tp)
if wdef and wdef.after_use then
wielded = wdef.after_use(wielded, digger, node, dp) or wielded
else
-- Wear out tool
if not core.setting_getbool("creative_mode") then
if not core.settings:get_bool("creative_mode") then
wielded:add_wear(dp.wear)
if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then
core.sound_play(wdef.sound.breaks, {pos = pos, gain = 0.5})
@ -485,7 +496,7 @@ function core.node_dig(pos, node, digger)
core.handle_node_drops(pos, drops, digger)
local oldmetadata = nil
if def.after_dig_node then
if def and def.after_dig_node then
oldmetadata = core.get_meta(pos):to_table()
end
@ -493,7 +504,7 @@ function core.node_dig(pos, node, digger)
core.remove_node(pos)
-- Run callback
if def.after_dig_node then
if def and def.after_dig_node then
-- Copy pos and node because callback can modify them
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}

@ -14,7 +14,7 @@ end
-- If item_entity_ttl is not set, enity will have default life time
-- Setting it to -1 disables the feature
local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
local time_to_live = tonumber(core.settings:get("item_entity_ttl"))
if not time_to_live then
time_to_live = 900
end
@ -53,6 +53,8 @@ core.register_entity(":__builtin:item", {
if itemtable then
itemname = stack:to_table().name
end
-- Backwards compatibility: old clients use the texture
-- to get the type of the item
local item_texture = nil
local item_type = ""
if core.registered_items[itemname] then
@ -66,6 +68,7 @@ core.register_entity(":__builtin:item", {
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c},
automatic_rotate = math.pi * 0.5,
wield_item = itemstring,
}
self.object:set_properties(prop)
end,
@ -101,31 +104,39 @@ core.register_entity(":__builtin:item", {
self:set_item(self.itemstring)
end,
-- moves items from this stack to an other stack
try_merge_with = function(self, own_stack, object, obj)
-- other item's stack
local stack = ItemStack(obj.itemstring)
if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then
-- only merge if items are the same
if own_stack:get_name() == stack:get_name() and
own_stack:get_meta() == stack:get_meta() and
own_stack:get_wear() == stack:get_wear() and
stack:get_free_space() > 0 then
local overflow = false
local count = stack:get_count() + own_stack:get_count()
local max_count = stack:get_stack_max()
if count > max_count then
overflow = true
stack:set_count(max_count)
count = count - max_count
own_stack:set_count(count)
else
self.itemstring = ''
stack:set_count(count)
end
local pos = object:getpos()
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
object:moveto(pos, false)
local s, c
local max_count = stack:get_stack_max()
local name = stack:get_name()
if not overflow then
obj.itemstring = name .. " " .. count
obj.itemstring = stack:to_string()
s = 0.2 + 0.1 * (count / max_count)
c = s
object:set_properties({
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c}
collisionbox = {-c, -c, -c, c, c, c},
wield_item = obj.itemstring
})
self.object:remove()
-- merging succeeded
@ -133,18 +144,20 @@ core.register_entity(":__builtin:item", {
else
s = 0.4
c = 0.3
obj.itemstring = stack:to_string()
object:set_properties({
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c}
collisionbox = {-c, -c, -c, c, c, c},
wield_item = obj.itemstring
})
obj.itemstring = name .. " " .. max_count
s = 0.2 + 0.1 * (count / max_count)
c = s
self.itemstring = own_stack:to_string()
self.object:set_properties({
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c}
collisionbox = {-c, -c, -c, c, c, c},
wield_item = self.itemstring
})
self.itemstring = name .. " " .. count
end
end
-- merging didn't succeed

@ -4,50 +4,6 @@
-- Misc. API functions
--
local jobs = {}
local time = 0.0
local last = core.get_us_time() / 1000000
core.register_globalstep(function(dtime)
local new = core.get_us_time() / 1000000
if new > last then
time = time + (new - last)
else
-- Overflow, we may lose a little bit of time here but
-- only 1 tick max, potentially running timers slightly
-- too early.
time = time + new
end
last = new
if #jobs < 1 then
return
end
-- Iterate backwards so that we miss any new timers added by
-- a timer callback, and so that we don't skip the next timer
-- in the list if we remove one.
for i = #jobs, 1, -1 do
local job = jobs[i]
if time >= job.expire then
core.set_last_run_mod(job.mod_origin)
job.func(unpack(job.arg))
table.remove(jobs, i)
end
end
end)
function core.after(after, func, ...)
assert(tonumber(after) and type(func) == "function",
"Invalid core.after invocation")
jobs[#jobs + 1] = {
func = func,
expire = time + after,
arg = {...},
mod_origin = core.get_last_run_mod()
}
end
function core.check_player_privs(name, ...)
local arg_type = type(name)
if (arg_type == "userdata" or arg_type == "table") and
@ -56,11 +12,11 @@ function core.check_player_privs(name, ...)
elseif arg_type ~= "string" then
error("Invalid core.check_player_privs argument type: " .. arg_type, 2)
end
local requested_privs = {...}
local player_privs = core.get_player_privs(name)
local missing_privileges = {}
if type(requested_privs[1]) == "table" then
-- We were provided with a table like { privA = true, privB = true }.
for priv, value in pairs(requested_privs[1]) do
@ -76,11 +32,11 @@ function core.check_player_privs(name, ...)
end
end
end
if #missing_privileges > 0 then
return false, missing_privileges
end
return true, ""
end
@ -114,6 +70,10 @@ function core.get_connected_players()
return temp_table
end
function minetest.player_exists(name)
return minetest.get_auth_handler().get_auth(name) ~= nil
end
-- Returns two position vectors representing a box of `radius` in each
-- direction centered around the player corresponding to `player_name`
function core.get_player_radius_area(player_name, radius)
@ -161,7 +121,7 @@ function core.get_node_group(name, group)
end
function core.setting_get_pos(name)
local value = core.setting_get(name)
local value = core.settings:get(name)
if not value then
return nil
end
@ -210,38 +170,11 @@ function core.http_add_fetch(httpenv)
return httpenv
end
if minetest.setting_getbool("disable_escape_sequences") then
function core.get_color_escape_sequence(color)
return ""
end
function core.get_background_escape_sequence(color)
return ""
end
function core.colorize(color, message)
return message
end
else
local ESCAPE_CHAR = string.char(0x1b)
function core.get_color_escape_sequence(color)
return ESCAPE_CHAR .. "(c@" .. color .. ")"
end
function core.get_background_escape_sequence(color)
return ESCAPE_CHAR .. "(b@" .. color .. ")"
end
function core.colorize(color, message)
return core.get_color_escape_sequence(color) .. message .. core.get_color_escape_sequence("#ffffff")
end
end
function core.close_formspec(player_name, formname)
return minetest.show_formspec(player_name, formname, "")
end
function core.cancel_shutdown_requests()
core.request_shutdown("", false, -1)
end

@ -331,8 +331,8 @@ core.register_item(":unknown", {
core.register_node(":air", {
description = "Air (you hacker you!)",
inventory_image = "unknown_node.png",
wield_image = "unknown_node.png",
inventory_image = "air.png",
wield_image = "air.png",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
@ -348,8 +348,8 @@ core.register_node(":air", {
core.register_node(":ignore", {
description = "Ignore (you hacker you!)",
inventory_image = "unknown_node.png",
wield_image = "unknown_node.png",
inventory_image = "ignore.png",
wield_image = "ignore.png",
drawtype = "airlike",
paramtype = "none",
sunlight_propagates = false,

@ -1,3 +1,5 @@
-- cache setting
local enable_damage = core.settings:get_bool("enable_damage")
local health_bar_definition =
{
@ -42,9 +44,8 @@ local function initialize_builtin_statbars(player)
player:hud_set_flags(player:hud_get_flags())
end
if player:hud_get_flags().healthbar and
core.is_yes(core.setting_get("enable_damage")) then
if hud_ids[name].id_healthbar == nil then
if player:hud_get_flags().healthbar and enable_damage then
if hud_ids[name].id_healthbar == nil then
health_bar_definition.number = player:get_hp()
hud_ids[name].id_healthbar = player:hud_add(health_bar_definition)
end
@ -56,8 +57,7 @@ local function initialize_builtin_statbars(player)
end
if (player:get_breath() < 11) then
if player:hud_get_flags().breathbar and
core.is_yes(core.setting_get("enable_damage")) then
if player:hud_get_flags().breathbar and enable_damage then
if hud_ids[name].id_breathbar == nil then
hud_ids[name].id_breathbar = player:hud_add(breath_bar_definition)
end

@ -1,10 +1,10 @@
-- Minetest: builtin/static_spawn.lua
local function warn_invalid_static_spawnpoint()
if core.setting_get("static_spawnpoint") and
if core.settings:get("static_spawnpoint") and
not core.setting_get_pos("static_spawnpoint") then
core.log("error", "The static_spawnpoint setting is invalid: \""..
core.setting_get("static_spawnpoint").."\"")
core.settings:get("static_spawnpoint").."\"")
end
end

@ -27,6 +27,7 @@ minetest = core
-- Load other files
local scriptdir = core.get_builtin_path() .. DIR_DELIM
local gamepath = scriptdir .. "game" .. DIR_DELIM
local clientpath = scriptdir .. "client" .. DIR_DELIM
local commonpath = scriptdir .. "common" .. DIR_DELIM
local asyncpath = scriptdir .. "async" .. DIR_DELIM
@ -37,15 +38,17 @@ dofile(commonpath .. "misc_helpers.lua")
if INIT == "game" then
dofile(gamepath .. "init.lua")
elseif INIT == "mainmenu" then
local mainmenuscript = core.setting_get("main_menu_script")
if mainmenuscript ~= nil and mainmenuscript ~= "" then
dofile(mainmenuscript)
local mm_script = core.settings:get("main_menu_script")
if mm_script and mm_script ~= "" then
dofile(mm_script)
else
dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
end
elseif INIT == "async" then
dofile(asyncpath .. "init.lua")
elseif INIT == "client" then
os.setlocale = nil
dofile(clientpath .. "init.lua")
else
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
end

@ -43,10 +43,10 @@ end
local function configure_selected_world_params(idx)
local worldconfig = modmgr.get_worldconfig(menudata.worldlist:get_list()[idx].path)
if worldconfig.creative_mode then
core.setting_set("creative_mode", worldconfig.creative_mode)
core.settings:set("creative_mode", worldconfig.creative_mode)
end
if worldconfig.enable_damage then
core.setting_set("enable_damage", worldconfig.enable_damage)
core.settings:set("enable_damage", worldconfig.enable_damage)
end
end
@ -54,7 +54,12 @@ 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 .. "server_flags_" .. flagname .. ".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
--------------------------------------------------------------------------------
@ -77,7 +82,7 @@ function order_favorite_list(list)
end
--------------------------------------------------------------------------------
function render_favorite(spec, is_favorite)
function render_serverlist_row(spec, is_favorite)
local text = ""
if spec.name then
text = text .. core.formspec_escape(spec.name:trim())
@ -97,6 +102,21 @@ function render_favorite(spec, is_favorite)
details = "0,"
end
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,"
else
details = details .. "5,"
end
else
details = details .. "0,"
end
if spec.clients and spec.clients_max then
local clients_color = ''
local clients_percent = 100 * spec.clients / spec.clients_max
@ -144,8 +164,8 @@ end
--------------------------------------------------------------------------------
os.tempfolder = function()
if core.setting_get("TMPFolder") then
return core.setting_get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000)
if core.settings:get("TMPFolder") then
return core.settings:get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000)
end
local filetocheck = os.tmpname()
@ -186,7 +206,7 @@ function menu_handle_key_up_down(fields, textlist, settingname)
oldidx < menudata.worldlist:size() then
newidx = oldidx + 1
end
core.setting_set(settingname, menudata.worldlist:get_raw_index(newidx))
core.settings:set(settingname, menudata.worldlist:get_raw_index(newidx))
configure_selected_world_params(newidx)
return true
end
@ -230,7 +250,7 @@ end
--------------------------------------------------------------------------------
function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency)
local textlines = core.splittext(text, textlen)
local textlines = core.wrap_text(text, textlen)
local retval = "textlist[" .. xpos .. "," .. ypos .. ";" .. width ..
"," .. height .. ";" .. tl_name .. ";"
@ -308,9 +328,9 @@ function menu_worldmt_legacy(selected)
for _, mode_name in pairs(modes_names) do
local mode_val = menu_worldmt(selected, mode_name)
if mode_val then
core.setting_set(mode_name, mode_val)
core.settings:set(mode_name, mode_val)
else
menu_worldmt(selected, mode_name, core.setting_get(mode_name))
menu_worldmt(selected, mode_name, core.settings:get(mode_name))
end
end
end

@ -17,14 +17,13 @@
--------------------------------------------------------------------------------
local enabled_all = false
local enabled_all = false
local function modname_valid(name)
return not name:find("[^a-z0-9_]")
end
local function get_formspec(data)
local mod = data.list:get_list()[data.selected_mod]
local retval =
@ -32,24 +31,12 @@ local function get_formspec(data)
"label[0.5,0;" .. fgettext("World:") .. "]" ..
"label[1.75,0;" .. data.worldspec.name .. "]"
if data.hide_gamemods then
retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]"
else
retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]"
end
if data.hide_modpackcontents then
retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]"
else
retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]"
end
if mod == nil then
mod = {name=""}
end
local hard_deps, soft_deps = modmgr.get_dependencies(mod.path)
retval = retval ..
"label[0,0.7;" .. fgettext("Mod:") .. "]" ..
"label[0.75,0.7;" .. mod.name .. "]" ..
@ -62,41 +49,45 @@ local function get_formspec(data)
"button[3.25,7;2.5,0.5;btn_config_world_save;" .. fgettext("Save") .. "]" ..
"button[5.75,7;2.5,0.5;btn_config_world_cancel;" .. fgettext("Cancel") .. "]"
if mod ~= nil and mod.name ~= "" and mod.typ ~= "game_mod" then
if mod and mod.name ~= "" and not mod.is_game_content then
if mod.is_modpack then
local rawlist = data.list:get_raw_list()
local all_enabled = true
for j=1,#rawlist,1 do
if rawlist[j].modpack == mod.name and
rawlist[j].enabled ~= true then
all_enabled = false
break
for j = 1, #rawlist, 1 do
if rawlist[j].modpack == mod.name and not rawlist[j].enabled then
all_enabled = false
break
end
end
if all_enabled == false then
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_enable;" .. fgettext("Enable MP") .. "]"
if all_enabled then
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_disable;" ..
fgettext("Disable MP") .. "]"
else
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_disable;" .. fgettext("Disable MP") .. "]"
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_enable;" ..
fgettext("Enable MP") .. "]"
end
else
if mod.enabled then
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. ";true]"
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" ..
fgettext("enabled") .. ";true]"
else
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. ";false]"
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" ..
fgettext("enabled") .. ";false]"
end
end
end
if enabled_all then
if enabled_all then
retval = retval ..
"button[8.75,0.125;2.5,0.5;btn_disable_all_mods;" .. fgettext("Disable all") .. "]" ..
"textlist[5.5,0.75;5.75,5.4;world_config_modlist;"
"button[8.75,0.125;2.5,0.5;btn_disable_all_mods;" .. fgettext("Disable all") .. "]"
else
retval = retval ..
"button[8.75,0.125;2.5,0.5;btn_enable_all_mods;" .. fgettext("Enable all") .. "]" ..
"textlist[5.5,0.75;5.75,5.4;world_config_modlist;"
"button[8.75,0.125;2.5,0.5;btn_enable_all_mods;" .. fgettext("Enable all") .. "]"
end
retval = retval ..
"tablecolumns[color;tree;text]" ..
"table[5.5,0.75;5.75,6;world_config_modlist;"
retval = retval .. modmgr.render_modlist(data.list)
retval = retval .. ";" .. data.selected_mod .."]"
@ -106,7 +97,7 @@ end
local function enable_mod(this, toset)
local mod = this.data.list:get_list()[this.data.selected_mod]
if mod.typ == "game_mod" then
if mod.is_game_content then
-- game mods can't be enabled or disabled
elseif not mod.is_modpack then
if toset == nil then
@ -129,16 +120,15 @@ end
local function handle_buttons(this, fields)
if fields["world_config_modlist"] ~= nil then
local event = core.explode_textlist_event(fields["world_config_modlist"])
this.data.selected_mod = event.index
core.setting_set("world_config_selected_mod", event.index)
local event = core.explode_table_event(fields["world_config_modlist"])
this.data.selected_mod = event.row
core.settings:set("world_config_selected_mod", event.row)
if event.type == "DCL" then
enable_mod(this)
end
return true
end
@ -160,44 +150,7 @@ local function handle_buttons(this, fields)
return true
end
if fields["cb_hide_gamemods"] ~= nil or
fields["cb_hide_mpcontent"] ~= nil then
local current = this.data.list:get_filtercriteria()
if current == nil then
current = {}
end
if fields["cb_hide_gamemods"] ~= nil then
if core.is_yes(fields["cb_hide_gamemods"]) then
current.hide_game = true
this.data.hide_gamemods = true
core.setting_set("world_config_hide_gamemods", "true")
else
current.hide_game = false
this.data.hide_gamemods = false
core.setting_set("world_config_hide_gamemods", "false")
end
end
if fields["cb_hide_mpcontent"] ~= nil then
if core.is_yes(fields["cb_hide_mpcontent"]) then
current.hide_modpackcontents = true
this.data.hide_modpackcontents = true
core.setting_set("world_config_hide_modpackcontents", "true")
else
current.hide_modpackcontents = false
this.data.hide_modpackcontents = false
core.setting_set("world_config_hide_modpackcontents", "false")
end
end
this.data.list:set_filtercriteria(current)
return true
end
if fields["btn_config_world_save"] then
local filename = this.data.worldspec.path ..
DIR_DELIM .. "world.mt"
@ -209,7 +162,7 @@ local function handle_buttons(this, fields)
local i,mod
for i,mod in ipairs(rawlist) do
if not mod.is_modpack and
mod.typ ~= "game_mod" then
not mod.is_game_content then
if modname_valid(mod.name) then
worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
else
@ -231,7 +184,7 @@ local function handle_buttons(this, fields)
if not worldfile:write() then
core.log("error", "Failed to write world config file")
end
this:delete()
return true
end
@ -245,19 +198,21 @@ local function handle_buttons(this, fields)
local list = this.data.list:get_raw_list()
for i = 1, #list do
if list[i].typ ~= "game_mod" and not list[i].is_modpack then
if not list[i].is_game_content
and not list[i].is_modpack then
list[i].enabled = true
end
end
enabled_all = true
return true
end
if fields.btn_disable_all_mods then
local list = this.data.list:get_raw_list()
for i = 1, #list do
if list[i].typ ~= "game_mod" and not list[i].is_modpack then
if not list[i].is_game_content
and not list[i].is_modpack then
list[i].enabled = false
end
end
@ -269,15 +224,12 @@ local function handle_buttons(this, fields)
end
function create_configure_world_dlg(worldidx)
local dlg = dialog_create("sp_config_world",
get_formspec,
handle_buttons,
nil)
dlg.data.hide_gamemods = core.setting_getbool("world_config_hide_gamemods")
dlg.data.hide_modpackcontents = core.setting_getbool("world_config_hide_modpackcontents")
dlg.data.selected_mod = tonumber(core.setting_get("world_config_selected_mod"))
dlg.data.selected_mod = tonumber(core.settings:get("world_config_selected_mod"))
if dlg.data.selected_mod == nil then
dlg.data.selected_mod = 0
end
@ -286,14 +238,14 @@ function create_configure_world_dlg(worldidx)
if dlg.data.worldspec == nil then dlg:delete() return nil end
dlg.data.worldconfig = modmgr.get_worldconfig(dlg.data.worldspec.path)
if dlg.data.worldconfig == nil or dlg.data.worldconfig.id == nil or
dlg.data.worldconfig.id == "" then
dlg:delete()
return nil
end
dlg.data.list = filterlist.create(
modmgr.preparemodlist, --refresh
modmgr.comparemod, --compare
@ -302,16 +254,16 @@ function create_configure_world_dlg(worldidx)
return true
end
end,
function(element,criteria)
function(element, criteria)
if criteria.hide_game and
element.typ == "game_mod" then
return false
element.is_game_content then
return false
end
if criteria.hide_modpackcontents and
element.modpack ~= nil then
return false
end
element.modpack ~= nil then
return false
end
return true
end, --filter
{ worldpath= dlg.data.worldspec.path,

@ -18,8 +18,8 @@
local function create_world_formspec(dialogdata)
local mapgens = core.get_mapgen_names()
local current_seed = core.setting_get("fixed_map_seed") or ""
local current_mg = core.setting_get("mg_name")
local current_seed = core.settings:get("fixed_map_seed") or ""
local current_mg = core.settings:get("mg_name")
local mglist = ""
local selindex = 1
@ -33,7 +33,7 @@ local function create_world_formspec(dialogdata)
end
mglist = mglist:sub(1, -2)
local gameid = core.setting_get("menu_last_game")
local gameid = core.settings:get("menu_last_game")
local game, gameidx = nil , 0
if gameid ~= nil then
@ -90,10 +90,10 @@ local function create_world_buttonhandler(this, fields)
local message = nil
core.setting_set("fixed_map_seed", fields["te_seed"])
core.settings:set("fixed_map_seed", fields["te_seed"])
if not menudata.worldlist:uid_exists_raw(worldname) then
core.setting_set("mg_name",fields["dd_mapgen"])
core.settings:set("mg_name",fields["dd_mapgen"])
message = core.create_world(worldname,gameindex)
else
message = fgettext("A world named \"$1\" already exists", worldname)
@ -102,13 +102,13 @@ local function create_world_buttonhandler(this, fields)
if message ~= nil then
gamedata.errormessage = message
else
core.setting_set("menu_last_game",gamemgr.games[gameindex].id)
core.settings:set("menu_last_game",gamemgr.games[gameindex].id)
if this.data.update_worldlist_filter then
menudata.worldlist:set_filtercriteria(gamemgr.games[gameindex].id)
mm_texture.update("singleplayer", gamemgr.games[gameindex].id)
end
menudata.worldlist:refresh()
core.setting_set("mainmenu_last_selected_world",
core.settings:set("mainmenu_last_selected_world",
menudata.worldlist:raw_index_by_uid(worldname))
end
else

@ -344,11 +344,86 @@ local function parse_config_file(read_all, parse_mods)
return settings
end
local settings = parse_config_file(false, true)
local function filter_settings(settings, searchstring)
if not searchstring or searchstring == "" then
return settings, -1
end
-- Setup the keyword list
local keywords = {}
for word in searchstring:lower():gmatch("%S+") do
table.insert(keywords, word)
end
local result = {}
local category_stack = {}
local current_level = 0
local best_setting = nil
for _, entry in pairs(settings) do
if entry.type == "category" then
-- Remove all settingless categories
while #category_stack > 0 and entry.level <= current_level do
table.remove(category_stack, #category_stack)
if #category_stack > 0 then
current_level = category_stack[#category_stack].level
else
current_level = 0
end
end
-- Push category onto stack
category_stack[#category_stack + 1] = entry
current_level = entry.level
else
-- See if setting matches keywords
local setting_score = 0
for k = 1, #keywords do
local keyword = keywords[k]
if string.find(entry.name:lower(), keyword, 1, true) then
setting_score = setting_score + 1
end
if entry.readable_name and
string.find(fgettext(entry.readable_name):lower(), keyword, 1, true) then
setting_score = setting_score + 1
end
if entry.comment and
string.find(fgettext_ne(entry.comment):lower(), keyword, 1, true) then
setting_score = setting_score + 1
end
end
-- Add setting to results if match
if setting_score > 0 then
-- Add parent categories
for _, category in pairs(category_stack) do
result[#result + 1] = category
end
category_stack = {}
-- Add setting
result[#result + 1] = entry
entry.score = setting_score
if not best_setting or
setting_score > result[best_setting].score then
best_setting = #result
end
end
end
end
return result, best_setting or -1
end
local full_settings = parse_config_file(false, true)
local search_string = ""
local settings = full_settings
local selected_setting = 1
local function get_current_value(setting)
local value = core.setting_get(setting.name)
local value = core.settings:get(setting.name)
if value == nil then
value = setting.default
end
@ -464,11 +539,11 @@ local function handle_change_setting_buttons(this, fields)
if setting.type == "bool" then
local new_value = fields["dd_setting_value"]
-- Note: new_value is the actual (translated) value shown in the dropdown
core.setting_setbool(setting.name, new_value == fgettext("Enabled"))
core.settings:set_bool(setting.name, new_value == fgettext("Enabled"))
elseif setting.type == "enum" then
local new_value = fields["dd_setting_value"]
core.setting_set(setting.name, new_value)
core.settings:set(setting.name, new_value)
elseif setting.type == "int" then
local new_value = tonumber(fields["te_setting_value"])
@ -490,7 +565,7 @@ local function handle_change_setting_buttons(this, fields)
core.update_formspec(this:get_formspec())
return true
end
core.setting_set(setting.name, new_value)
core.settings:set(setting.name, new_value)
elseif setting.type == "float" then
local new_value = tonumber(fields["te_setting_value"])
@ -500,7 +575,7 @@ local function handle_change_setting_buttons(this, fields)
core.update_formspec(this:get_formspec())
return true
end
core.setting_set(setting.name, new_value)
core.settings:set(setting.name, new_value)
elseif setting.type == "flags" then
local new_value = fields["te_setting_value"]
@ -514,13 +589,13 @@ local function handle_change_setting_buttons(this, fields)
return true
end
end
core.setting_set(setting.name, new_value)
core.settings:set(setting.name, new_value)
else
local new_value = fields["te_setting_value"]
core.setting_set(setting.name, new_value)
core.settings:set(setting.name, new_value)
end
core.setting_save()
core.settings:write()
this:delete()
return true
end
@ -544,14 +619,17 @@ end
local function create_settings_formspec(tabview, name, tabdata)
local formspec = "size[12,6.5;true]" ..
"tablecolumns[color;tree;text;text]" ..
"tablecolumns[color;tree;text,width=32;text]" ..
"tableoptions[background=#00000000;border=false]" ..
"table[0,0;12,5.5;list_settings;"
"field[0.3,0.1;10.2,1;search_string;;" .. core.formspec_escape(search_string) .. "]" ..
"field_close_on_enter[search_string;false]" ..
"button[10.2,-0.2;2,1;search;" .. fgettext("Search") .. "]" ..
"table[0,0.8;12,4.5;list_settings;"
local current_level = 0
for _, entry in ipairs(settings) do
local name
if not core.setting_getbool("main_menu_technical_settings") and entry.readable_name then
if not core.settings:get_bool("main_menu_technical_settings") and entry.readable_name then
name = fgettext_ne(entry.readable_name)
else
name = entry.name
@ -588,7 +666,7 @@ local function create_settings_formspec(tabview, name, tabdata)
"button[10,6;2,1;btn_edit;" .. fgettext("Edit") .. "]" ..
"button[7,6;3,1;btn_restore;" .. fgettext("Restore Default") .. "]" ..
"checkbox[0,5.3;cb_tech_settings;" .. fgettext("Show technical names") .. ";"
.. dump(core.setting_getbool("main_menu_technical_settings")) .. "]"
.. dump(core.settings:get_bool("main_menu_technical_settings")) .. "]"
return formspec
end
@ -597,13 +675,13 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
local list_enter = false
if fields["list_settings"] then
selected_setting = core.get_table_index("list_settings")
if core.explode_table_event(fields["list_settings"]).type == "DCL" then
if core.explode_table_event(fields["list_settings"]).type == "DCL" then
-- Directly toggle booleans
local setting = settings[selected_setting]
if setting.type == "bool" then
if setting and setting.type == "bool" then
local current_value = get_current_value(setting)
core.setting_setbool(setting.name, not core.is_yes(current_value))
core.setting_save()
core.settings:set_bool(setting.name, not core.is_yes(current_value))
core.settings:write()
return true
else
list_enter = true
@ -613,9 +691,39 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
end
end
if fields.search or fields.key_enter_field == "search_string" then
if search_string == fields.search_string then
if selected_setting > 0 then
-- Go to next result on enter press
local i = selected_setting + 1
local looped = false
while i > #settings or settings[i].type == "category" do
i = i + 1
if i > #settings then
-- Stop infinte looping
if looped then
return false
end
i = 1
looped = true
end
end
selected_setting = i
core.update_formspec(this:get_formspec())
return true
end
else
-- Search for setting
search_string = fields.search_string
settings, selected_setting = filter_settings(full_settings, search_string)
core.update_formspec(this:get_formspec())
end
return true
end
if fields["btn_edit"] or list_enter then
local setting = settings[selected_setting]
if setting.type ~= "category" then
if setting and setting.type ~= "category" then
local edit_dialog = dialog_create("change_setting", create_change_setting_formspec,
handle_change_setting_buttons)
edit_dialog:set_parent(this)
@ -627,9 +735,9 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
if fields["btn_restore"] then
local setting = settings[selected_setting]
if setting.type ~= "category" then
core.setting_set(setting.name, setting.default)
core.setting_save()
if setting and setting.type ~= "category" then
core.settings:set(setting.name, setting.default)
core.settings:write()
core.update_formspec(this:get_formspec())
end
return true
@ -641,8 +749,8 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
end
if fields["cb_tech_settings"] then
core.setting_set("main_menu_technical_settings", fields["cb_tech_settings"])
core.setting_save()
core.settings:set("main_menu_technical_settings", fields["cb_tech_settings"])
core.settings:write()
core.update_formspec(this:get_formspec())
return true
end
@ -661,10 +769,4 @@ end
-- Generate minetest.conf.example and settings_translation_file.cpp
-- *** Please note ***
-- There is text in minetest.conf.example that will not be generated from
-- settingtypes.txt but must be preserved:
-- The documentation of mapgen noise parameter formats (title plus 16 lines)
-- Noise parameter 'mgv5_np_ground' in group format (13 lines)
--assert(loadfile(core.get_mainmenu_path()..DIR_DELIM.."generate_from_settingtypes.lua"))(parse_config_file(true, false))
--assert(loadfile(core.get_builtin_path()..DIR_DELIM.."mainmenu"..DIR_DELIM.."generate_from_settingtypes.lua"))(parse_config_file(true, false))

@ -68,10 +68,10 @@ end
function gamemgr.gamelist()
local retval = ""
if #gamemgr.games > 0 then
retval = retval .. gamemgr.games[1].name
retval = retval .. core.formspec_escape(gamemgr.games[1].name)
for i=2,#gamemgr.games,1 do
retval = retval .. "," .. gamemgr.games[i].name
retval = retval .. "," .. core.formspec_escape(gamemgr.games[i].name)
end
end
return retval

@ -16,9 +16,9 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
mt_color_grey = "#AAAAAA"
mt_color_blue = "#0000DD"
mt_color_green = "#00DD00"
mt_color_dark_green = "#003300"
mt_color_blue = "#6389FF"
mt_color_green = "#72FF63"
mt_color_dark_green = "#25C191"
--for all other colors ask sfan5 to complete his work!
@ -56,9 +56,8 @@ tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
if PLATFORM == "Android" then
tabs.simple_main = dofile(menupath .. DIR_DELIM .. "tab_simple_main.lua")
else
tabs.singleplayer = dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
tabs.multiplayer = dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
tabs.server = dofile(menupath .. DIR_DELIM .. "tab_server.lua")
tabs.local_game = dofile(menupath .. DIR_DELIM .. "tab_local.lua")
tabs.play_online = dofile(menupath .. DIR_DELIM .. "tab_online.lua")
tabs.texturepacks = dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
end
@ -119,25 +118,24 @@ local function init_globals()
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
menudata.worldlist:set_sortmode("alphabetic")
if not core.setting_get("menu_last_game") then
local default_game = core.setting_get("default_game") or "minetest"
core.setting_set("menu_last_game", default_game)
if not core.settings:get("menu_last_game") then
local default_game = core.settings:get("default_game") or "minetest"
core.settings:set("menu_last_game", default_game)
end
mm_texture.init()
end
-- Create main tabview
local tv_main = tabview_create("maintab", {x = 12, y = 5.2}, {x = 0, y = 0})
local tv_main = tabview_create("maintab", {x = 12, y = 5.4}, {x = 0, y = 0})
if PLATFORM == "Android" then
tv_main:add(tabs.simple_main)
tv_main:add(tabs.settings)
else
tv_main:set_autosave_tab(true)
tv_main:add(tabs.singleplayer)
tv_main:add(tabs.multiplayer)
tv_main:add(tabs.server)
tv_main:add(tabs.local_game)
tv_main:add(tabs.play_online)
tv_main:add(tabs.settings)
tv_main:add(tabs.texturepacks)
end
@ -149,7 +147,7 @@ local function init_globals()
tv_main:set_fixed_size(false)
if PLATFORM ~= "Android" then
tv_main:set_tab(core.setting_get("maintab_LAST"))
tv_main:set_tab(core.settings:get("maintab_LAST"))
end
ui.set_default("maintab")
tv_main:show()
@ -167,4 +165,3 @@ local function init_globals()
end
init_globals()

@ -18,7 +18,7 @@
--------------------------------------------------------------------------------
function get_mods(path,retval,modpack)
local mods = core.get_dir_list(path, true)
for _, name in ipairs(mods) do
if name:sub(1, 1) ~= "." then
local prefix = path .. DIR_DELIM .. name .. DIR_DELIM
@ -237,49 +237,37 @@ function modmgr.render_modlist(render_list)
local list = render_list:get_list()
local last_modpack = nil
for i,v in ipairs(list) do
if retval ~= "" then
retval = retval ..","
end
local retval = {}
for i, v in ipairs(list) do
local color = ""
if v.is_modpack then
local rawlist = render_list:get_raw_list()
color = mt_color_dark_green
local all_enabled = true
for j=1,#rawlist,1 do
for j = 1, #rawlist, 1 do
if rawlist[j].modpack == list[i].name and
rawlist[j].enabled ~= true then
all_enabled = false
break
rawlist[j].enabled ~= true then
-- Modpack not entirely enabled so showing as grey
color = mt_color_grey
break
end
end
if all_enabled == false then
color = mt_color_grey
else
color = mt_color_dark_green
end
end
if v.typ == "game_mod" then
elseif v.is_game_content then
color = mt_color_blue
else
if v.enabled then
color = mt_color_green
end
elseif v.enabled then
color = mt_color_green
end
retval = retval .. color
if v.modpack ~= nil then
retval = retval .. " "
retval[#retval + 1] = color
if v.modpack ~= nil or v.typ == "game_mod" then
retval[#retval + 1] = "1"
else
retval[#retval + 1] = "0"
end
retval = retval .. v.name
retval[#retval + 1] = core.formspec_escape(v.name)
end
return retval
return table.concat(retval, ",")
end
--------------------------------------------------------------------------------
@ -425,8 +413,18 @@ function modmgr.preparemodlist(data)
local gamespec = gamemgr.find_by_gameid(data.gameid)
gamemgr.get_game_mods(gamespec, game_mods)
if #game_mods > 0 then
-- Add title
retval[#retval + 1] = {
typ = "game",
is_game_content = true,
name = fgettext("Subgame Mods")
}
end
for i=1,#game_mods,1 do
game_mods[i].typ = "game_mod"
game_mods[i].is_game_content = true
retval[#retval + 1] = game_mods[i]
end

@ -233,14 +233,14 @@ function modstore.handle_buttons(parent, fields, name, data)
if not core.handle_async(
function(param)
local fullurl = core.setting_get("modstore_download_url") ..
local fullurl = core.settings:get("modstore_download_url") ..
param.moddetails.download_url
if param.version ~= nil then
local found = false
for i=1,#param.moddetails.versions, 1 do
if param.moddetails.versions[i].date:sub(1,10) == param.version then
fullurl = core.setting_get("modstore_download_url") ..
fullurl = core.settings:get("modstore_download_url") ..
param.moddetails.versions[i].download_url
found = true
end
@ -400,7 +400,7 @@ function modstore.getscreenshot(ypos,listentry)
listentry.texturename = "in progress"
--prepare url and filename
local fullurl = core.setting_get("modstore_download_url") ..
local fullurl = core.settings:get("modstore_download_url") ..
listentry.details.screenshot_url
local filename = os.tempfolder() .. "_MID_" .. listentry.id

@ -19,61 +19,68 @@
local core_developers = {
"Perttu Ahola (celeron55) <celeron55@gmail.com>",
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
"PilzAdam <pilzadam@minetest.net>",
"sfan5 <sfan5@live.de>",
"kahrl <kahrl@gmx.net>",
"sapier",
"ShadowNinja <shadowninja@minetest.net>",
"Nathanaël Courant (Nore/Ekdohibs) <nore@mesecons.net>",
"Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>",
"Matt Gregory (paramat)",
"est31 <MTest31@outlook.com>",
"paramat",
"Craig Robbins (Zeno) <craig.d.robbins@gmail.com>",
"Auke Kok (sofar) <sofar@foo-projects.org>",
"Andrew Ward (rubenwardy) <rubenwardy@gmail.com>",
"rubenwardy <rw@rubenwardy.com>",
"Krock/SmallJoker <mk939@ymail.com>",
}
local active_contributors = {
"Duane Robertson <duane@duanerobertson.com>",
"SmallJoker <mk939@ymail.com>",
"Lars Hofhansl <larsh@apache.org>",
"Jeija <jeija@mesecons.net>",
"Gregory Currie (gregorycu)",
"Sokomine <wegwerf@anarres.dyndns.org>",
"TeTpaAka",
"Jean-Patrick G (kilbith) <jeanpatrick.guerrero@gmail.com>",
"Diego Martínez (kaeza) <kaeza@users.sf.net>",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
"Rogier <rogier777@gmail.com>",
"red-001 <red-001@outlook.ie> [CSM & Menu fixes]",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com> [Audiovisuals: lighting]",
"numberZero [Audiovisuals: meshgen]",
"Lars Hofhansl <larsh@apache.org> [Occulusion culling, fixes]",
"Jean-Patrick G (kilbith) <jeanpatrick.guerrero@gmail.com> [Audiovisuals]",
"Vincent Glize (Dumbeldor) <vincent.glize@live.fr> [CSM]",
"bigfoot547 [CSM]",
"Rogier <rogier777@gmail.com> [Fixes]",
"Wuzzy [Audiovisuals]",
"Shara/Ezhh [Settings]",
}
local previous_core_developers = {
"BlockMen",
"Maciej Kasatkin (RealBadAngel) <maciej.kasatkin@o2.pl>",
"Maciej Kasatkin (RealBadAngel) [RIP]",
"Lisa Milne (darkrose) <lisa@ltmnet.com>",
"proller",
"Ilya Zhuravlev (xyz) <xyz@minetest.net>",
"PilzAdam <pilzadam@minetest.net>",
"est31 <MTest31@outlook.com>",
"kahrl <kahrl@gmx.net>",
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
"sapier",
}
local previous_contributors = {
"Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>",
"Jurgen Doser (doserj) <jurgen.doser@gmail.com>",
"MirceaKitsune <mirceakitsune@gmail.com>",
"dannydark <the_skeleton_of_a_child@yahoo.co.uk>",
"0gb.us <0gb.us@0gb.us>",
"Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>",
"Jonathan Neuschafer <j.neuschaefer@gmx.net>",
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>",
"Břetislav Štec (t0suj4/TBC_x)",
"Aaron Suen <warr1024@gmail.com>",
"Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>",
"matttpt <matttpt@gmail.com>",
"JacobF <queatz@gmail.com>",
"TriBlade9 <triblade9@mail.com>",
"Zefram <zefram@fysh.org>",
"Gregory Currie (gregorycu) [optimisation]",
"Diego Martínez (kaeza) <kaeza@users.sf.net>",
"T4im [Profiler]",
"TeTpaAka [Hand overriding, nametag colors]",
"HybridDog [Fixes]",
"Duane Robertson <duane@duanerobertson.com> [MGValleys]",
"neoascetic [OS X Fixes]",
"TriBlade9 <triblade9@mail.com> [Audiovisuals]",
"Jurgen Doser (doserj) <jurgen.doser@gmail.com> [Fixes]",
"MirceaKitsune <mirceakitsune@gmail.com> [Audiovisuals]",
"Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com> [Fixes]",
"matttpt <matttpt@gmail.com> [Fixes]",
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest Logo]",
"Jeija <jeija@mesecons.net> [HTTP, particles]",
}
local function buildCreditList(source)
ret = {}
for i = 1, #source do
ret[i] = core.formspec_escape(source[i])
end
return table.concat(ret, ",,")
end
return {
name = "credits",
caption = fgettext("Credits"),
@ -85,15 +92,15 @@ return {
"label[0.5,3.5;http://minetest.net]" ..
"tablecolumns[color;text]" ..
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
"table[3.5,-0.25;8.5,5.8;list_credits;" ..
"table[3.5,-0.25;8.5,6.05;list_credits;" ..
"#FFFF00," .. fgettext("Core Developers") .. ",," ..
table.concat(core_developers, ",,") .. ",,," ..
buildCreditList(core_developers) .. ",,," ..
"#FFFF00," .. fgettext("Active Contributors") .. ",," ..
table.concat(active_contributors, ",,") .. ",,," ..
buildCreditList(active_contributors) .. ",,," ..
"#FFFF00," .. fgettext("Previous Core Developers") ..",," ..
table.concat(previous_core_developers, ",,") .. ",,," ..
buildCreditList(previous_core_developers) .. ",,," ..
"#FFFF00," .. fgettext("Previous Contributors") .. ",," ..
table.concat(previous_contributors, ",,") .. "," ..
buildCreditList(previous_contributors) .. "," ..
";1]"
end
}

@ -16,9 +16,9 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
local function current_game()
local last_game_id = core.setting_get("menu_last_game")
local last_game_id = core.settings:get("menu_last_game")
local game, index = gamemgr.find_by_gameid(last_game_id)
return game
end
@ -36,10 +36,10 @@ local function singleplayer_refresh_gamebar()
if ("game_btnbar_" .. gamemgr.games[j].id == key) then
mm_texture.update("singleplayer", gamemgr.games[j])
core.set_topleft_text(gamemgr.games[j].name)
core.setting_set("menu_last_game",gamemgr.games[j].id)
core.settings:set("menu_last_game",gamemgr.games[j].id)
menudata.worldlist:set_filtercriteria(gamemgr.games[j].id)
local index = filterlist.get_current_index(menudata.worldlist,
tonumber(core.setting_get("mainmenu_last_selected_world")))
tonumber(core.settings:get("mainmenu_last_selected_world")))
if not index or index < 1 then
local selected = core.get_textlist_index("sp_worlds")
if selected ~= nil and selected < #menudata.worldlist:get_list() then
@ -57,24 +57,24 @@ local function singleplayer_refresh_gamebar()
local btnbar = buttonbar_create("game_button_bar",
game_buttonbar_button_handler,
{x=-0.3,y=5.65}, "horizontal", {x=12.4,y=1.15})
{x=-0.3,y=5.9}, "horizontal", {x=12.4,y=1.15})
for i=1,#gamemgr.games,1 do
local btn_name = "game_btnbar_" .. gamemgr.games[i].id
local image = nil
local text = nil
local tooltip = core.formspec_escape(gamemgr.games[i].name)
if gamemgr.games[i].menuicon_path ~= nil and
gamemgr.games[i].menuicon_path ~= "" then
image = core.formspec_escape(gamemgr.games[i].menuicon_path)
else
local part1 = gamemgr.games[i].id:sub(1,5)
local part2 = gamemgr.games[i].id:sub(6,10)
local part3 = gamemgr.games[i].id:sub(11)
text = part1 .. "\n" .. part2
if part3 ~= nil and
part3 ~= "" then
@ -89,28 +89,57 @@ local function get_formspec(tabview, name, tabdata)
local retval = ""
local index = filterlist.get_current_index(menudata.worldlist,
tonumber(core.setting_get("mainmenu_last_selected_world"))
tonumber(core.settings:get("mainmenu_last_selected_world"))
)
retval = retval ..
"button[4,4.15;2.6,0.5;world_delete;".. fgettext("Delete") .. "]" ..
"button[6.5,4.15;2.8,0.5;world_create;".. fgettext("New") .. "]" ..
"button[9.2,4.15;2.55,0.5;world_configure;".. fgettext("Configure") .. "]" ..
"button[8.5,4.95;3.25,0.5;play;".. fgettext("Play") .. "]" ..
"label[4,-0.25;".. fgettext("Select World:") .. "]"..
"checkbox[0.25,0.25;cb_creative_mode;".. fgettext("Creative Mode") .. ";" ..
dump(core.setting_getbool("creative_mode")) .. "]"..
dump(core.settings:get_bool("creative_mode")) .. "]"..
"checkbox[0.25,0.7;cb_enable_damage;".. fgettext("Enable Damage") .. ";" ..
dump(core.setting_getbool("enable_damage")) .. "]"..
dump(core.settings:get_bool("enable_damage")) .. "]"..
"checkbox[0.25,1.15;cb_server;".. fgettext("Host Server") ..";" ..
dump(core.settings:get_bool("enable_server")) .. "]" ..
"textlist[4,0.25;7.5,3.7;sp_worlds;" ..
menu_render_worldlist() ..
";" .. index .. "]"
if core.settings:get_bool("enable_server") then
retval = retval ..
"button[8.5,5;3.25,0.5;play;".. fgettext("Host Game") .. "]" ..
"checkbox[0.25,1.6;cb_server_announce;" .. fgettext("Announce Server") .. ";" ..
dump(core.settings:get_bool("server_announce")) .. "]" ..
"label[0.25,2.2;" .. fgettext("Name/Password") .. "]" ..
"field[0.55,3.2;3.5,0.5;te_playername;;" ..
core.formspec_escape(core.settings:get("name")) .. "]" ..
"pwdfield[0.55,4;3.5,0.5;te_passwd;]"
local bind_addr = core.settings:get("bind_address")
if bind_addr ~= nil and bind_addr ~= "" then
retval = retval ..
"field[0.55,5.2;2.25,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" ..
core.formspec_escape(core.settings:get("bind_address")) .. "]" ..
"field[2.8,5.2;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" ..
core.formspec_escape(core.settings:get("port")) .. "]"
else
retval = retval ..
"field[0.55,5.2;3.5,0.5;te_serverport;" .. fgettext("Server Port") .. ";" ..
core.formspec_escape(core.settings:get("port")) .. "]"
end
else
retval = retval ..
"button[8.5,5;3.25,0.5;play;".. fgettext("Play Game") .. "]"
end
return retval
end
local function main_button_handler(this, fields, name, tabdata)
assert(name == "singleplayer")
assert(name == "local")
local world_doubleclick = false
@ -125,7 +154,7 @@ local function main_button_handler(this, fields, name, tabdata)
end
if event.type == "CHG" and selected ~= nil then
core.setting_set("mainmenu_last_selected_world",
core.settings:set("mainmenu_last_selected_world",
menudata.worldlist:get_raw_index(selected))
return true
end
@ -136,7 +165,7 @@ local function main_button_handler(this, fields, name, tabdata)
end
if fields["cb_creative_mode"] then
core.setting_set("creative_mode", fields["cb_creative_mode"])
core.settings:set("creative_mode", fields["cb_creative_mode"])
local selected = core.get_textlist_index("sp_worlds")
menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"])
@ -144,27 +173,65 @@ local function main_button_handler(this, fields, name, tabdata)
end
if fields["cb_enable_damage"] then
core.setting_set("enable_damage", fields["cb_enable_damage"])
core.settings:set("enable_damage", fields["cb_enable_damage"])
local selected = core.get_textlist_index("sp_worlds")
menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"])
return true
end
if fields["play"] ~= nil or
world_doubleclick or
fields["key_enter"] then
if fields["cb_server"] then
core.settings:set("enable_server", fields["cb_server"])
return true
end
if fields["cb_server_announce"] then
core.settings:set("server_announce", fields["cb_server_announce"])
local selected = core.get_textlist_index("srv_worlds")
menu_worldmt(selected, "server_announce", fields["cb_server_announce"])
return true
end
if fields["play"] ~= nil or world_doubleclick or fields["key_enter"] then
local selected = core.get_textlist_index("sp_worlds")
gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
if selected ~= nil and gamedata.selected_world ~= 0 then
gamedata.singleplayer = true
core.start()
if core.settings:get_bool("enable_server") then
if selected ~= nil and gamedata.selected_world ~= 0 then
gamedata.playername = fields["te_playername"]
gamedata.password = fields["te_passwd"]
gamedata.port = fields["te_serverport"]
gamedata.address = ""
core.settings:set("port",gamedata.port)
if fields["te_serveraddr"] ~= nil then
core.settings:set("bind_address",fields["te_serveraddr"])
end
--update last game
local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
if world then
local game, index = gamemgr.find_by_gameid(world.gameid)
core.settings:set("menu_last_game", game.id)
end
core.start()
else
gamedata.errormessage =
fgettext("No world created or selected!")
end
else
gamedata.errormessage =
fgettext("No world created or selected!")
if selected ~= nil and gamedata.selected_world ~= 0 then
gamedata.singleplayer = true
core.start()
else
gamedata.errormessage =
fgettext("No world created or selected!")
end
return true
end
return true
end
if fields["world_create"] ~= nil then
@ -192,7 +259,7 @@ local function main_button_handler(this, fields, name, tabdata)
mm_texture.update("singleplayer",current_game())
end
end
return true
end
@ -202,7 +269,7 @@ local function main_button_handler(this, fields, name, tabdata)
local configdialog =
create_configure_world_dlg(
menudata.worldlist:get_raw_index(selected))
if (configdialog ~= nil) then
configdialog:set_parent(this)
this:hide()
@ -210,22 +277,22 @@ local function main_button_handler(this, fields, name, tabdata)
mm_texture.update("singleplayer",current_game())
end
end
return true
end
end
local function on_change(type, old_tab, new_tab)
local buttonbar = ui.find_by_name("game_button_bar")
if ( buttonbar == nil ) then
singleplayer_refresh_gamebar()
buttonbar = ui.find_by_name("game_button_bar")
end
if (type == "ENTER") then
local game = current_game()
if game then
menudata.worldlist:set_filtercriteria(game.id)
core.set_topleft_text(game.name)
@ -242,8 +309,8 @@ end
--------------------------------------------------------------------------------
return {
name = "singleplayer",
caption = fgettext("Singleplayer"),
name = "local",
caption = fgettext("Local Game"),
cbf_formspec = get_formspec,
cbf_button_handler = main_button_handler,
on_change = on_change

@ -28,7 +28,8 @@ local function get_formspec(tabview, name, tabdata)
local retval =
"label[0.05,-0.25;".. fgettext("Installed Mods:") .. "]" ..
"textlist[0,0.25;5.1,5;modlist;" ..
"tablecolumns[color;tree;text]" ..
"table[0,0.25;5.1,5;modlist;" ..
modmgr.render_modlist(modmgr.global_mods) ..
";" .. tabdata.selected_mod .. "]"
@ -74,7 +75,7 @@ local function get_formspec(tabview, name, tabdata)
if error == nil then
local descriptiontext = descriptionfile:read("*all")
descriptionlines = core.splittext(descriptiontext,42)
descriptionlines = core.wrap_text(descriptiontext, 42)
descriptionfile:close()
else
descriptionlines = {}
@ -127,8 +128,8 @@ end
--------------------------------------------------------------------------------
local function handle_buttons(tabview, fields, tabname, tabdata)
if fields["modlist"] ~= nil then
local event = core.explode_textlist_event(fields["modlist"])
tabdata.selected_mod = event.index
local event = core.explode_table_event(fields["modlist"])
tabdata.selected_mod = event.row
return true
end

@ -20,28 +20,48 @@ 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 = menudata.favorites[tabdata.fav_selected]
local fav_selected = nil
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 = ""
end
local retval =
"label[7.75,-0.15;" .. fgettext("Address / Port") .. "]" ..
"label[7.75,1.05;" .. fgettext("Name / Password") .. "]" ..
"field[8,0.75;3.3,0.5;te_address;;" ..
core.formspec_escape(core.setting_get("address")) .. "]" ..
"field[11.15,0.75;1.4,0.5;te_port;;" ..
core.formspec_escape(core.setting_get("remote_port")) .. "]" ..
"button[10.1,4.9;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]" ..
"field[8,1.95;2.95,0.5;te_name;;" ..
core.formspec_escape(core.setting_get("name")) .. "]" ..
"pwdfield[10.78,1.95;1.77,0.5;te_pwd;]" ..
"box[7.73,2.35;4.3,2.28;#999999]"
-- Search
"field[0.15,0.35;6.05,0.27;te_search;;"..core.formspec_escape(tabdata.search_for).."]"..
"button[5.8,0.1;2,0.1;btn_mp_search;" .. fgettext("Search") .. "]" ..
-- Address / Port
"label[7.75,-0.25;" .. fgettext("Address / Port") .. "]" ..
"field[8,0.65;3.25,0.5;te_address;;" ..
core.formspec_escape(core.settings:get("address")) .. "]" ..
"field[11.1,0.65;1.4,0.5;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;;" ..
core.formspec_escape(core.settings:get("name")) .. "]" ..
"pwdfield[10.73,1.85;1.77,0.5;te_pwd;]" ..
-- Description Background
"box[7.73,2.25;4.25,2.6;#999999]"..
-- Connect
"button[10.1,5.15;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]"
if tabdata.fav_selected and fav_selected then
if gamedata.fav then
retval = retval .. "button[7.85,4.9;2.3,0.5;btn_delete_favorite;" ..
retval = retval .. "button[7.75,5.15;2.3,0.5;btn_delete_favorite;" ..
fgettext("Del. Favorite") .. "]"
end
if fav_selected.description then
retval = retval .. "textarea[8.1,2.4;4.26,2.6;;" ..
retval = retval .. "textarea[8.1,2.3;4.23,2.9;;" ..
core.formspec_escape((gamedata.serverdescription or ""), true) .. ";]"
end
end
@ -49,6 +69,7 @@ local function get_formspec(tabview, name, tabdata)
--favourites
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;" .. -- "/"
@ -58,9 +79,27 @@ local function get_formspec(tabview, name, tabdata)
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
"color,span=1;" ..
"text,padding=1]" ..
"table[-0.15,-0.1;7.75,5.5;favourites;"
"table[-0.15,0.6;7.75,5.15;favourites;"
if #menudata.favorites > 0 then
if menudata.search_result then
for i = 1, #menudata.search_result do
local favs = core.get_favorites("local")
local server = menudata.search_result[i]
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
if i ~= 1 then
retval = retval .. ","
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
@ -75,9 +114,9 @@ local function get_formspec(tabview, name, tabdata)
end
end
end
retval = retval .. render_favorite(menudata.favorites[1], (#favs > 0))
retval = retval .. render_serverlist_row(menudata.favorites[1], (#favs > 0))
for i = 2, #menudata.favorites do
retval = retval .. "," .. render_favorite(menudata.favorites[i], (i <= #favs))
retval = retval .. "," .. render_serverlist_row(menudata.favorites[i], (i <= #favs))
end
end
@ -92,17 +131,19 @@ end
--------------------------------------------------------------------------------
local function main_button_handler(tabview, fields, name, tabdata)
local serverlist = menudata.search_result or menudata.favorites
if fields.te_name then
gamedata.playername = fields.te_name
core.setting_set("name", 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 = menudata.favorites[event.row]
local fav = serverlist[event.row]
if event.type == "DCL" then
if event.row <= #menudata.favorites 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
@ -122,8 +163,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
gamedata.serverdescription = fav.description
if gamedata.address and gamedata.port then
core.setting_set("address", gamedata.address)
core.setting_set("remote_port", gamedata.port)
core.settings:set("address", gamedata.address)
core.settings:set("remote_port", gamedata.port)
core.start()
end
end
@ -131,7 +172,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
end
if event.type == "CHG" then
if event.row <= #menudata.favorites then
if event.row <= #serverlist then
gamedata.fav = false
local favs = core.get_favorites("local")
local address = fav.address
@ -146,8 +187,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
end
if address and port then
core.setting_set("address", address)
core.setting_set("remote_port", port)
core.settings:set("address", address)
core.settings:set("remote_port", port)
end
tabdata.fav_selected = event.row
end
@ -157,7 +198,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
if fields.key_up or fields.key_down then
local fav_idx = core.get_table_index("favourites")
local fav = menudata.favorites[fav_idx]
local fav = serverlist[fav_idx]
if fav_idx then
if fields.key_up and fav_idx > 1 then
@ -176,10 +217,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
local address = fav.address
local port = fav.port
gamedata.serverdescription = fav.description
if address and port then
core.setting_set("address", address)
core.setting_set("remote_port", port)
core.settings:set("address", address)
core.settings:set("remote_port", port)
end
tabdata.fav_selected = fav_idx
@ -194,21 +235,81 @@ local function main_button_handler(tabview, fields, name, tabdata)
asyncOnlineFavourites()
tabdata.fav_selected = nil
core.setting_set("address", "")
core.setting_set("remote_port", "30000")
core.settings:set("address", "")
core.settings:set("remote_port", "30000")
return true
end
if (fields.btn_mp_connect or fields.key_enter) and fields.te_address and fields.te_port then
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
end
menudata.search_result = {}
-- setup the keyword list
local keywords = {}
for word in input:gmatch("%S+") do
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 name = server.name:lower()
local _, count = name: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)
end
return true
end
if (fields.btn_mp_connect or fields.key_enter)
and fields.te_address ~= "" and fields.te_port then
gamedata.playername = fields.te_name
gamedata.password = fields.te_pwd
gamedata.address = fields.te_address
gamedata.port = fields.te_port
gamedata.selected_world = 0
local fav_idx = core.get_table_index("favourites")
local fav = menudata.favorites[fav_idx]
local fav = serverlist[fav_idx]
if fav_idx and fav_idx <= #menudata.favorites and
if fav_idx and fav_idx <= #serverlist and
fav.address == fields.te_address and
fav.port == fields.te_port then
@ -225,8 +326,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
gamedata.serverdescription = ""
end
core.setting_set("address", fields.te_address)
core.setting_set("remote_port", fields.te_port)
core.settings:set("address", fields.te_address)
core.settings:set("remote_port", fields.te_port)
core.start()
return true
@ -241,8 +342,8 @@ end
--------------------------------------------------------------------------------
return {
name = "multiplayer",
caption = fgettext("Client"),
name = "online",
caption = fgettext("Play Online"),
cbf_formspec = get_formspec,
cbf_button_handler = main_button_handler,
on_change = on_change

@ -1,195 +0,0 @@
--Minetest
--Copyright (C) 2014 sapier
--
--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.
--------------------------------------------------------------------------------
local function get_formspec(tabview, name, tabdata)
local index = menudata.worldlist:get_current_index(
tonumber(core.setting_get("mainmenu_last_selected_world"))
)
local retval =
"button[4,4.15;2.6,0.5;world_delete;" .. fgettext("Delete") .. "]" ..
"button[6.5,4.15;2.8,0.5;world_create;" .. fgettext("New") .. "]" ..
"button[9.2,4.15;2.55,0.5;world_configure;" .. fgettext("Configure") .. "]" ..
"button[8.5,4.95;3.25,0.5;start_server;" .. fgettext("Start Game") .. "]" ..
"label[4,-0.25;" .. fgettext("Select World:") .. "]" ..
"checkbox[0.25,0.25;cb_creative_mode;" .. fgettext("Creative Mode") .. ";" ..
dump(core.setting_getbool("creative_mode")) .. "]" ..
"checkbox[0.25,0.7;cb_enable_damage;" .. fgettext("Enable Damage") .. ";" ..
dump(core.setting_getbool("enable_damage")) .. "]" ..
"checkbox[0.25,1.15;cb_server_announce;" .. fgettext("Public") .. ";" ..
dump(core.setting_getbool("server_announce")) .. "]" ..
"label[0.25,2.2;" .. fgettext("Name/Password") .. "]" ..
"field[0.55,3.2;3.5,0.5;te_playername;;" ..
core.formspec_escape(core.setting_get("name")) .. "]" ..
"pwdfield[0.55,4;3.5,0.5;te_passwd;]"
local bind_addr = core.setting_get("bind_address")
if bind_addr ~= nil and bind_addr ~= "" then
retval = retval ..
"field[0.55,5.2;2.25,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" ..
core.formspec_escape(core.setting_get("bind_address")) .. "]" ..
"field[2.8,5.2;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" ..
core.formspec_escape(core.setting_get("port")) .. "]"
else
retval = retval ..
"field[0.55,5.2;3.5,0.5;te_serverport;" .. fgettext("Server Port") .. ";" ..
core.formspec_escape(core.setting_get("port")) .. "]"
end
retval = retval ..
"textlist[4,0.25;7.5,3.7;srv_worlds;" ..
menu_render_worldlist() ..
";" .. index .. "]"
return retval
end
--------------------------------------------------------------------------------
local function main_button_handler(this, fields, name, tabdata)
local world_doubleclick = false
if fields["srv_worlds"] ~= nil then
local event = core.explode_textlist_event(fields["srv_worlds"])
local selected = core.get_textlist_index("srv_worlds")
menu_worldmt_legacy(selected)
if event.type == "DCL" then
world_doubleclick = true
end
if event.type == "CHG" then
core.setting_set("mainmenu_last_selected_world",
menudata.worldlist:get_raw_index(core.get_textlist_index("srv_worlds")))
return true
end
end
if menu_handle_key_up_down(fields,"srv_worlds","mainmenu_last_selected_world") then
return true
end
if fields["cb_creative_mode"] then
core.setting_set("creative_mode", fields["cb_creative_mode"])
local selected = core.get_textlist_index("srv_worlds")
menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"])
return true
end
if fields["cb_enable_damage"] then
core.setting_set("enable_damage", fields["cb_enable_damage"])
local selected = core.get_textlist_index("srv_worlds")
menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"])
return true
end
if fields["cb_server_announce"] then
core.setting_set("server_announce", fields["cb_server_announce"])
local selected = core.get_textlist_index("srv_worlds")
menu_worldmt(selected, "server_announce", fields["cb_server_announce"])
return true
end
if fields["start_server"] ~= nil or
world_doubleclick or
fields["key_enter"] then
local selected = core.get_textlist_index("srv_worlds")
gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
if selected ~= nil and gamedata.selected_world ~= 0 then
gamedata.playername = fields["te_playername"]
gamedata.password = fields["te_passwd"]
gamedata.port = fields["te_serverport"]
gamedata.address = ""
core.setting_set("port",gamedata.port)
if fields["te_serveraddr"] ~= nil then
core.setting_set("bind_address",fields["te_serveraddr"])
end
--update last game
local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
if world then
local game, index = gamemgr.find_by_gameid(world.gameid)
core.setting_set("menu_last_game", game.id)
end
core.start()
else
gamedata.errormessage =
fgettext("No world created or selected!")
end
return true
end
if fields["world_create"] ~= nil then
local create_world_dlg = create_create_world_dlg(true)
create_world_dlg:set_parent(this)
create_world_dlg:show()
this:hide()
return true
end
if fields["world_delete"] ~= nil then
local selected = core.get_textlist_index("srv_worlds")
if selected ~= nil and
selected <= menudata.worldlist:size() then
local world = menudata.worldlist:get_list()[selected]
if world ~= nil and
world.name ~= nil and
world.name ~= "" then
local index = menudata.worldlist:get_raw_index(selected)
local delete_world_dlg = create_delete_world_dlg(world.name,index)
delete_world_dlg:set_parent(this)
delete_world_dlg:show()
this:hide()
end
end
return true
end
if fields["world_configure"] ~= nil then
local selected = core.get_textlist_index("srv_worlds")
if selected ~= nil then
local configdialog =
create_configure_world_dlg(
menudata.worldlist:get_raw_index(selected))
if (configdialog ~= nil) then
configdialog:set_parent(this)
configdialog:show()
this:hide()
end
end
return true
end
return false
end
--------------------------------------------------------------------------------
return {
name = "server",
caption = fgettext("Server"),
cbf_formspec = get_formspec,
cbf_button_handler = main_button_handler,
on_change = nil
}

@ -25,7 +25,8 @@ local labels = {
},
node_highlighting = {
fgettext("Node Outlining"),
fgettext("Node Highlighting")
fgettext("Node Highlighting"),
fgettext("None")
},
filters = {
fgettext("No Filter"),
@ -52,7 +53,7 @@ local dd_options = {
},
node_highlighting = {
table.concat(labels.node_highlighting, ","),
{"box", "halo"}
{"box", "halo", "none"}
},
filters = {
table.concat(labels.filters, ","),
@ -70,39 +71,39 @@ local dd_options = {
local getSettingIndex = {
Leaves = function()
local style = core.setting_get("leaves_style")
local style = core.settings:get("leaves_style")
for idx, name in pairs(dd_options.leaves[2]) do
if style == name then return idx end
end
return 1
end,
NodeHighlighting = function()
local style = core.setting_get("node_highlighting")
local style = core.settings:get("node_highlighting")
for idx, name in pairs(dd_options.node_highlighting[2]) do
if style == name then return idx end
end
return 1
end,
Filter = function()
if core.setting_get(dd_options.filters[2][3]) == "true" then
if core.settings:get(dd_options.filters[2][3]) == "true" then
return 3
elseif core.setting_get(dd_options.filters[2][3]) == "false" and
core.setting_get(dd_options.filters[2][2]) == "true" then
elseif core.settings:get(dd_options.filters[2][3]) == "false" and
core.settings:get(dd_options.filters[2][2]) == "true" then
return 2
end
return 1
end,
Mipmap = function()
if core.setting_get(dd_options.mipmap[2][3]) == "true" then
if core.settings:get(dd_options.mipmap[2][3]) == "true" then
return 3
elseif core.setting_get(dd_options.mipmap[2][3]) == "false" and
core.setting_get(dd_options.mipmap[2][2]) == "true" then
elseif core.settings:get(dd_options.mipmap[2][3]) == "false" and
core.settings:get(dd_options.mipmap[2][2]) == "true" then
return 2
end
return 1
end,
Antialiasing = function()
local antialiasing_setting = core.setting_get("fsaa")
local antialiasing_setting = core.settings:get("fsaa")
for i = 1, #dd_options.antialiasing[2] do
if antialiasing_setting == dd_options.antialiasing[2][i] then
return i
@ -177,20 +178,20 @@ local function formspec(tabview, name, tabdata)
local tab_string =
"box[0,0;3.5,4.5;#999999]" ..
"checkbox[0.25,0;cb_smooth_lighting;" .. fgettext("Smooth Lighting") .. ";"
.. dump(core.setting_getbool("smooth_lighting")) .. "]" ..
.. dump(core.settings:get_bool("smooth_lighting")) .. "]" ..
"checkbox[0.25,0.5;cb_particles;" .. fgettext("Particles") .. ";"
.. dump(core.setting_getbool("enable_particles")) .. "]" ..
.. dump(core.settings:get_bool("enable_particles")) .. "]" ..
"checkbox[0.25,1;cb_3d_clouds;" .. fgettext("3D Clouds") .. ";"
.. dump(core.setting_getbool("enable_3d_clouds")) .. "]" ..
.. dump(core.settings:get_bool("enable_3d_clouds")) .. "]" ..
"checkbox[0.25,1.5;cb_opaque_water;" .. fgettext("Opaque Water") .. ";"
.. dump(core.setting_getbool("opaque_water")) .. "]" ..
.. dump(core.settings:get_bool("opaque_water")) .. "]" ..
"checkbox[0.25,2.0;cb_connected_glass;" .. fgettext("Connected Glass") .. ";"
.. dump(core.setting_getbool("connected_glass")) .. "]" ..
.. dump(core.settings:get_bool("connected_glass")) .. "]" ..
"dropdown[0.25,2.8;3.3;dd_node_highlighting;" .. dd_options.node_highlighting[1] .. ";"
.. getSettingIndex.NodeHighlighting() .. "]" ..
"dropdown[0.25,3.6;3.3;dd_leaves_style;" .. dd_options.leaves[1] .. ";"
.. getSettingIndex.Leaves() .. "]" ..
"box[3.75,0;3.75,3.45;#999999]" ..
"box[3.75,0;3.75,4.45;#999999]" ..
"label[3.85,0.1;" .. fgettext("Texturing:") .. "]" ..
"dropdown[3.85,0.55;3.85;dd_filters;" .. dd_options.filters[1] .. ";"
.. getSettingIndex.Filter() .. "]" ..
@ -199,9 +200,12 @@ local function formspec(tabview, name, tabdata)
"label[3.85,2.15;" .. fgettext("Antialiasing:") .. "]" ..
"dropdown[3.85,2.6;3.85;dd_antialiasing;" .. dd_options.antialiasing[1] .. ";"
.. getSettingIndex.Antialiasing() .. "]" ..
"label[3.85,3.45;" .. fgettext("Screen:") .. "]" ..
"checkbox[3.85,3.6;cb_autosave_screensize;" .. fgettext("Autosave screen size") .. ";"
.. dump(core.settings:get_bool("autosave_screensize")) .. "]" ..
"box[7.75,0;4,4.4;#999999]" ..
"checkbox[8,0;cb_shaders;" .. fgettext("Shaders") .. ";"
.. dump(core.setting_getbool("enable_shaders")) .. "]"
.. dump(core.settings:get_bool("enable_shaders")) .. "]"
if PLATFORM == "Android" then
tab_string = tab_string ..
@ -209,38 +213,38 @@ local function formspec(tabview, name, tabdata)
.. fgettext("Reset singleplayer world") .. "]"
else
tab_string = tab_string ..
"button[8,4.75;3.75,0.5;btn_change_keys;"
"button[8,4.85;3.75,0.5;btn_change_keys;"
.. fgettext("Change keys") .. "]"
end
tab_string = tab_string ..
"button[0,4.75;3.75,0.5;btn_advanced_settings;"
"button[0,4.85;3.75,0.5;btn_advanced_settings;"
.. fgettext("Advanced Settings") .. "]"
if core.setting_get("touchscreen_threshold") ~= nil then
if core.settings:get("touchscreen_threshold") ~= nil then
tab_string = tab_string ..
"label[4.3,4.1;" .. fgettext("Touchthreshold (px)") .. "]" ..
"dropdown[3.85,4.55;3.85;dd_touchthreshold;0,10,20,30,40,50;" ..
((tonumber(core.setting_get("touchscreen_threshold")) / 10) + 1) .. "]"
((tonumber(core.settings:get("touchscreen_threshold")) / 10) + 1) .. "]"
end
if core.setting_getbool("enable_shaders") then
if core.settings:get_bool("enable_shaders") then
tab_string = tab_string ..
"checkbox[8,0.5;cb_bumpmapping;" .. fgettext("Bump Mapping") .. ";"
.. dump(core.setting_getbool("enable_bumpmapping")) .. "]" ..
.. dump(core.settings:get_bool("enable_bumpmapping")) .. "]" ..
"checkbox[8,1;cb_tonemapping;" .. fgettext("Tone Mapping") .. ";"
.. dump(core.setting_getbool("tone_mapping")) .. "]" ..
.. dump(core.settings:get_bool("tone_mapping")) .. "]" ..
"checkbox[8,1.5;cb_generate_normalmaps;" .. fgettext("Normal Mapping") .. ";"
.. dump(core.setting_getbool("generate_normalmaps")) .. "]" ..
.. dump(core.settings:get_bool("generate_normalmaps")) .. "]" ..
"checkbox[8,2;cb_parallax;" .. fgettext("Parallax Occlusion") .. ";"
.. dump(core.setting_getbool("enable_parallax_occlusion")) .. "]" ..
.. dump(core.settings:get_bool("enable_parallax_occlusion")) .. "]" ..
"checkbox[8,2.5;cb_waving_water;" .. fgettext("Waving Water") .. ";"
.. dump(core.setting_getbool("enable_waving_water")) .. "]" ..
.. dump(core.settings:get_bool("enable_waving_water")) .. "]" ..
"checkbox[8,3;cb_waving_leaves;" .. fgettext("Waving Leaves") .. ";"
.. dump(core.setting_getbool("enable_waving_leaves")) .. "]" ..
.. dump(core.settings:get_bool("enable_waving_leaves")) .. "]" ..
"checkbox[8,3.5;cb_waving_plants;" .. fgettext("Waving Plants") .. ";"
.. dump(core.setting_getbool("enable_waving_plants")) .. "]"
.. dump(core.settings:get_bool("enable_waving_plants")) .. "]"
else
tab_string = tab_string ..
"tablecolumns[color;text]" ..
@ -271,60 +275,64 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
return true
end
if fields["cb_smooth_lighting"] then
core.setting_set("smooth_lighting", fields["cb_smooth_lighting"])
core.settings:set("smooth_lighting", fields["cb_smooth_lighting"])
return true
end
if fields["cb_particles"] then
core.setting_set("enable_particles", fields["cb_particles"])
core.settings:set("enable_particles", fields["cb_particles"])
return true
end
if fields["cb_3d_clouds"] then
core.setting_set("enable_3d_clouds", fields["cb_3d_clouds"])
core.settings:set("enable_3d_clouds", fields["cb_3d_clouds"])
return true
end
if fields["cb_opaque_water"] then
core.setting_set("opaque_water", fields["cb_opaque_water"])
core.settings:set("opaque_water", fields["cb_opaque_water"])
return true
end
if fields["cb_connected_glass"] then
core.setting_set("connected_glass", fields["cb_connected_glass"])
core.settings:set("connected_glass", fields["cb_connected_glass"])
return true
end
if fields["cb_autosave_screensize"] then
core.settings:set("autosave_screensize", fields["cb_autosave_screensize"])
return true
end
if fields["cb_shaders"] then
if (core.setting_get("video_driver") == "direct3d8" or
core.setting_get("video_driver") == "direct3d9") then
core.setting_set("enable_shaders", "false")
if (core.settings:get("video_driver") == "direct3d8" or
core.settings:get("video_driver") == "direct3d9") then
core.settings:set("enable_shaders", "false")
gamedata.errormessage = fgettext("To enable shaders the OpenGL driver needs to be used.")
else
core.setting_set("enable_shaders", fields["cb_shaders"])
core.settings:set("enable_shaders", fields["cb_shaders"])
end
return true
end
if fields["cb_bumpmapping"] then
core.setting_set("enable_bumpmapping", fields["cb_bumpmapping"])
core.settings:set("enable_bumpmapping", fields["cb_bumpmapping"])
return true
end
if fields["cb_tonemapping"] then
core.setting_set("tone_mapping", fields["cb_tonemapping"])
core.settings:set("tone_mapping", fields["cb_tonemapping"])
return true
end
if fields["cb_generate_normalmaps"] then
core.setting_set("generate_normalmaps", fields["cb_generate_normalmaps"])
core.settings:set("generate_normalmaps", fields["cb_generate_normalmaps"])
return true
end
if fields["cb_parallax"] then
core.setting_set("enable_parallax_occlusion", fields["cb_parallax"])
core.settings:set("enable_parallax_occlusion", fields["cb_parallax"])
return true
end
if fields["cb_waving_water"] then
core.setting_set("enable_waving_water", fields["cb_waving_water"])
core.settings:set("enable_waving_water", fields["cb_waving_water"])
return true
end
if fields["cb_waving_leaves"] then
core.setting_set("enable_waving_leaves", fields["cb_waving_leaves"])
core.settings:set("enable_waving_leaves", fields["cb_waving_leaves"])
end
if fields["cb_waving_plants"] then
core.setting_set("enable_waving_plants", fields["cb_waving_plants"])
core.settings:set("enable_waving_plants", fields["cb_waving_plants"])
return true
end
if fields["btn_change_keys"] then
@ -332,7 +340,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
return true
end
if fields["cb_touchscreen_target"] then
core.setting_set("touchtarget", fields["cb_touchscreen_target"])
core.settings:set("touchtarget", fields["cb_touchscreen_target"])
return true
end
if fields["btn_reset_singleplayer"] then
@ -345,49 +353,49 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
for i = 1, #labels.leaves do
if fields["dd_leaves_style"] == labels.leaves[i] then
core.setting_set("leaves_style", dd_options.leaves[2][i])
core.settings:set("leaves_style", dd_options.leaves[2][i])
ddhandled = true
end
end
for i = 1, #labels.node_highlighting do
if fields["dd_node_highlighting"] == labels.node_highlighting[i] then
core.setting_set("node_highlighting", dd_options.node_highlighting[2][i])
core.settings:set("node_highlighting", dd_options.node_highlighting[2][i])
ddhandled = true
end
end
if fields["dd_filters"] == labels.filters[1] then
core.setting_set("bilinear_filter", "false")
core.setting_set("trilinear_filter", "false")
core.settings:set("bilinear_filter", "false")
core.settings:set("trilinear_filter", "false")
ddhandled = true
elseif fields["dd_filters"] == labels.filters[2] then
core.setting_set("bilinear_filter", "true")
core.setting_set("trilinear_filter", "false")
core.settings:set("bilinear_filter", "true")
core.settings:set("trilinear_filter", "false")
ddhandled = true
elseif fields["dd_filters"] == labels.filters[3] then
core.setting_set("bilinear_filter", "false")
core.setting_set("trilinear_filter", "true")
core.settings:set("bilinear_filter", "false")
core.settings:set("trilinear_filter", "true")
ddhandled = true
end
if fields["dd_mipmap"] == labels.mipmap[1] then
core.setting_set("mip_map", "false")
core.setting_set("anisotropic_filter", "false")
core.settings:set("mip_map", "false")
core.settings:set("anisotropic_filter", "false")
ddhandled = true
elseif fields["dd_mipmap"] == labels.mipmap[2] then
core.setting_set("mip_map", "true")
core.setting_set("anisotropic_filter", "false")
core.settings:set("mip_map", "true")
core.settings:set("anisotropic_filter", "false")
ddhandled = true
elseif fields["dd_mipmap"] == labels.mipmap[3] then
core.setting_set("mip_map", "true")
core.setting_set("anisotropic_filter", "true")
core.settings:set("mip_map", "true")
core.settings:set("anisotropic_filter", "true")
ddhandled = true
end
if fields["dd_antialiasing"] then
core.setting_set("fsaa",
core.settings:set("fsaa",
antialiasing_fname_to_name(fields["dd_antialiasing"]))
ddhandled = true
end
if fields["dd_touchthreshold"] then
core.setting_set("touchscreen_threshold", fields["dd_touchthreshold"])
core.settings:set("touchscreen_threshold", fields["dd_touchthreshold"])
ddhandled = true
end

@ -25,12 +25,12 @@ local function get_formspec(tabview, name, tabdata)
local retval =
"label[9.5,0;".. fgettext("Name / Password") .. "]" ..
"field[0.25,3.35;5.5,0.5;te_address;;" ..
core.formspec_escape(core.setting_get("address")) .."]" ..
core.formspec_escape(core.settings:get("address")) .."]" ..
"field[5.75,3.35;2.25,0.5;te_port;;" ..
core.formspec_escape(core.setting_get("remote_port")) .."]" ..
core.formspec_escape(core.settings:get("remote_port")) .."]" ..
"button[10,2.6;2,1.5;btn_mp_connect;".. fgettext("Connect") .. "]" ..
"field[9.8,1;2.6,0.5;te_name;;" ..
core.formspec_escape(core.setting_get("name")) .."]" ..
core.formspec_escape(core.settings:get("name")) .."]" ..
"pwdfield[9.8,2;2.6,0.5;te_pwd;]"
@ -43,6 +43,7 @@ local function get_formspec(tabview, name, tabdata)
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;" .. -- "/"
@ -70,9 +71,9 @@ local function get_formspec(tabview, name, tabdata)
end
end
end
retval = retval .. render_favorite(menudata.favorites[1], (#favs > 0))
retval = retval .. render_serverlist_row(menudata.favorites[1], (#favs > 0))
for i = 2, #menudata.favorites do
retval = retval .. "," .. render_favorite(menudata.favorites[i], (i <= #favs))
retval = retval .. "," .. render_serverlist_row(menudata.favorites[i], (i <= #favs))
end
end
@ -88,9 +89,9 @@ local function get_formspec(tabview, name, tabdata)
-- checkboxes
retval = retval ..
"checkbox[8.0,3.9;cb_creative;".. fgettext("Creative Mode") .. ";" ..
dump(core.setting_getbool("creative_mode")) .. "]"..
dump(core.settings:get_bool("creative_mode")) .. "]"..
"checkbox[8.0,4.4;cb_damage;".. fgettext("Enable Damage") .. ";" ..
dump(core.setting_getbool("enable_damage")) .. "]"
dump(core.settings:get_bool("enable_damage")) .. "]"
-- buttons
retval = retval ..
"button[0,3.7;8,1.5;btn_start_singleplayer;" .. fgettext("Start Singleplayer") .. "]" ..
@ -127,8 +128,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
end
if address and port then
core.setting_set("address", address)
core.setting_set("remote_port", port)
core.settings:set("address", address)
core.settings:set("remote_port", port)
end
tabdata.fav_selected = event.row
end
@ -144,18 +145,18 @@ local function main_button_handler(tabview, fields, name, tabdata)
asyncOnlineFavourites()
tabdata.fav_selected = nil
core.setting_set("address", "")
core.setting_set("remote_port", "30000")
core.settings:set("address", "")
core.settings:set("remote_port", "30000")
return true
end
if fields.cb_creative then
core.setting_set("creative_mode", fields.cb_creative)
core.settings:set("creative_mode", fields.cb_creative)
return true
end
if fields.cb_damage then
core.setting_set("enable_damage", fields.cb_damage)
core.settings:set("enable_damage", fields.cb_damage)
return true
end
@ -185,12 +186,12 @@ local function main_button_handler(tabview, fields, name, tabdata)
gamedata.selected_world = 0
core.setting_set("address", fields.te_address)
core.setting_set("remote_port", fields.te_port)
core.start()
return true
end
core.settings:set("address", fields.te_address)
core.settings:set("remote_port", fields.te_port)
core.start()
return true
end
if fields.btn_config_sp_world then
local configdialog = create_configure_world_dlg(1)

@ -54,9 +54,9 @@ local function get_formspec(tabview, name, tabdata)
local retval = "label[4,-0.25;" .. fgettext("Select texture pack:") .. "]" ..
"textlist[4,0.25;7.5,5.0;TPs;"
local current_texture_path = core.setting_get("texture_path")
local current_texture_path = core.settings:get("texture_path")
local list = filter_texture_pack_list(core.get_dir_list(core.get_texturepath(), true))
local index = tonumber(core.setting_get("mainmenu_last_selected_TP"))
local index = tonumber(core.settings:get("mainmenu_last_selected_TP"))
if not index then index = 1 end
@ -106,7 +106,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
local event = core.explode_textlist_event(fields["TPs"])
if event.type == "CHG" or event.type == "DCL" then
local index = core.get_textlist_index("TPs")
core.setting_set("mainmenu_last_selected_TP", index)
core.settings:set("mainmenu_last_selected_TP", index)
local list = filter_texture_pack_list(core.get_dir_list(core.get_texturepath(), true))
local current_index = core.get_textlist_index("TPs")
if current_index and #list >= current_index then
@ -114,7 +114,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
if list[current_index] == fgettext("None") then
new_path = ""
end
core.setting_set("texture_path", new_path)
core.settings:set("texture_path", new_path)
end
end
return true

@ -24,7 +24,7 @@ function mm_texture.init()
DIR_DELIM .. "pack" .. DIR_DELIM
mm_texture.basetexturedir = mm_texture.defaulttexturedir
mm_texture.texturepack = core.setting_get("texture_path")
mm_texture.texturepack = core.settings:get("texture_path")
mm_texture.gameid = nil
end
@ -61,7 +61,7 @@ function mm_texture.reset()
mm_texture.set_generic("header")
if not have_bg then
if core.setting_getbool("menu_clouds") then
if core.settings:get_bool("menu_clouds") then
core.set_clouds(true)
else
mm_texture.set_dirt_bg()
@ -88,7 +88,7 @@ function mm_texture.update_game(gamedetails)
if not have_bg then
if core.setting_getbool("menu_clouds") then
if core.settings:get_bool("menu_clouds") then
core.set_clouds(true)
else
mm_texture.set_dirt_bg()

@ -15,10 +15,18 @@
--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_bool_default(name, default)
local val = core.settings:get_bool(name)
if val == nil then
return default
end
return val
end
local profiler_path = core.get_builtin_path()..DIR_DELIM.."profiler"..DIR_DELIM
local profiler = {}
local sampler = assert(loadfile(profiler_path .. "sampling.lua"))(profiler)
local instrumentation = assert(loadfile(profiler_path .. "instrumentation.lua"))(profiler, sampler)
local instrumentation = assert(loadfile(profiler_path .. "instrumentation.lua"))(profiler, sampler, get_bool_default)
local reporter = dofile(profiler_path .. "reporter.lua")
profiler.instrument = instrumentation.instrument
@ -27,7 +35,7 @@ profiler.instrument = instrumentation.instrument
-- Is called later, after `core.register_chatcommand` was set up.
--
function profiler.init_chatcommand()
local instrument_profiler = core.setting_getbool("instrument.profiler") or false
local instrument_profiler = get_bool_default("instrument.profiler", false)
if instrument_profiler then
instrumentation.init_chatcommand()
end

@ -17,8 +17,9 @@
local format, pairs, type = string.format, pairs, type
local core, get_current_modname = core, core.get_current_modname
local profiler, sampler = ...
local instrument_builtin = core.setting_getbool("instrument.builtin") or false
local profiler, sampler, get_bool_default = ...
local instrument_builtin = get_bool_default("instrument.builtin", false)
local register_functions = {
register_globalstep = 0,
@ -137,7 +138,7 @@ local function instrument_register(func, func_name)
end
local function init_chatcommand()
if core.setting_getbool("instrument.chatcommand") or true then
if get_bool_default("instrument.chatcommand", true) then
local orig_register_chatcommand = core.register_chatcommand
core.register_chatcommand = function(cmd, def)
def.func = instrument {
@ -153,8 +154,7 @@ end
-- Start instrumenting selected functions
--
local function init()
local is_set = core.setting_getbool
if is_set("instrument.entity") or true then
if get_bool_default("instrument.entity", true) then
-- Explicitly declare entity api-methods.
-- Simple iteration would ignore lookup via __index.
local entity_instrumentation = {
@ -180,7 +180,7 @@ local function init()
end
end
if is_set("instrument.abm") or true then
if get_bool_default("instrument.abm", true) then
-- Wrap register_abm() to automatically instrument abms.
local orig_register_abm = core.register_abm
core.register_abm = function(spec)
@ -193,7 +193,7 @@ local function init()
end
end
if is_set("instrument.lbm") or true then
if get_bool_default("instrument.lbm", true) then
-- Wrap register_lbm() to automatically instrument lbms.
local orig_register_lbm = core.register_lbm
core.register_lbm = function(spec)
@ -206,13 +206,13 @@ local function init()
end
end
if is_set("instrument.global_callback") or true then
if get_bool_default("instrument.global_callback", true) then
for func_name, _ in pairs(register_functions) do
core[func_name] = instrument_register(core[func_name], func_name)
end
end
if is_set("instrument.profiler") or false then
if get_bool_default("instrument.profiler", false) then
-- Measure overhead of instrumentation, but keep it down for functions
-- So keep the `return` for better optimization.
profiler.empty_instrument = instrument {

@ -18,7 +18,7 @@
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
local core, setting_get = core, core.setting_get
local core, settings = core, core.settings
local reporter = {}
---
@ -229,7 +229,7 @@ end
local worldpath = core.get_worldpath()
local function get_save_path(format, filter)
local report_path = setting_get("profiler.report_path") or ""
local report_path = settings:get("profiler.report_path") or ""
if report_path ~= "" then
core.mkdir(sprintf("%s%s%s", worldpath, DIR_DELIM, report_path))
end
@ -249,7 +249,7 @@ end
--
function reporter.save(profile, format, filter)
if not format or format == "" then
format = setting_get("profiler.default_report_format") or "txt"
format = settings:get("profiler.default_report_format") or "txt"
end
if filter == "" then
filter = nil

@ -185,7 +185,7 @@ end
function sampler.init()
sampler.reset()
if core.setting_getbool("instrument.profiler") then
if core.settings:get_bool("instrument.profiler") then
core.register_globalstep(function()
if logged_time == 0 then
return

@ -107,6 +107,12 @@ continuous_forward (Continuous forward) bool false
# Enable Joysticks
enable_joysticks (Enable Joysticks) bool false
# The identifier of the joystick to use
joystick_id (Joystick ID) int 0
# The type of joystick
joystick_type (Joystick Type) enum auto auto,generic,xbox
# The time in seconds it takes between repeated events
# when holding down a joystick button combination.
repeat_joystick_button_time (Joystick button repetition interval) float 0.17
@ -156,6 +162,10 @@ keymap_chat (Chat key) key KEY_KEY_T
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_cmd (Command key) key /
# Key for opening the chat window to type local commands.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_cmd_local (Command key) key .
# Key for opening the chat console.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keyman_console (Console key) key KEY_F10
@ -176,6 +186,26 @@ keymap_fastmove (Fast key) key KEY_KEY_J
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_noclip (Noclip key) key KEY_KEY_H
# Key for selecting the next item in the hotbar.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_hotbar_next (Hotbar next key) key KEY_KEY_N
# Key for selecting the previous item in the hotbar.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_hotbar_previous (Hotbar previous key) key KEY_KEY_B
# Key for muting the game.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_mute (Mute key) key KEY_KEY_M
# Key for increasing the volume.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_increase_volume (Inc. volume key) key
# Key for decreasing the volume.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_decrease_volume (Dec. volume key) key
# Key for toggling autorun.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_autorun (Autorun key) key
@ -196,6 +226,10 @@ keymap_screenshot (Screenshot) key KEY_F12
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_drop (Drop item key) key KEY_KEY_Q
# Key to use view zoom when possible.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_zoom (View zoom key) key KEY_KEY_Z
# Key for toggling the display of the HUD.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_toggle_hud (HUD toggle key) key KEY_F1
@ -204,6 +238,10 @@ keymap_toggle_hud (HUD toggle key) key KEY_F1
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_toggle_chat (Chat toggle key) key KEY_F2
# Key for toggling the display of the large chat console.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_console (Large chat console key) key KEY_F10
# Key for toggling the display of the fog.
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
keymap_toggle_force_fog_off (Fog toggle key) key KEY_F3
@ -264,12 +302,19 @@ show_entity_selectionbox (Show entity selection boxes) bool true
# when connecting to the server.
enable_remote_media_server (Connect to external media server) bool true
# Enable Lua modding support on client.
# This support is experimental and API can change.
enable_client_modding (Client modding) bool false
# URL to the server list displayed in the Multiplayer Tab.
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
# Maximum size of the out chat queue. 0 to disable queueing and -1 to make the queue size unlimited
max_out_chat_queue_size (Maximum size of the out chat queue) int 20
[*Graphics]
[**In-Game]
@ -302,7 +347,10 @@ enable_clouds (Clouds) bool true
enable_3d_clouds (3D clouds) bool true
# Method used to highlight selected object.
node_highlighting (Node highlighting) enum box box,halo
node_highlighting (Node highlighting) enum box box,halo,none
# Adds particles when digging a node.
enable_particles (Digging particles) bool true
[***Filtering]
@ -337,12 +385,20 @@ texture_min_size (Minimum texture size for filters) int 64
# when set to higher number than 0.
fsaa (FSAA) enum 0 0,1,2,4,8,16
# Undersampling is similar to using lower screen resolution, but it applies
# to the game world only, keeping the GUI intact.
# It should give significant performance boost at the cost of less detailed image.
undersampling (Undersampling) enum 0 0,2,3,4
[***Shaders]
# Shaders allow advanced visual effects and may increase performance on some video cards.
# Thy only work with the OpenGL video backend.
# This only works with the OpenGL video backend.
enable_shaders (Shaders) bool true
# Path to shader directory. If no path is defined, default location will be used.
shader_path (Shader path) path
[****Tone Mapping]
# Enables filmic tone mapping
@ -377,7 +433,7 @@ enable_parallax_occlusion (Parallax occlusion) bool false
parallax_occlusion_mode (Parallax occlusion mode) int 1 0 1
# Strength of parallax.
3d_parallax_strength (Parallax occlusion strength) float 0.025
3d_paralax_strength (Parallax occlusion strength) float 0.025
# Number of parallax occlusion iterations.
parallax_occlusion_iterations (Parallax occlusion iterations) int 4
@ -426,6 +482,9 @@ screenW (Screen width) int 800
# Height component of the initial window size.
screenH (Screen height) int 600
# Save window size automatically when modified.
autosave_screensize (Autosave Screen Size) bool true
# Fullscreen mode.
fullscreen (Full screen) bool false
@ -440,11 +499,11 @@ fov (Field of view) int 72 30 160
# Field of view while zooming in degrees.
# This requires the "zoom" privilege on the server.
zoom_fov (Field of view for zoom) int 15 15 160
zoom_fov (Field of view for zoom) int 15 7 160
# Adjust the gamma encoding for the light tables. Lower numbers are brighter.
# Adjust the gamma encoding for the light tables. Higher numbers are brighter.
# This setting is for the client only and is ignored by the server.
display_gamma (Gamma) float 1.8 1.0 3.0
display_gamma (Gamma) float 2.2 1.0 3.0
# Path to texture directory. All textures are first searched from here.
texture_path (Texture path) path
@ -459,13 +518,13 @@ cloud_height (Cloud height) int 120
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
cloud_radius (Cloud radius) int 12
# Multiplier for view bobbing.
# Enable view bobbing and amount of view bobbing.
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
view_bobbing_amount (View bobbing) float 1.0
view_bobbing_amount (View bobbing factor) float 1.0
# Multiplier for fall bobbing.
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
fall_bobbing_amount (Fall bobbing) float 0.0
fall_bobbing_amount (Fall bobbing factor) float 0.0
# 3D support.
# Currently supported:
@ -477,6 +536,9 @@ fall_bobbing_amount (Fall bobbing) float 0.0
# - pageflip: quadbuffer based 3d.
3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,pageflip
# In-game chat console height, between 0.1 (10%) and 1.0 (100%).
console_height (Console height) float 1.0 0.1 1.0
# In-game chat console background color (R,G,B).
console_color (Console color) string (0,0,0)
@ -502,9 +564,21 @@ desynchronize_mapblock_texture_animation (Desynchronize block animation) bool tr
# Useful if there's something to be displayed right or left of hotbar.
hud_hotbar_max_width (Maximum hotbar width) float 1.0
# Modifies the size of the hudbar elements.
hud_scaling (HUD scale factor) float 1.0
# Enables caching of facedir rotated meshes.
enable_mesh_cache (Mesh cache) bool false
# Delay between mesh updates on the client in ms. Increasing this will slow
# down the rate of mesh updates, thus reducing jitter on slower clients.
mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50
# Size of the MapBlock cache of the mesh generator. Increasing this will
# increase the cache hit %, reducing the data being copied from the main
# thread, thus reducing jitter.
meshgen_block_cache_size (Mapblock mesh generator's MapBlock cache size MB) int 20 0 1000
# Enables minimap.
enable_minimap (Minimap) bool true
@ -528,9 +602,16 @@ ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0
# Enables animation of inventory items.
inventory_items_animations (Inventory items animations) bool false
# Android systems only: Tries to create inventory textures from meshes
# when no supported render was found.
inventory_image_hack (Inventory image hack) bool false
# Fraction of the visible distance at which fog starts to be rendered
fog_start (Fog Start) float 0.4 0.0 0.99
# Makes all liquids opaque
opaque_water (Opaque liquids) bool false
[**Menus]
# Use a cloud animation for the main menu background.
@ -597,6 +678,10 @@ screenshot_quality (Screenshot quality) int 0 0 100
# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens.
screen_dpi (DPI) int 72
# Windows systems only: Start Minetest with the command line window in the background.
# Contains the same information as the file debug.txt (default name).
enable_console (Enable console window) bool false
[*Sound]
enable_sound (Sound) bool true
@ -703,9 +788,15 @@ map-dir (Map directory) path
# Setting it to -1 disables the feature.
item_entity_ttl (Item entity TTL) int 900
# If enabled, show the server status message on player connection.
show_statusline_on_connect (Status message on connection) bool true
# Enable players getting damage and dying.
enable_damage (Damage) bool false
# Enable creative mode for new created maps.
creative_mode (Creative) bool false
# A chosen map seed for a new map, leave empty for random.
# Will be overridden when creating a new world in the main menu.
fixed_map_seed (Fixed map seed) string
@ -758,7 +849,7 @@ active_object_send_range_blocks (Active object send range) int 3
# How large area of blocks are subject to the active block stuff, stated in mapblocks (16 nodes).
# In active blocks objects are loaded and ABMs run.
active_block_range (Active block range) int 2
active_block_range (Active block range) int 3
# From how far blocks are sent to clients, stated in mapblocks (16 nodes).
max_block_send_distance (Max block send distance) int 10
@ -793,9 +884,8 @@ movement_acceleration_fast (Fast mode acceleration) float 10
movement_speed_walk (Walking speed) float 4
movement_speed_crouch (Crouch speed) float 1.35
movement_speed_fast (Fast mode speed) float 20
movement_speed_climb (Climbing speed) float 2
movement_speed_climb (Climbing speed) float 3
movement_speed_jump (Jumping speed) float 6.5
movement_speed_descend (Descending speed) float 6
movement_liquid_fluidity (Liquid fluidity) float 1
movement_liquid_fluidity_smooth (Liquid fluidity smoothing) float 0.5
movement_liquid_sink (Liquid sink) float 10
@ -834,7 +924,7 @@ active_block_mgmt_interval (Active Block Management interval) float 2.0
abm_interval (Active Block Modifier interval) float 1.0
# Length of time between NodeTimer execution cycles
nodetimer_interval (NodeTimer interval) float 1.0
nodetimer_interval (NodeTimer interval) float 0.2
# If enabled, invalid world data won't cause the server to shut down.
# Only enable this if you know what you are doing.
@ -858,6 +948,12 @@ liquid_update (Liquid update tick) float 1.0
# Stated in mapblocks (16 nodes)
block_send_optimize_distance (block send optimize distance) int 4 2
# If enabled the server will perform map block occlusion culling based on
# on the eye position of the player. This can reduce the number of blocks
# sent to the client 50-80%. The client will not longer receive most invisible
# so that the utility of noclip mode is reduced.
server_side_occlusion_culling (Server side occlusion culling) bool true
[*Mapgen]
# Name of map generator to be used when creating a new world.
@ -870,13 +966,10 @@ water_level (Water level) int 1
# From how far blocks are generated for clients, stated in mapblocks (16 nodes).
max_block_generate_distance (Max block generate distance) int 6
# Where the map generator stops.
# Please note:
# - Limited to 31000 (setting above has no effect)
# - The map generator works in groups of 80x80x80 nodes (5x5x5 MapBlocks).
# - Those groups have an offset of -32, -32 nodes from the origin.
# - Only groups which are within the map_generation_limit are generated
map_generation_limit (Map generation limit) int 31000 0 31000
# Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).
# Only mapchunks completely within the mapgen limit are generated.
# Value is stored per-world.
mapgen_limit (Map generation limit) int 31000 0 31000
# Global map generation attributes.
# In Mapgen v6 the 'decorations' flag controls all decorations except trees
@ -909,23 +1002,63 @@ emergequeue_limit_generate (Limit of emerge queues to generate) int 32
# at the cost of slightly buggy caves.
num_emerge_threads (Number of emerge threads) int 1
# Noise parameters for biome API temperature, humidity and biome blend.
mg_biome_np_heat (Mapgen biome heat noise parameters) noise_params 50, 50, (750, 750, 750), 5349, 3, 0.5, 2.0
mg_biome_np_heat_blend (Mapgen heat blend noise parameters) noise_params 0, 1.5, (8, 8, 8), 13, 2, 1.0, 2.0
mg_biome_np_humidity (Mapgen biome humidity noise parameters) noise_params 50, 50, (750, 750, 750), 842, 3, 0.5, 2.0
mg_biome_np_humidity_blend (Mapgen biome humidity blend noise parameters) noise_params 0, 1.5, (8, 8, 8), 90003, 2, 1.0, 2.0
[***Biome API temperature and humidity noise parameters]
# Temperature variation for biomes.
mg_biome_np_heat (Heat noise) noise_params 50, 50, (1000, 1000, 1000), 5349, 3, 0.5, 2.0
# Small-scale temperature variation for blending biomes on borders.
mg_biome_np_heat_blend (Heat blend noise) noise_params 0, 1.5, (8, 8, 8), 13, 2, 1.0, 2.0
# Humidity variation for biomes.
mg_biome_np_humidity (Humidity noise) noise_params 50, 50, (1000, 1000, 1000), 842, 3, 0.5, 2.0
# Small-scale humidity variation for blending biomes on borders.
mg_biome_np_humidity_blend (Humidity blend noise) noise_params 0, 1.5, (8, 8, 8), 90003, 2, 1.0, 2.0
[***Mapgen v5]
# Controls width of tunnels, a smaller value creates wider tunnels.
mgv5_cave_width (Mapgen v5 cave width) float 0.125
# Map generation attributes specific to Mapgen v5.
# Flags that are not specified in the flag string are not modified from the default.
# Flags starting with 'no' are used to explicitly disable them.
mgv5_spflags (Mapgen v5 specific flags) flags caverns caverns,nocaverns
# Controls width of tunnels, a smaller value creates wider tunnels.
mgv5_cave_width (Cave width) float 0.125
# Y-level of cavern upper limit.
mgv5_cavern_limit (Cavern limit) int -256
# Y-distance over which caverns expand to full size.
mgv5_cavern_taper (Cavern taper) int 256
# Defines full size of caverns, smaller values create larger caverns.
mgv5_cavern_threshold (Cavern threshold) float 0.7
# Variation of biome filler depth.
mgv5_np_filler_depth (Filler depth noise) noise_params 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0
# Variation of terrain vertical scale.
# When noise is < -0.55 terrain is near-flat.
mgv5_np_factor (Factor noise) noise_params 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0
# Y-level of average terrain surface.
mgv5_np_height (Height noise) noise_params 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0
# First of 2 3D noises that together define tunnels.
mgv5_np_cave1 (Cave1 noise) noise_params 0, 12, (50, 50, 50), 52534, 4, 0.5, 2.0
# Second of 2 3D noises that together define tunnels.
mgv5_np_cave2 (Cave2 noise) noise_params 0, 12, (50, 50, 50), 10325, 4, 0.5, 2.0
# 3D noise defining giant caverns.
mgv5_np_cavern (Cavern noise) noise_params 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0
mgv5_np_filler_depth (Mapgen v5 filler depth noise parameters) noise_params 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0
mgv5_np_factor (Mapgen v5 factor noise parameters) noise_params 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0
mgv5_np_height (Mapgen v5 height noise parameters) noise_params 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0
mgv5_np_cave1 (Mapgen v5 cave1 noise parameters) noise_params 0, 12, (50, 50, 50), 52534, 4, 0.5, 2.0
mgv5_np_cave2 (Mapgen v5 cave2 noise parameters) noise_params 0, 12, (50, 50, 50), 10325, 4, 0.5, 2.0
# TODO
# Noise parameters in group format, unsupported by advanced settings
# menu but settable in minetest.conf.
# See documentation of noise parameter formats in minetest.conf.example.
# 3D noise defining terrain.
#mgv5_np_ground = {
# offset = 0
# scale = 40
@ -940,27 +1073,52 @@ mgv5_np_cave2 (Mapgen v5 cave2 noise parameters) noise_params 0, 12, (50, 50, 50
[***Mapgen v6]
# Map generation attributes specific to Mapgen v6.
# When snowbiomes are enabled jungles are automatically enabled, the 'jungles' flag is ignored.
# The 'snowbiomes' flag enables the new 5 biome system.
# When the new biome system is enabled jungles are automatically enabled and
# the 'jungles' flag is ignored.
# Flags that are not specified in the flag string are not modified from the default.
# Flags starting with 'no' are used to explicitly disable them.
mgv6_spflags (Mapgen v6 flags) flags jungles,biomeblend,mudflow,snowbiomes,trees jungles,biomeblend,mudflow,snowbiomes,flat,trees,nojungles,nobiomeblend,nomudflow,nosnowbiomes,noflat,notrees
mgv6_spflags (Mapgen v6 specific flags) flags jungles,biomeblend,mudflow,snowbiomes,trees jungles,biomeblend,mudflow,snowbiomes,flat,trees,nojungles,nobiomeblend,nomudflow,nosnowbiomes,noflat,notrees
# Controls size of deserts and beaches in Mapgen v6.
# When snowbiomes are enabled 'mgv6_freq_desert' is ignored.
mgv6_freq_desert (Mapgen v6 desert frequency) float 0.45
mgv6_freq_beach (Mapgen v6 beach frequency) float 0.15
# Deserts occur when np_biome exceeds this value.
# When the new biome system is enabled, this is ignored.
mgv6_freq_desert (Desert noise threshold) float 0.45
mgv6_np_terrain_base (Mapgen v6 terrain base noise parameters) noise_params -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
mgv6_np_terrain_higher (Mapgen v6 terrain altitude noise parameters) noise_params 20, 16, (500, 500, 500), 85039, 5, 0.6, 2.0
mgv6_np_steepness (Mapgen v6 steepness noise parameters) noise_params 0.85, 0.5, (125, 125, 125), -932, 5, 0.7, 2.0
mgv6_np_height_select (Mapgen v6 height select noise parameters) noise_params 0.5, 1, (250, 250, 250), 4213, 5, 0.69, 2.0
mgv6_np_mud (Mapgen v6 mud noise parameters) noise_params 4, 2, (200, 200, 200), 91013, 3, 0.55, 2.0
mgv6_np_beach (Mapgen v6 beach noise parameters) noise_params 0, 1, (250, 250, 250), 59420, 3, 0.50, 2.0
mgv6_np_biome (Mapgen v6 biome noise parameters) noise_params 0, 1, (500, 500, 500), 9130, 3, 0.50, 2.0
mgv6_np_cave (Mapgen v6 cave noise parameters) noise_params 6, 6, (250, 250, 250), 34329, 3, 0.50, 2.0
mgv6_np_humidity (Mapgen v6 humidity noise parameters) noise_params 0.5, 0.5, (500, 500, 500), 72384, 3, 0.50, 2.0
mgv6_np_trees (Mapgen v6 trees noise parameters) noise_params 0, 1, (125, 125, 125), 2, 4, 0.66, 2.0
mgv6_np_apple_trees (Mapgen v6 apple trees noise parameters) noise_params 0, 1, (100, 100, 100), 342902, 3, 0.45, 2.0
# Sandy beaches occur when np_beach exceeds this value.
mgv6_freq_beach (Beach noise threshold) float 0.15
# Y-level of lower terrain and lakebeds.
mgv6_np_terrain_base (Terrain base noise) noise_params -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
# Y-level of higher (cliff-top) terrain.
mgv6_np_terrain_higher (Terrain higher noise) noise_params 20, 16, (500, 500, 500), 85039, 5, 0.6, 2.0
# Varies steepness of cliffs.
mgv6_np_steepness (Steepness noise) noise_params 0.85, 0.5, (125, 125, 125), -932, 5, 0.7, 2.0
# Defines areas of 'terrain_higher' (cliff-top terrain).
mgv6_np_height_select (Height select noise) noise_params 0.5, 1, (250, 250, 250), 4213, 5, 0.69, 2.0
# Varies depth of biome surface nodes.
mgv6_np_mud (Mud noise) noise_params 4, 2, (200, 200, 200), 91013, 3, 0.55, 2.0
# Defines areas with sandy beaches.
mgv6_np_beach (Beach noise) noise_params 0, 1, (250, 250, 250), 59420, 3, 0.50, 2.0
# Temperature variation for biomes.
mgv6_np_biome (Biome noise) noise_params 0, 1, (500, 500, 500), 9130, 3, 0.50, 2.0
# Variation of number of caves.
mgv6_np_cave (Cave noise) noise_params 6, 6, (250, 250, 250), 34329, 3, 0.50, 2.0
# Humidity variation for biomes.
mgv6_np_humidity (Humidity noise) noise_params 0.5, 0.5, (500, 500, 500), 72384, 3, 0.50, 2.0
# Defines tree areas and tree density.
mgv6_np_trees (Trees noise) noise_params 0, 1, (125, 125, 125), 2, 4, 0.66, 2.0
# Defines areas where trees have apples.
mgv6_np_apple_trees (Apple trees noise) noise_params 0, 1, (100, 100, 100), 342902, 3, 0.45, 2.0
[***Mapgen v7]
@ -969,37 +1127,77 @@ mgv6_np_apple_trees (Mapgen v6 apple trees noise parameters) noise_params 0, 1,
# Floatlands are currently experimental and subject to change.
# Flags that are not specified in the flag string are not modified from the default.
# Flags starting with 'no' are used to explicitly disable them.
mgv7_spflags (Mapgen v7 flags) flags mountains,ridges mountains,ridges,floatlands,nomountains,noridges,nofloatlands
mgv7_spflags (Mapgen v7 specific flags) flags mountains,ridges,nofloatlands,caverns mountains,ridges,floatlands,caverns,nomountains,noridges,nofloatlands,nocaverns
# Controls width of tunnels, a smaller value creates wider tunnels.
mgv7_cave_width (Mapgen v7 cave width) float 0.09
mgv7_cave_width (Cave width) float 0.09
# Controls the density of floatland mountain terrain.
# Is an offset added to the 'np_mountain' noise value.
mgv7_float_mount_density (Mapgen v7 floatland mountain density) float 0.6
mgv7_float_mount_density (Floatland mountain density) float 0.6
# Typical maximum height, above and below midpoint, of floatland mountain terrain.
mgv7_float_mount_height (Mapgen v7 floatland mountain height) float 128.0
mgv7_float_mount_height (Floatland mountain height) float 128.0
# Y-level of floatland midpoint and lake surface.
mgv7_floatland_level (Mapgen v7 floatland level) int 1280
mgv7_floatland_level (Floatland level) int 1280
# Y-level to which floatland shadows extend.
mgv7_shadow_limit (Mapgen v7 shadow limit) int 1024
mgv7_shadow_limit (Shadow limit) int 1024
mgv7_np_terrain_base (Mapgen v7 terrain base noise parameters) noise_params 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0
mgv7_np_terrain_alt (Mapgen v7 terrain altitude noise parameters) noise_params 4, 25, (600, 600, 600), 5934, 5, 0.6, 2.0
mgv7_np_terrain_persist (Mapgen v7 terrain persistation noise parameters) noise_params 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0
mgv7_np_height_select (Mapgen v7 height select noise parameters) noise_params -8, 16, (500, 500, 500), 4213, 6, 0.7, 2.0
mgv7_np_filler_depth (Mapgen v7 filler depth noise parameters) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
mgv7_np_mount_height (Mapgen v7 mount height noise parameters) noise_params 256, 112, (1000, 1000, 1000), 72449, 3, 0.6, 2.0
mgv7_np_ridge_uwater (Mapgen v7 river course noise parameters) noise_params 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0
mgv7_np_floatland_base (Mapgen v7 floatland base terrain noise parameters) noise_params -0.6, 1.5, (600, 600, 600), 114, 5, 0.6, 2.0
mgv7_np_float_base_height (Mapgen v7 floatland base terrain height noise parameters) noise_params 48, 24, (300, 300, 300), 907, 4, 0.7, 2.0
mgv7_np_mountain (Mapgen v7 mountain noise parameters) noise_params -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0
mgv7_np_ridge (Mapgen v7 river channel wall noise parameters) noise_params 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0
mgv7_np_cave1 (Mapgen v7 cave1 noise parameters) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
mgv7_np_cave2 (Mapgen v7 cave2 noise parameters) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
# Y-level of cavern upper limit.
mgv7_cavern_limit (Cavern limit) int -256
# Y-distance over which caverns expand to full size.
mgv7_cavern_taper (Cavern taper) int 256
# Defines full size of caverns, smaller values create larger caverns.
mgv7_cavern_threshold (Cavern threshold) float 0.7
# Y-level of higher (cliff-top) terrain.
mgv7_np_terrain_base (Terrain base noise) noise_params 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0
# Y-level of lower terrain and lakebeds.
mgv7_np_terrain_alt (Terrain alt noise) noise_params 4, 25, (600, 600, 600), 5934, 5, 0.6, 2.0
# Varies roughness of terrain.
# Defines the 'persistence' value for terrain_base and terrain_alt noises.
mgv7_np_terrain_persist (Terrain persistence noise) noise_params 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0
# Defines areas of higher (cliff-top) terrain and affects steepness of cliffs.
mgv7_np_height_select (Height select noise) noise_params -8, 16, (500, 500, 500), 4213, 6, 0.7, 2.0
# Variation of biome filler depth.
mgv7_np_filler_depth (Filler depth noise) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
# Variation of maximum mountain height (in nodes).
mgv7_np_mount_height (Mountain height noise) noise_params 256, 112, (1000, 1000, 1000), 72449, 3, 0.6, 2.0
# Defines large-scale river channel structure.
mgv7_np_ridge_uwater (Ridge underwater noise) noise_params 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0
# Defines areas of floatland smooth terrain.
# Smooth floatlands occur when noise > 0.
mgv7_np_floatland_base (Floatland base noise) noise_params -0.6, 1.5, (600, 600, 600), 114, 5, 0.6, 2.0
# Variation of hill height and lake depth on floatland smooth terrain.
mgv7_np_float_base_height (Floatland base height noise) noise_params 48, 24, (300, 300, 300), 907, 4, 0.7, 2.0
# 3D noise defining mountain structure and height.
# Also defines structure of floatland mountain terrain.
mgv7_np_mountain (Mountain noise) noise_params -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0
# 3D noise defining structure of river canyon walls.
mgv7_np_ridge (Ridge noise) noise_params 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0
# 3D noise defining giant caverns.
mgv7_np_cavern (Cavern noise) noise_params 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0
# First of 2 3D noises that together define tunnels.
mgv7_np_cave1 (Cave1 noise) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
# Second of 2 3D noises that together define tunnels.
mgv7_np_cave2 (Cave2 noise) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
[***Mapgen flat]
@ -1007,46 +1205,49 @@ mgv7_np_cave2 (Mapgen v7 cave2 noise parameters) noise_params 0, 12, (67, 67, 67
# Occasional lakes and hills can be added to the flat world.
# Flags that are not specified in the flag string are not modified from the default.
# Flags starting with 'no' are used to explicitly disable them.
mgflat_spflags (Mapgen flat flags) flags lakes,hills,,nolakes,nohills
mgflat_spflags (Mapgen flat specific flags) flags nolakes,nohills lakes,hills,nolakes,nohills
# Y of flat ground.
mgflat_ground_level (Mapgen flat ground level) int 8
mgflat_ground_level (Ground level) int 8
# Y of upper limit of large pseudorandom caves.
mgflat_large_cave_depth (Mapgen flat large cave depth) int -33
mgflat_large_cave_depth (Large cave depth) int -33
# Controls width of tunnels, a smaller value creates wider tunnels.
mgflat_cave_width (Mapgen flat cave width) float 0.09
mgflat_cave_width (Cave width) float 0.09
# Terrain noise threshold for lakes.
# Controls proportion of world area covered by lakes.
# Adjust towards 0.0 for a larger proportion.
mgflat_lake_threshold (Mapgen flat lake threshold) float -0.45
mgflat_lake_threshold (Lake threshold) float -0.45
# Controls steepness/depth of lake depressions.
mgflat_lake_steepness (Mapgen flat lake steepness) float 48.0
mgflat_lake_steepness (Lake steepness) float 48.0
# Terrain noise threshold for hills.
# Controls proportion of world area covered by hills.
# Adjust towards 0.0 for a larger proportion.
mgflat_hill_threshold (Mapgen flat hill threshold) float 0.45
mgflat_hill_threshold (Hill threshold) float 0.45
# Controls steepness/height of hills.
mgflat_hill_steepness (Mapgen flat hill steepness) float 64.0
mgflat_hill_steepness (Hill steepness) float 64.0
# Determines terrain shape.
# The 3 numbers in brackets control the scale of the
# terrain, the 3 numbers should be identical.
mgflat_np_terrain (Mapgen flat terrain noise parameters) noise_params 0, 1, (600, 600, 600), 7244, 5, 0.6, 2.0
# Defines location and terrain of optional hills and lakes.
mgflat_np_terrain (Terrain noise) noise_params 0, 1, (600, 600, 600), 7244, 5, 0.6, 2.0
mgflat_np_filler_depth (Mapgen flat filler depth noise parameters) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
mgflat_np_cave1 (Mapgen flat cave1 noise parameters) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
mgflat_np_cave2 (Mapgen flat cave2 noise parameters) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
# Variation of biome filler depth.
mgflat_np_filler_depth (Filler depth noise) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
# First of 2 3D noises that together define tunnels.
mgflat_np_cave1 (Cave1 noise) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
# Second of 2 3D noises that together define tunnels.
mgflat_np_cave2 (Cave2 noise) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
[***Mapgen fractal]
# Controls width of tunnels, a smaller value creates wider tunnels.
mgfractal_cave_width (Mapgen fractal cave width) float 0.09
mgfractal_cave_width (Cave width) float 0.09
# Choice of 18 fractals from 9 formulas.
# 1 = 4D "Roundy" mandelbrot set.
@ -1067,48 +1268,55 @@ mgfractal_cave_width (Mapgen fractal cave width) float 0.09
# 16 = 3D "Cosine Mandelbulb" julia set.
# 17 = 4D "Mandelbulb" mandelbrot set.
# 18 = 4D "Mandelbulb" julia set.
mgfractal_fractal (Mapgen fractal fractal) int 1 1 18
mgfractal_fractal (Fractal type) int 1 1 18
# Iterations of the recursive function.
# Controls the amount of fine detail.
mgfractal_iterations (Mapgen fractal iterations) int 11
mgfractal_iterations (Iterations) int 11
# Approximate (X,Y,Z) scale of fractal in nodes.
mgfractal_scale (Mapgen fractal scale) v3f (4096.0, 1024.0, 4096.0)
mgfractal_scale (Scale) v3f (4096.0, 1024.0, 4096.0)
# (X,Y,Z) offset of fractal from world centre in units of 'scale'.
# Used to move a suitable spawn area of low land close to (0, 0).
# The default is suitable for mandelbrot sets, it needs to be edited for julia sets.
# Range roughly -2 to 2. Multiply by 'scale' for offset in nodes.
mgfractal_offset (Mapgen fractal offset) v3f (1.79, 0.0, 0.0)
mgfractal_offset (Offset) v3f (1.79, 0.0, 0.0)
# W co-ordinate of the generated 3D slice of a 4D fractal.
# Determines which 3D slice of the 4D shape is generated.
# Has no effect on 3D fractals.
# Range roughly -2 to 2.
mgfractal_slice_w (Mapgen fractal slice w) float 0.0
mgfractal_slice_w (Slice w) float 0.0
# Julia set only: X component of hypercomplex constant determining julia shape.
# Range roughly -2 to 2.
mgfractal_julia_x (Mapgen fractal julia x) float 0.33
mgfractal_julia_x (Julia x) float 0.33
# Julia set only: Y component of hypercomplex constant determining julia shape.
# Range roughly -2 to 2.
mgfractal_julia_y (Mapgen fractal julia y) float 0.33
mgfractal_julia_y (Julia y) float 0.33
# Julia set only: Z component of hypercomplex constant determining julia shape.
# Range roughly -2 to 2.
mgfractal_julia_z (Mapgen fractal julia z) float 0.33
mgfractal_julia_z (Julia z) float 0.33
# Julia set only: W component of hypercomplex constant determining julia shape.
# Has no effect on 3D fractals.
# Range roughly -2 to 2.
mgfractal_julia_w (Mapgen fractal julia w) float 0.33
mgfractal_julia_w (Julia w) float 0.33
mgfractal_np_seabed (Mapgen fractal seabed noise parameters) noise_params -14, 9, (600, 600, 600), 41900, 5, 0.6, 2.0
mgfractal_np_filler_depth (Mapgen fractal filler depth noise parameters) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
mgfractal_np_cave1 (Mapgen fractal cave1 noise parameters) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
mgfractal_np_cave2 (Mapgen fractal cave2 noise parameters) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
# Y-level of seabed.
mgfractal_np_seabed (Seabed noise) noise_params -14, 9, (600, 600, 600), 41900, 5, 0.6, 2.0
# Variation of biome filler depth.
mgfractal_np_filler_depth (Filler depth noise) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
# First of 2 3D noises that together define tunnels.
mgfractal_np_cave1 (Cave1 noise) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
# Second of 2 3D noises that together define tunnels.
mgfractal_np_cave2 (Cave2 noise) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
# Mapgen Valleys parameters
[***Mapgen Valleys]
@ -1186,7 +1394,7 @@ mgvalleys_np_inter_valley_slope (Valley Slope) noise_params 0.5, 0.5, (128, 128,
[*Security]
# Prevent mods from doing insecure things like running shell commands.
secure.enable_security (Enable mod security) bool false
secure.enable_security (Enable mod security) bool true
# Comma-separated list of trusted mods that are allowed to access insecure
# functions even when mod security is on (via request_insecure_environment()).
@ -1209,7 +1417,6 @@ profiler.load (Load the game profiler) bool false
profiler.default_report_format (Default report format) enum txt txt,csv,lua,json,json_pretty
# The file path relative to your worldpath in which profiles will be saved to.
#
profiler.report_path (Report path) string ""
[***Instrumentation]
@ -1260,7 +1467,7 @@ language (Language) enum ,be,ca,cs,da,de,en,eo,es,et,fr,he,hu,id,it,ja,jbo,ko,
# - action
# - info
# - verbose
debug_log_level (Debug log level) enum action ,warning,action,info,verbose
debug_log_level (Debug log level) enum action ,none,error,warning,action,info,verbose
# IPv6 support.
enable_ipv6 (IPv6) bool true

@ -37,7 +37,7 @@ const float fogShadingParameter = 1 / ( 1 - fogStart);
vec3 uncharted2Tonemap(vec3 x)
{
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334;
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
}
vec4 applyToneMapping(vec4 color)
@ -163,7 +163,8 @@ void main(void)
}
#endif
if (GENERATE_NORMALMAPS == 1 && normalTexturePresent == false) {
#if GENERATE_NORMALMAPS == 1
if (normalTexturePresent == false) {
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
@ -177,7 +178,7 @@ void main(void)
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
use_normalmap = true;
}
#endif
vec4 base = texture2D(baseTexture, uv).rgba;
#ifdef ENABLE_BUMPMAPPING
@ -200,20 +201,18 @@ void main(void)
col = applyToneMapping(col);
#endif
if (fogDistance != 0.0) {
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
// the fog will only be rendered correctly if the last operation before the
// clamp() is an addition. Else, the clamp() seems to be ignored.
// E.g. the following won't work:
// float clarity = clamp(fogShadingParameter
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
// As additions usually come for free following a multiplication, the new formula
// should be more efficient as well.
// Note: clarity = (1 - fogginess)
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col = mix(skyBgColor, col, clarity);
}
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
// the fog will only be rendered correctly if the last operation before the
// clamp() is an addition. Else, the clamp() seems to be ignored.
// E.g. the following won't work:
// float clarity = clamp(fogShadingParameter
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
// As additions usually come for free following a multiplication, the new formula
// should be more efficient as well.
// Note: clarity = (1 - fogginess)
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col = mix(skyBgColor, col, clarity);
col = vec4(col.rgb, base.a);
gl_FragColor = col;

@ -1,7 +1,8 @@
uniform mat4 mWorldViewProj;
uniform mat4 mWorld;
uniform float dayNightRatio;
// Color of the light emitted by the sun.
uniform vec3 dayLight;
uniform vec3 eyePosition;
uniform float animationTimer;
@ -14,6 +15,8 @@ varying vec3 tsEyeVec;
varying vec3 tsLightVec;
varying float area_enable_parallax;
// Color of the light emitted by the light sources.
const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
const float e = 2.718281828459;
const float BS = 10.0;
@ -119,31 +122,23 @@ float disp_z;
v.z = dot(eyeVec, normal);
tsEyeVec = normalize (v);
// Calculate color.
// Red, green and blue components are pre-multiplied with
// 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;
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;
float rg = mix(night, day, dayNightRatio);
rg += light_source * 2.5; // Make light sources brighter
float b = rg;
// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 23.0;
// The alpha gives the ratio of sunlight in the incoming light.
float nightRatio = 1 - gl_Color.a;
color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb +
nightRatio * artificialLight.rgb) * 2;
color.a = 1;
// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13) / 0.17) * 0.025);
// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85) / 0.15) * 0.065);
color.r = rg;
color.g = rg;
color.b = b;
color.a = gl_Color.a;
float brightness = (color.r + color.g + color.b) / 3;
color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
0.07 * brightness);
gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0);
}

@ -1,176 +0,0 @@
uniform sampler2D baseTexture;
uniform sampler2D normalTexture;
uniform sampler2D textureFlags;
uniform vec4 skyBgColor;
uniform float fogDistance;
uniform vec3 eyePosition;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 tsEyeVec;
varying vec3 lightVec;
varying vec3 tsLightVec;
bool normalTexturePresent = false;
bool texTileableHorizontal = false;
bool texTileableVertical = false;
bool texSeamless = false;
const float e = 2.718281828459;
const float BS = 10.0;
const float fogStart = FOG_START;
const float fogShadingParameter = 1 / ( 1 - fogStart);
#ifdef ENABLE_TONE_MAPPING
/* Hable's UC2 Tone mapping parameters
A = 0.22;
B = 0.30;
C = 0.10;
D = 0.20;
E = 0.01;
F = 0.30;
W = 11.2;
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
*/
vec3 uncharted2Tonemap(vec3 x)
{
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334;
}
vec4 applyToneMapping(vec4 color)
{
color = vec4(pow(color.rgb, vec3(2.2)), color.a);
const float gamma = 1.6;
const float exposureBias = 5.5;
color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
// Precalculated white_scale from
//vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
vec3 whiteScale = vec3(1.036015346);
color.rgb *= whiteScale;
return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
}
#endif
void get_texture_flags()
{
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
if (flags.r > 0.5) {
normalTexturePresent = true;
}
if (flags.g > 0.5) {
texTileableHorizontal = true;
}
if (flags.b > 0.5) {
texTileableVertical = true;
}
if (texTileableHorizontal && texTileableVertical) {
texSeamless = true;
}
}
float intensity(vec3 color)
{
return (color.r + color.g + color.b) / 3.0;
}
float get_rgb_height(vec2 uv)
{
return intensity(texture2D(baseTexture,uv).rgb);
}
vec4 get_normal_map(vec2 uv)
{
vec4 bump = texture2D(normalTexture, uv).rgba;
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
bump.y = -bump.y;
return bump;
}
void main(void)
{
vec3 color;
vec4 bump;
vec2 uv = gl_TexCoord[0].st;
bool use_normalmap = false;
get_texture_flags();
#ifdef ENABLE_PARALLAX_OCCLUSION
if (normalTexturePresent) {
vec3 tsEye = normalize(tsEyeVec);
float height = PARALLAX_OCCLUSION_SCALE * texture2D(normalTexture, uv).a - PARALLAX_OCCLUSION_BIAS;
uv = uv + texture2D(normalTexture, uv).z * height * vec2(tsEye.x,-tsEye.y);
}
#endif
#ifdef USE_NORMALMAPS
if (normalTexturePresent) {
bump = get_normal_map(uv);
use_normalmap = true;
}
#endif
if (GENERATE_NORMALMAPS == 1 && use_normalmap == false) {
float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP));
float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP));
float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y));
float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP));
float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP));
float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y));
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0);
use_normalmap = true;
}
vec4 base = texture2D(baseTexture, uv).rgba;
#ifdef ENABLE_BUMPMAPPING
if (use_normalmap) {
vec3 L = normalize(lightVec);
vec3 E = normalize(eyeVec);
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5);
float diffuse = dot(E,bump.xyz);
/* Mathematic optimization
* Original: color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb;
* This optimization save 2 multiplications (orig: 4 multiplications + 3 additions
* end: 2 multiplications + 3 additions)
*/
color = (0.05 + diffuse + 0.2 * specular) * base.rgb;
} else {
color = base.rgb;
}
#else
color = base.rgb;
#endif
vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
#ifdef ENABLE_TONE_MAPPING
col = applyToneMapping(col);
#endif
if (fogDistance != 0.0) {
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
// the fog will only be rendered correctly if the last operation before the
// clamp() is an addition. Else, the clamp() seems to be ignored.
// E.g. the following won't work:
// float clarity = clamp(fogShadingParameter
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
// As additions usually come for free following a multiplication, the new formula
// should be more efficient as well.
// Note: clarity = (1 - fogginess)
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col = mix(skyBgColor, col, clarity);
}
col = vec4(col.rgb, base.a);
gl_FragColor = col;
}

@ -1,142 +0,0 @@
uniform mat4 mWorldViewProj;
uniform mat4 mWorld;
uniform float dayNightRatio;
uniform vec3 eyePosition;
uniform float animationTimer;
varying vec3 vPosition;
varying vec3 worldPosition;
varying vec3 eyeVec;
varying vec3 lightVec;
varying vec3 tsEyeVec;
varying vec3 tsLightVec;
const float e = 2.718281828459;
const float BS = 10.0;
float smoothCurve(float x)
{
return x * x * (3.0 - 2.0 * x);
}
float triangleWave(float x)
{
return abs(fract( x + 0.5 ) * 2.0 - 1.0);
}
float smoothTriangleWave(float x)
{
return smoothCurve(triangleWave( x )) * 2.0 - 1.0;
}
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
vec4 pos = gl_Vertex;
pos.y -= 2.0;
float posYbuf = (pos.z / WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH);
pos.y -= sin(posYbuf) * WATER_WAVE_HEIGHT + sin(posYbuf / 7.0) * WATER_WAVE_HEIGHT;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
/*
* Mathematic optimization: pos2.x * A + pos2.z * A (2 multiplications + 1 addition)
* replaced with: (pos2.x + pos2.z) * A (1 addition + 1 multiplication)
* And bufferize calcul to a float
*/
float pos2XpZ = pos2.x + pos2.z;
pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2XpZ * 0.01) * 2.0 - 1.0) * 0.4;
pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2XpZ * -0.01) * 2.0 - 1.0) * 0.2;
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2XpZ * -0.01) * 2.0 - 1.0) * 0.4;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
if (gl_TexCoord[0].y < 0.05) {
/*
* Mathematic optimization: pos2.x * A + pos2.z * A (2 multiplications + 1 addition)
* replaced with: (pos2.x + pos2.z) * A (1 addition + 1 multiplication)
* And bufferize calcul to a float
*/
float pos2XpZ = pos2.x + pos2.z;
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2XpZ * 0.1) * 2.0 - 1.0) * 0.8;
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2XpZ * -0.5) * 2.0 - 1.0) * 0.4;
}
gl_Position = mWorldViewProj * pos;
#else
gl_Position = mWorldViewProj * gl_Vertex;
#endif
vPosition = gl_Position.xyz;
worldPosition = (mWorld * gl_Vertex).xyz;
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
vec3 normal, tangent, binormal;
normal = normalize(gl_NormalMatrix * gl_Normal);
if (gl_Normal.x > 0.5) {
// 1.0, 0.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.x < -0.5) {
// -1.0, 0.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.y > 0.5) {
// 0.0, 1.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
} else if (gl_Normal.y < -0.5) {
// 0.0, -1.0, 0.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
} else if (gl_Normal.z > 0.5) {
// 0.0, 0.0, 1.0
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
} else if (gl_Normal.z < -0.5) {
// 0.0, 0.0, -1.0
tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0));
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
}
mat3 tbnMatrix = mat3(tangent.x, binormal.x, normal.x,
tangent.y, binormal.y, normal.y,
tangent.z, binormal.z, normal.z);
lightVec = sunPosition - worldPosition;
tsLightVec = lightVec * tbnMatrix;
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
tsEyeVec = eyeVec * tbnMatrix;
vec4 color;
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;
float rg = mix(night, day, dayNightRatio);
rg += light_source * 2.5; // Make light sources brighter
float b = rg;
// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 23.0;
// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
color.r = rg;
color.g = rg;
color.b = b;
color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = clamp(color,0.0,1.0);
}

@ -75,7 +75,8 @@ void main(void)
}
#endif
if (GENERATE_NORMALMAPS == 1 && normalTexturePresent == false) {
#if GENERATE_NORMALMAPS == 1
if (normalTexturePresent == false) {
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
@ -89,6 +90,7 @@ void main(void)
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
use_normalmap = true;
}
#endif
vec4 base = texture2D(baseTexture, uv).rgba;
@ -108,19 +110,18 @@ void main(void)
vec4 col = vec4(color.rgb, base.a);
col *= gl_Color;
if (fogDistance != 0.0) {
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
// the fog will only be rendered correctly if the last operation before the
// clamp() is an addition. Else, the clamp() seems to be ignored.
// E.g. the following won't work:
// float clarity = clamp(fogShadingParameter
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
// As additions usually come for free following a multiplication, the new formula
// should be more efficient as well.
// Note: clarity = (1 - fogginess)
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col = mix(skyBgColor, col, clarity);
}
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
// the fog will only be rendered correctly if the last operation before the
// clamp() is an addition. Else, the clamp() seems to be ignored.
// E.g. the following won't work:
// float clarity = clamp(fogShadingParameter
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
// As additions usually come for free following a multiplication, the new formula
// should be more efficient as well.
// Note: clarity = (1 - fogginess)
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col = mix(skyBgColor, col, clarity);
gl_FragColor = vec4(col.rgb, base.a);
}

@ -1,7 +1,6 @@
uniform mat4 mWorldViewProj;
uniform mat4 mWorld;
uniform float dayNightRatio;
uniform vec3 eyePosition;
uniform float animationTimer;

152
clientmods/preview/init.lua Normal file

@ -0,0 +1,152 @@
local modname = core.get_current_modname() or "??"
local modstorage = core.get_mod_storage()
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_on_shutdown(function()
print("[PREVIEW] shutdown client")
end)
core.register_on_connect(function()
print("[PREVIEW] Player connection completed")
local server_info = core.get_server_info()
print("Server version: " .. server_info.protocol_version)
print("Server ip: " .. server_info.ip)
print("Server address: " .. server_info.address)
print("Server port: " .. server_info.port)
end)
core.register_on_placenode(function(pointed_thing, node)
print("The local player place a node!")
print("pointed_thing :" .. dump(pointed_thing))
print("node placed :" .. dump(node))
return false
end)
core.register_on_item_use(function(itemstack, pointed_thing)
print("The local player used an item!")
print("pointed_thing :" .. dump(pointed_thing))
print("item = " .. itemstack:get_name())
return false
end)
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_on_receiving_chat_messages(function(message)
print("[PREVIEW] Received message " .. message)
return false
end)
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_on_sending_chat_messages(function(message)
print("[PREVIEW] Sending message " .. message)
return false
end)
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_on_hp_modification(function(hp)
print("[PREVIEW] HP modified " .. hp)
end)
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_on_damage_taken(function(hp)
print("[PREVIEW] Damage taken " .. hp)
end)
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_globalstep(function(dtime)
-- print("[PREVIEW] globalstep " .. dtime)
end)
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_chatcommand("dump", {
func = function(param)
return true, dump(_G)
end,
})
core.register_chatcommand("colorize_test", {
func = function(param)
return true, core.colorize("red", param)
end,
})
core.register_chatcommand("test_node", {
func = function(param)
core.display_chat_message(dump(core.get_node({x=0, y=0, z=0})))
core.display_chat_message(dump(core.get_node_or_nil({x=0, y=0, z=0})))
end,
})
local function preview_minimap()
local minimap = core.ui.minimap
if not minimap then
print("[PREVIEW] Minimap is disabled. Skipping.")
return
end
minimap:set_mode(4)
minimap:show()
minimap:set_pos({x=5, y=50, z=5})
minimap:set_shape(math.random(0, 1))
print("[PREVIEW] Minimap: mode => " .. dump(minimap:get_mode()) ..
" position => " .. dump(minimap:get_pos()) ..
" angle => " .. dump(minimap:get_angle()))
end
core.after(2, function()
print("[PREVIEW] loaded " .. modname .. " mod")
modstorage:set_string("current_mod", modname)
print(modstorage:get_string("current_mod"))
preview_minimap()
end)
core.after(5, function()
if core.ui.minimap then
core.ui.minimap:show()
end
print("[PREVIEW] Day count: " .. core.get_day_count() ..
" time of day " .. core.get_timeofday())
print("[PREVIEW] Node level: " .. core.get_node_level({x=0, y=20, z=0}) ..
" max level " .. core.get_node_max_level({x=0, y=20, z=0}))
print("[PREVIEW] Find node near: " .. dump(core.find_node_near({x=0, y=20, z=0}, 10,
{"group:tree", "default:dirt", "default:stone"})))
end)
core.register_on_dignode(function(pos, node)
print("The local player dug a node!")
print("pos:" .. dump(pos))
print("node:" .. dump(node))
return false
end)
core.register_on_punchnode(function(pos, node)
print("The local player punched a node!")
local itemstack = core.get_wielded_item()
--[[
-- getters
print(dump(itemstack:is_empty()))
print(dump(itemstack:get_name()))
print(dump(itemstack:get_count()))
print(dump(itemstack:get_wear()))
print(dump(itemstack:get_meta()))
print(dump(itemstack:get_metadata()
print(dump(itemstack:is_known()))
--print(dump(itemstack:get_definition()))
print(dump(itemstack:get_tool_capabilities()))
print(dump(itemstack:to_string()))
print(dump(itemstack:to_table()))
-- setters
print(dump(itemstack:set_name("default:dirt")))
print(dump(itemstack:set_count("95")))
print(dump(itemstack:set_wear(934)))
print(dump(itemstack:get_meta()))
print(dump(itemstack:get_metadata()))
--]]
print(dump(itemstack:to_table()))
print("pos:" .. dump(pos))
print("node:" .. dump(node))
return false
end)

@ -1,4 +1,3 @@
option(ENABLE_SYSTEM_GMP "Use GMP from system" TRUE)
mark_as_advanced(GMP_LIBRARY GMP_INCLUDE_DIR)
set(USE_SYSTEM_GMP FALSE)
@ -19,9 +18,9 @@ endif()
if(NOT USE_SYSTEM_GMP)
message(STATUS "Using bundled mini-gmp library.")
set(GMP_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/gmp)
set(GMP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/gmp)
set(GMP_LIBRARY gmp)
add_subdirectory(gmp)
add_subdirectory(lib/gmp)
endif()
include(FindPackageHandleStandardArgs)

@ -20,8 +20,7 @@ endif()
if(NOT JSONCPP_FOUND)
message(STATUS "Using bundled JSONCPP library.")
set(JSON_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/jsoncpp)
set(JSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/jsoncpp)
set(JSON_LIBRARY jsoncpp)
add_subdirectory(jsoncpp/json)
add_subdirectory(lib/jsoncpp)
endif()

@ -0,0 +1,28 @@
# Look for Lua library to use
# This selects LuaJIT by default
option(ENABLE_LUAJIT "Enable LuaJIT support" TRUE)
set(USE_LUAJIT FALSE)
option(REQUIRE_LUAJIT "Require LuaJIT support" FALSE)
if(REQUIRE_LUAJIT)
set(ENABLE_LUAJIT TRUE)
endif()
if(ENABLE_LUAJIT)
find_package(LuaJIT)
if(LUAJIT_FOUND)
set(USE_LUAJIT TRUE)
message (STATUS "Using LuaJIT provided by system.")
elseif(REQUIRE_LUAJIT)
message(FATAL_ERROR "LuaJIT not found whereas REQUIRE_LUAJIT=\"TRUE\" is used.\n"
"To continue, either install LuaJIT or do not use REQUIRE_LUAJIT=\"TRUE\".")
endif()
else()
message (STATUS "LuaJIT detection disabled! (ENABLE_LUAJIT=0)")
endif()
if(NOT USE_LUAJIT)
message(STATUS "LuaJIT not found, using bundled Lua.")
set(LUA_LIBRARY lua)
set(LUA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/src)
add_subdirectory(lib/lua)
endif()

1149
doc/client_lua_api.md Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,4 +1,4 @@
Minetest Lua Mainmenu API Reference 0.4.15
Minetest Lua Mainmenu API Reference 0.4.16
========================================
Introduction

@ -76,6 +76,9 @@ by texture packs. All existing fallback textures can be found in the directory
* `player.png`: front texture of the 2D upright sprite player
* `player_back.png`: back texture of the 2D upright sprite player
* `progress_bar.png`: foreground texture of the loading screen's progress bar
* `progress_bar_bg.png`: background texture of the loading screen's progress bar
* `moon.png`: texture of the moon. Default texture is generated by Minetest
* `moon_tonemap.png`: tonemap to be used when `moon.png` was found
* `sun.png`: texture of the sun. Default texture is generated by Minetest

@ -1,12 +1,13 @@
=============================
Minetest World Format 22...25
Minetest World Format 22...27
=============================
This applies to a world format carrying the block serialization version
22...25, used at least in
22...27, used at least in
- 0.4.dev-20120322 ... 0.4.dev-20120606 (22...23)
- 0.4.0 (23)
- 24 was never released as stable and existed for ~2 days
- 27 was added in 0.4.15-dev
The block serialization version does not fully specify every aspect of this
format; if compliance with this format is to be checked, it needs to be
@ -262,15 +263,36 @@ u8 flags
- 0x02: day_night_differs: Whether the lighting of the block is different
on day and night. Only blocks that have this bit set are updated when
day transforms to night.
- 0x04: lighting_expired: If true, lighting is invalid and should be
updated. If you can't calculate lighting in your generator properly,
you could try setting this 1 to everything and setting the uppermost
block in every sector as is_underground=0. I am quite sure it doesn't
work properly, though.
- 0x04: lighting_expired: Not used in version 27 and above. If true,
lighting is invalid and should be updated. If you can't calculate
lighting in your generator properly, you could try setting this 1 to
everything and setting the uppermost block in every sector as
is_underground=0. I am quite sure it doesn't work properly, though.
- 0x08: generated: True if the block has been generated. If false, block
is mostly filled with CONTENT_IGNORE and is likely to contain eg. parts
of trees of neighboring blocks.
u16 lighting_complete
- Added in version 27.
- This contains 12 flags, each of them corresponds to a direction.
- Indicates if the light is correct at the sides of a map block.
Lighting may not be correct if the light changed, but a neighbor
block was not loaded at that time.
If these flags are false, Minetest will automatically recompute light
when both this block and its required neighbor are loaded.
- The bit order is:
nothing, nothing, nothing, nothing,
night X-, night Y-, night Z-, night Z+, night Y+, night X+,
day X-, day Y-, day Z-, day Z+, day Y+, day X+.
Where 'day' is for the day light bank, 'night' is for the night
light bank.
The 'nothing' bits should be always set, as they will be used
to indicate if direct sunlight spreading is finished.
- Example: if the block at (0, 0, 0) has
lighting_complete = 0b1111111111111110,
then Minetest will correct lighting in the day light bank when
the block at (1, 0, 0) is also loaded.
u8 content_width
- Number of bytes in the content (param0) fields of nodes
if map format version <= 23:

2
fonts/Arimo-LICENSE.txt Normal file

@ -0,0 +1,2 @@
Arimo - Apache License, version 2.0
Arimo-Regular.ttf: Digitized data copyright (c) 2010-2012 Google Corporation.

BIN
fonts/Arimo-Regular.ttf Normal file

Binary file not shown.

@ -0,0 +1,2 @@
Cousine - Apache License, version 2.0
Cousine-Regular.ttf: Digitized data copyright (c) 2010-2012 Google Corporation.

BIN
fonts/Cousine-Regular.ttf Normal file

Binary file not shown.

@ -0,0 +1,13 @@
Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

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