|
@ -73,15 +73,14 @@ locale/
|
|||
*.a
|
||||
|
||||
## Android build files
|
||||
build/android/assets
|
||||
build/android/bin
|
||||
build/android/Debug
|
||||
build/android/src/main/assets
|
||||
build/android/build
|
||||
build/android/deps
|
||||
build/android/gen
|
||||
build/android/jni/src
|
||||
build/android/libs
|
||||
build/android/jni/src
|
||||
build/android/src/main/jniLibs
|
||||
build/android/obj
|
||||
build/android/path.cfg
|
||||
build/android/and_env
|
||||
build/android/AndroidManifest.xml
|
||||
build/android/local.properties
|
||||
build/android/.gradle
|
||||
timestamp
|
||||
|
||||
|
|
11
.travis.yml
|
@ -2,10 +2,13 @@ language: cpp
|
|||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
os:
|
||||
- osx
|
||||
- linux
|
||||
env:
|
||||
- PLATFORM=Win32
|
||||
- PLATFORM=Win64
|
||||
- PLATFORM=Linux
|
||||
- PLATFORM=Unix
|
||||
before_install: ./util/travis/before_install.sh
|
||||
script: ./util/travis/script.sh
|
||||
sudo: required
|
||||
|
@ -18,3 +21,9 @@ matrix:
|
|||
compiler: clang
|
||||
- env: PLATFORM=Win64
|
||||
compiler: clang
|
||||
- env: PLATFORM=Win32
|
||||
os: osx
|
||||
- env: PLATFORM=Win64
|
||||
os: osx
|
||||
- compiler: gcc
|
||||
os: osx
|
||||
|
|
|
@ -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 13)
|
||||
set(VERSION_PATCH 14)
|
||||
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||
|
||||
# Change to false for releases
|
||||
|
@ -113,6 +113,9 @@ endif()
|
|||
set(CUSTOM_DOCDIR "" CACHE STRING "Directory to install documentation into")
|
||||
if(NOT CUSTOM_DOCDIR STREQUAL "")
|
||||
set(DOCDIR "${CUSTOM_DOCDIR}")
|
||||
if(NOT RUN_IN_PLACE)
|
||||
set(EXAMPLE_CONF_DIR ${DOCDIR})
|
||||
endif()
|
||||
message(STATUS "Using DOCDIR=${DOCDIR}")
|
||||
endif()
|
||||
|
||||
|
@ -149,16 +152,9 @@ 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}/games/minimal" DESTINATION "${SHAREDIR}/games")
|
||||
set(MINETEST_GAME_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game")
|
||||
if(EXISTS ${MINETEST_GAME_SOURCE} AND IS_DIRECTORY ${MINETEST_GAME_SOURCE})
|
||||
install(FILES ${MINETEST_GAME_SOURCE}/game.conf DESTINATION "${SHAREDIR}/games/minetest_game/")
|
||||
install(FILES ${MINETEST_GAME_SOURCE}/README.txt DESTINATION "${SHAREDIR}/games/minetest_game/")
|
||||
install(DIRECTORY ${MINETEST_GAME_SOURCE}/mods DESTINATION "${SHAREDIR}/games/minetest_game")
|
||||
install(DIRECTORY ${MINETEST_GAME_SOURCE}/menu DESTINATION "${SHAREDIR}/games/minetest_game")
|
||||
endif()
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games" DESTINATION "${SHAREDIR}" PATTERN ".git*" EXCLUDE)
|
||||
|
||||
if(BUILD_CLIENT)
|
||||
#install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/sounds/base/pack" DESTINATION "${SHAREDIR}/sounds/base")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base")
|
||||
endif()
|
||||
if(RUN_IN_PLACE)
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
# Contributing
|
||||
|
||||
Contributions are welcome! Here's how you can help:
|
||||
|
||||
- [Contributing code](#code)
|
||||
- [Reporting issues](#issues)
|
||||
- [Requesting features](#feature-requests)
|
||||
- [Translating](#translations)
|
||||
- [Donating](#donations)
|
||||
|
||||
## Code
|
||||
|
||||
If you are planning to start some significant coding, you would benefit from asking first on [our IRC channel](http://www.minetest.net/irc/) before starting.
|
||||
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) the repository and [clone](https://help.github.com/articles/cloning-a-repository/) your fork.
|
||||
|
||||
2. Start coding!
|
||||
- Refer to the [Lua API](https://github.com/minetest/minetest/blob/master/doc/lua_api.txt), [Developer Wiki](http://dev.minetest.net/Main_Page) and other [documentation](https://github.com/minetest/minetest/tree/master/doc).
|
||||
- Follow the [C/C++](http://dev.minetest.net/Code_style_guidelines) and [Lua](http://dev.minetest.net/Lua_code_style_guidelines) code style guidelines.
|
||||
- Check your code works as expected and document any changes to the Lua API.
|
||||
|
||||
3. Commit & [push](https://help.github.com/articles/pushing-to-a-remote/) your changes to a new branch (not `master`, one change per branch)
|
||||
- Commit messages should:
|
||||
- Use the present tense
|
||||
- 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)
|
||||
- Add a short description explaining briefly what you've done (or if it's a work-in-progress - what you need to do)
|
||||
|
||||
##### A pull-request is considered merge-able when:
|
||||
|
||||
1. It follows the [roadmap](https://forum.minetest.net/viewtopic.php?t=9177) in some way and fits the whole picture of the project.
|
||||
2. It works.
|
||||
3. It follows the code style for [C/C++](http://dev.minetest.net/Code_style_guidelines) or [Lua](http://dev.minetest.net/Lua_code_style_guidelines).
|
||||
4. The code's interfaces are well designed, regardless of other aspects that might need more work in the future.
|
||||
5. It uses protocols and formats which include the required compatibility.
|
||||
|
||||
## Issues
|
||||
|
||||
If you experience an issue, we would like to know the details - especially when a stable release is on the way.
|
||||
|
||||
1. Do a quick search on GitHub to check if the issue has already been reported.
|
||||
2. Is it an issue with the Minetest *engine*? If not, report it [elsewhere](http://www.minetest.net/development/#reporting-issues).
|
||||
3. [Open an issue](https://github.com/minetest/minetest/issues/new) and describe the issue you are having - you could include:
|
||||
- Error logs (check the bottom of the `debug.txt` file)
|
||||
- Screenshots
|
||||
- Ways you have tried to solve the issue, and whether they worked or not
|
||||
- Your Minetest version and the content (subgames, mods or texture packs) you have installed
|
||||
- Your platform (e.g. Windows 10 or Ubuntu 15.04 x64)
|
||||
|
||||
After reporting you should aim to answer questions or clarifications as this helps pinpoint the cause of the issue (if you don't do this your issue may be closed after 1 month).
|
||||
|
||||
## Feature requests
|
||||
|
||||
Feature requests are welcome but take a moment to see if your idea follows the [roadmap](https://forum.minetest.net/viewtopic.php?t=9177) in some way and fits the whole picture of the project. You should provide a clear explanation with as much detail as possible.
|
||||
|
||||
## Translations
|
||||
|
||||
Translations of Minetest are performed using Weblate. You can access the project page with a list of current languages [here](https://hosted.weblate.org/projects/minetest/minetest/).
|
||||
|
||||
### Donations
|
||||
|
||||
If you'd like to monetarily support Minetest development, you can find donation methods on [our website](http://www.minetest.net/development/#donate).
|
||||
|
||||
# Maintaining
|
||||
|
||||
*This is a concise version of the [Rules & Guidelines](http://dev.minetest.net/Category:Rules_and_Guidelines) on the developer wiki.*
|
||||
|
||||
These notes are for those who have push access Minetest (core developers / maintainers).
|
||||
|
||||
- See the [project organisation](http://dev.minetest.net/Organisation) for the people involved.
|
||||
|
||||
## Reviewing pull requests
|
||||
|
||||
Pull requests should be reviewed and, if appropriate, checked if they achieve their intended purpose. You can show that you are in the process of, or will review the pull request by commenting *"Looks good"* or something similar.
|
||||
|
||||
**If the pull-request is not [merge-able](#a-pull-request-is-considered-merge-able-when):**
|
||||
|
||||
Submit a comment explaining to the author what they need to change to make the pull-request merge-able.
|
||||
|
||||
- If the author comments or makes changes to the pull-request, it can be reviewed again.
|
||||
- If no response is made from the author within 1 month (when improvements are suggested or a question is asked), it can be closed.
|
||||
|
||||
**If the pull-request is [merge-able](#a-pull-request-is-considered-merge-able-when):**
|
||||
|
||||
Submit a :+1: (+1) or "Looks good" comment to show you believe the pull-request should be merged. "Looks good" comments often signify that the patch might require (more) testing.
|
||||
|
||||
- Two core developers must agree to the merge before it is carried out and both should +1 the pull request.
|
||||
- Who intends to merge the pull-request should follow the commit rules:
|
||||
- The title should follow the commit guidelines (title starts with a capital letter, present tense, descriptive).
|
||||
- Don't modify history older than 10 minutes.
|
||||
- Use rebase, not merge to get linear history:
|
||||
- `curl https://github.com/minetest/minetest/pull/1.patch | git am`
|
||||
|
||||
## Reviewing issues and feature requests
|
||||
|
||||
- If an issue does not get a response from its author within 1 month (when requiring more details), it can be closed.
|
||||
- When an issue is a duplicate, refer to the first ones and close the later ones.
|
||||
- Tag issues with the appropriate [labels](https://github.com/minetest/minetest/labels) for devices, platforms etc.
|
||||
|
||||
## Releasing a new version
|
||||
|
||||
*Refer to [dev.minetest.net/Releasing_Minetest](http://dev.minetest.net/Releasing_Minetest)*
|
10
README.txt
|
@ -105,11 +105,17 @@ Compiling on GNU/Linux:
|
|||
Install dependencies. Here's an example for Debian/Ubuntu:
|
||||
$ sudo apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
For Fedora users:
|
||||
$ sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl* 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.
|
||||
This is an example for installing git on Debian/Ubuntu:
|
||||
$ sudo apt-get install git-core
|
||||
|
||||
For Fedora users:
|
||||
$ sudo dnf install git-core
|
||||
|
||||
Download source (this is the URL to the latest of source repository, which might not work at all times) using git:
|
||||
$ git clone --depth 1 https://github.com/minetest/minetest.git
|
||||
$ cd minetest
|
||||
|
@ -376,8 +382,8 @@ Authors of media files
|
|||
Everything not listed in here:
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
BlockMen:
|
||||
textures/base/pack/menuheader.png
|
||||
Paramat:
|
||||
textures/base/pack/menu_header.png
|
||||
|
||||
erlehmann:
|
||||
misc/minetest-icon-24x24.png
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.minetest.minetest"
|
||||
android:versionCode="###ANDROID_VERSION###"
|
||||
android:versionName="###BASE_VERSION###.###ANDROID_VERSION###"
|
||||
android:installLocation="auto">
|
||||
<uses-sdk android:minSdkVersion="9"/>
|
||||
<uses-feature android:glEsVersion="0x00010000" android:required="true"/>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
###DEBUG_BUILD###
|
||||
<application android:icon="@drawable/irr_icon" android:label="Minetest" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" ###DEBUG_FLAG###>
|
||||
<activity android:name=".MtNativeActivity"
|
||||
android:label="Minetest"
|
||||
android:launchMode="singleTask"
|
||||
android:configChanges="orientation|keyboard|keyboardHidden|navigation"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:clearTaskOnLaunch="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.app.lib_name" android:value="minetest" />
|
||||
</activity>
|
||||
<activity android:name=".MinetestTextEntry"
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:excludeFromRecents="true">
|
||||
</activity>
|
||||
<activity android:name=".MinetestAssetCopy"
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:excludeFromRecents="true">
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
|
@ -8,42 +8,21 @@ OS := $(shell uname)
|
|||
# build for build platform
|
||||
APP_PLATFORM = android-9
|
||||
|
||||
# paths used for timestaps, dependencys, tree config and libs
|
||||
PATHCFGFILE = path.cfg
|
||||
|
||||
ROOT = $(shell pwd)
|
||||
ANDR_ROOT = $(shell pwd)
|
||||
PROJ_ROOT = $(shell realpath $(ANDR_ROOT)/../..)
|
||||
APP_ROOT = $(ANDR_ROOT)/src/main
|
||||
|
||||
GAMES_TO_COPY = minetest_game
|
||||
MODS_TO_COPY =
|
||||
|
||||
|
||||
VERSION_MAJOR := $(shell cat $(ROOT)/../../CMakeLists.txt | \
|
||||
VERSION_MAJOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
|
||||
grep ^set\(VERSION_MAJOR\ | sed 's/)/ /' | cut -f2 -d' ')
|
||||
VERSION_MINOR := $(shell cat $(ROOT)/../../CMakeLists.txt | \
|
||||
VERSION_MINOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
|
||||
grep ^set\(VERSION_MINOR\ | sed 's/)/ /' | cut -f2 -d' ')
|
||||
VERSION_PATCH := $(shell cat $(ROOT)/../../CMakeLists.txt | \
|
||||
VERSION_PATCH := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
|
||||
grep ^set\(VERSION_PATCH\ | sed 's/)/ /' | cut -f2 -d' ')
|
||||
|
||||
################################################################################
|
||||
# Android Version code
|
||||
# Increase for each build!
|
||||
################################################################################
|
||||
# Play Store actual version (16/03/15): 11
|
||||
ANDROID_VERSION_CODE = 13
|
||||
|
||||
################################################################################
|
||||
# toolchain config for arm old processors
|
||||
################################################################################
|
||||
#TARGET_HOST = arm-linux
|
||||
#TARGET_ABI = armeabi
|
||||
#TARGET_LIBDIR = armeabi
|
||||
#TARGET_TOOLCHAIN = arm-linux-androideabi-
|
||||
#TARGET_CFLAGS_ADDON = -mfloat-abi=softfp -mfpu=vfp
|
||||
#TARGET_ARCH = arm
|
||||
#CROSS_PREFIX = arm-linux-androideabi-
|
||||
#COMPILER_VERSION = 4.8
|
||||
#HAVE_LEVELDB = 1
|
||||
|
||||
################################################################################
|
||||
# toolchain config for arm new processors
|
||||
################################################################################
|
||||
|
@ -51,11 +30,11 @@ TARGET_HOST = arm-linux
|
|||
TARGET_ABI = armeabi-v7a
|
||||
TARGET_LIBDIR = armeabi-v7a
|
||||
TARGET_TOOLCHAIN = arm-linux-androideabi-
|
||||
TARGET_CFLAGS_ADDON = -mfloat-abi=softfp -mfpu=vfpv3
|
||||
TARGET_CFLAGS_ADDON = -mfloat-abi=softfp -mfpu=vfpv3 -O3
|
||||
TARGET_CXXFLAGS_ADDON = $(TARGET_CFLAGS_ADDON)
|
||||
TARGET_ARCH = armv7
|
||||
CROSS_PREFIX = arm-linux-androideabi-
|
||||
COMPILER_VERSION = 4.8
|
||||
COMPILER_VERSION = 4.9
|
||||
HAVE_LEVELDB = 1
|
||||
|
||||
################################################################################
|
||||
|
@ -67,7 +46,7 @@ HAVE_LEVELDB = 1
|
|||
#TARGET_TOOLCHAIN = mipsel-linux-android-
|
||||
#TARGET_ARCH = mips32
|
||||
#CROSS_PREFIX = mipsel-linux-android-
|
||||
#COMPILER_VERSION = 4.8
|
||||
#COMPILER_VERSION = 4.9
|
||||
#HAVE_LEVELDB = 0
|
||||
|
||||
################################################################################
|
||||
|
@ -79,76 +58,80 @@ HAVE_LEVELDB = 1
|
|||
#TARGET_TOOLCHAIN = x86-
|
||||
#CROSS_PREFIX = i686-linux-android-
|
||||
#TARGET_ARCH = x86
|
||||
#COMPILER_VERSION = 4.8
|
||||
#COMPILER_VERSION = 4.9
|
||||
#HAVE_LEVELDB = 1
|
||||
|
||||
################################################################################
|
||||
ASSETS_TIMESTAMP = deps/assets_timestamp
|
||||
|
||||
LEVELDB_DIR = $(ROOT)/deps/leveldb/
|
||||
LEVELDB_DIR = $(ANDR_ROOT)/deps/leveldb/
|
||||
LEVELDB_LIB = $(LEVELDB_DIR)libleveldb.a
|
||||
LEVELDB_TIMESTAMP = $(LEVELDB_DIR)/timestamp
|
||||
LEVELDB_TIMESTAMP_INT = $(ROOT)/deps/leveldb_timestamp
|
||||
LEVELDB_TIMESTAMP_INT = $(ANDR_ROOT)/deps/leveldb_timestamp
|
||||
LEVELDB_URL_GIT = https://github.com/google/leveldb
|
||||
LEVELDB_COMMIT = 2d0320a458d0e6a20fff46d5f80b18bfdcce7018
|
||||
|
||||
OPENAL_DIR = $(ROOT)/deps/openal-soft/
|
||||
OPENAL_DIR = $(ANDR_ROOT)/deps/openal-soft/
|
||||
OPENAL_LIB = $(OPENAL_DIR)libs/$(TARGET_ABI)/libopenal.so
|
||||
OPENAL_TIMESTAMP = $(OPENAL_DIR)/timestamp
|
||||
OPENAL_TIMESTAMP_INT = $(ROOT)/deps/openal_timestamp
|
||||
OPENAL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openal_timestamp
|
||||
OPENAL_URL_GIT = https://github.com/apportable/openal-soft
|
||||
|
||||
OGG_DIR = $(ROOT)/deps/libvorbis-libogg-android/
|
||||
OGG_DIR = $(ANDR_ROOT)/deps/libvorbis-libogg-android/
|
||||
OGG_LIB = $(OGG_DIR)libs/$(TARGET_ABI)/libogg.so
|
||||
VORBIS_LIB = $(OGG_DIR)libs/$(TARGET_ABI)/libogg.so
|
||||
OGG_TIMESTAMP = $(OGG_DIR)timestamp
|
||||
OGG_TIMESTAMP_INT = $(ROOT)/deps/ogg_timestamp
|
||||
OGG_TIMESTAMP_INT = $(ANDR_ROOT)/deps/ogg_timestamp
|
||||
OGG_URL_GIT = https://github.com/vincentjames501/libvorbis-libogg-android
|
||||
|
||||
IRRLICHT_DIR = $(ROOT)/deps/irrlicht/
|
||||
IRRLICHT_REVISION = 5122
|
||||
IRRLICHT_DIR = $(ANDR_ROOT)/deps/irrlicht/
|
||||
IRRLICHT_LIB = $(IRRLICHT_DIR)lib/Android/libIrrlicht.a
|
||||
IRRLICHT_TIMESTAMP = $(IRRLICHT_DIR)timestamp
|
||||
IRRLICHT_TIMESTAMP_INT = $(ROOT)/deps/irrlicht_timestamp
|
||||
IRRLICHT_URL_SVN = http://svn.code.sf.net/p/irrlicht/code/branches/ogl-es/
|
||||
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.1l
|
||||
OPENSSL_VERSION = 1.0.2h
|
||||
OPENSSL_BASEDIR = openssl-$(OPENSSL_VERSION)
|
||||
OPENSSL_DIR = $(ROOT)/deps/$(OPENSSL_BASEDIR)/
|
||||
OPENSSL_DIR = $(ANDR_ROOT)/deps/$(OPENSSL_BASEDIR)/
|
||||
OPENSSL_LIB = $(OPENSSL_DIR)/libssl.so.1.0.0
|
||||
OPENSSL_TIMESTAMP = $(OPENSSL_DIR)timestamp
|
||||
OPENSSL_TIMESTAMP_INT = $(ROOT)/deps/openssl_timestamp
|
||||
OPENSSL_URL = http://www.openssl.org/source/openssl-$(OPENSSL_VERSION).tar.gz
|
||||
OPENSSL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openssl_timestamp
|
||||
OPENSSL_URL = https://www.openssl.org/source/openssl-$(OPENSSL_VERSION).tar.gz
|
||||
|
||||
CURL_VERSION = 7.41.0
|
||||
CURL_DIR = $(ROOT)/deps/curl-$(CURL_VERSION)
|
||||
CURL_VERSION = 7.48.0
|
||||
CURL_DIR = $(ANDR_ROOT)/deps/curl-$(CURL_VERSION)
|
||||
CURL_LIB = $(CURL_DIR)/lib/.libs/libcurl.a
|
||||
CURL_TIMESTAMP = $(CURL_DIR)/timestamp
|
||||
CURL_TIMESTAMP_INT = $(ROOT)/deps/curl_timestamp
|
||||
CURL_URL_HTTP = http://curl.haxx.se/download/curl-${CURL_VERSION}.tar.bz2
|
||||
CURL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/curl_timestamp
|
||||
CURL_URL_HTTP = https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.bz2
|
||||
|
||||
GMP_VERSION = 6.0.0
|
||||
GMP_DIR = $(ROOT)/deps/gmp-$(GMP_VERSION)
|
||||
GMP_VERSION = 6.1.0
|
||||
GMP_DIR = $(ANDR_ROOT)/deps/gmp-$(GMP_VERSION)
|
||||
GMP_LIB = $(GMP_DIR)/usr/lib/libgmp.so
|
||||
GMP_TIMESTAMP = $(GMP_DIR)/timestamp
|
||||
GMP_TIMESTAMP_INT = $(ROOT)/deps/gmp_timestamp
|
||||
GMP_TIMESTAMP_INT = $(ANDR_ROOT)/deps/gmp_timestamp
|
||||
GMP_URL_HTTP = https://gmplib.org/download/gmp/gmp-$(GMP_VERSION).tar.bz2
|
||||
|
||||
FREETYPE_DIR = $(ROOT)/deps/freetype2-android/
|
||||
FREETYPE_DIR = $(ANDR_ROOT)/deps/freetype2-android/
|
||||
FREETYPE_LIB = $(FREETYPE_DIR)/Android/obj/local/$(TARGET_ABI)/libfreetype2-static.a
|
||||
FREETYPE_TIMESTAMP = $(FREETYPE_DIR)timestamp
|
||||
FREETYPE_TIMESTAMP_INT = $(ROOT)/deps/freetype_timestamp
|
||||
FREETYPE_TIMESTAMP_INT = $(ANDR_ROOT)/deps/freetype_timestamp
|
||||
FREETYPE_URL_GIT = https://github.com/cdave1/freetype2-android
|
||||
|
||||
ICONV_VERSION = 1.14
|
||||
ICONV_DIR = $(ROOT)/deps/libiconv/
|
||||
ICONV_DIR = $(ANDR_ROOT)/deps/libiconv/
|
||||
ICONV_LIB = $(ICONV_DIR)/lib/.libs/libiconv.so
|
||||
ICONV_TIMESTAMP = $(ICONV_DIR)timestamp
|
||||
ICONV_TIMESTAMP_INT = $(ROOT)/deps/iconv_timestamp
|
||||
ICONV_URL_HTTP = http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz
|
||||
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-3080704
|
||||
SQLITE3_URL = http://www.sqlite.org/2014/$(SQLITE3_FOLDER).zip
|
||||
SQLITE3_FOLDER = sqlite-amalgamation-3120200
|
||||
SQLITE3_URL = https://www.sqlite.org/2016/$(SQLITE3_FOLDER).zip
|
||||
|
||||
-include $(PATHCFGFILE)
|
||||
ANDROID_SDK = $(shell grep '^sdk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
|
||||
ANDROID_NDK = $(shell grep '^ndk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
|
||||
NDK_MODULE_PATH = $(ANDROID_NDK)/toolchains
|
||||
|
||||
#use interim target variable to switch leveldb on or off
|
||||
ifeq ($(HAVE_LEVELDB),1)
|
||||
|
@ -162,54 +145,50 @@ endif
|
|||
freetype_download clean_freetype freetype \
|
||||
apk clean_apk \
|
||||
clean_all clean prep_srcdir \
|
||||
install_debug install envpaths all \
|
||||
manifest clean_manifest\
|
||||
install_debug install_release envpaths all \
|
||||
$(ASSETS_TIMESTAMP) $(LEVELDB_TIMESTAMP) \
|
||||
$(OPENAL_TIMESTAMP) $(OGG_TIMESTAMP) \
|
||||
$(IRRLICHT_TIMESTAMP) $(CURL_TIMESTAMP) \
|
||||
$(OPENSSL_TIMESTAMP) curl_binary \
|
||||
$(ROOT)/jni/src/android_version.h \
|
||||
$(ROOT)/jni/src/android_version_githash.h
|
||||
$(OPENSSL_TIMESTAMP) \
|
||||
$(ANDR_ROOT)/jni/src/android_version.h \
|
||||
$(ANDR_ROOT)/jni/src/android_version_githash.h
|
||||
|
||||
debug : $(PATHCFGFILE)
|
||||
debug : local.properties
|
||||
export NDEBUG=; \
|
||||
export BUILD_TYPE=debug; \
|
||||
$(MAKE) apk
|
||||
|
||||
all : debug release
|
||||
|
||||
release : $(PATHCFGFILE)
|
||||
release : local.properties
|
||||
@export NDEBUG=1; \
|
||||
export BUILD_TYPE=release; \
|
||||
$(MAKE) apk
|
||||
|
||||
reconfig: delconfig
|
||||
@$(MAKE) $(PATHCFGFILE)
|
||||
@$(MAKE) local.properties
|
||||
|
||||
delconfig :
|
||||
$(RM) ${PATHCFGFILE}
|
||||
delconfig:
|
||||
$(RM) local.properties
|
||||
|
||||
$(PATHCFGFILE) :
|
||||
local.properties:
|
||||
@echo "Please specify path of ANDROID NDK"; \
|
||||
echo "e.g. /home/user/android-ndk-r9c/"; \
|
||||
echo "e.g. $$HOME/Android/ndk-r11c/"; \
|
||||
read ANDROID_NDK ; \
|
||||
if [ ! -d $$ANDROID_NDK ] ; then \
|
||||
echo "$$ANDROID_NDK is not a valid folder"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "ANDROID_NDK = $$ANDROID_NDK" > ${PATHCFGFILE}; \
|
||||
echo "NDK_MODULE_PATH = $$ANDROID_NDK/toolchains" >> ${PATHCFGFILE}; \
|
||||
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";\
|
||||
echo "+ Note: NDK_MODULE_PATH is set to $$ANDROID_NDK/toolchains"; \
|
||||
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";\
|
||||
echo "ndk.dir = $$ANDROID_NDK" > local.properties; \
|
||||
echo "Please specify path of ANDROID SDK"; \
|
||||
echo "e.g. /home/user/adt-bundle-linux-x86_64-20131030/sdk/"; \
|
||||
echo "e.g. $$HOME/Android/sdk/"; \
|
||||
read SDKFLDR ; \
|
||||
if [ ! -d $$SDKFLDR ] ; then \
|
||||
echo "$$SDKFLDR is not a valid folder"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "SDKFOLDER = $$SDKFLDR" >> ${PATHCFGFILE};
|
||||
echo "sdk.dir = $$SDKFLDR" >> local.properties;
|
||||
|
||||
|
||||
$(OPENAL_TIMESTAMP) : openal_download
|
||||
@LAST_MODIF=$$(find ${OPENAL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
|
||||
|
@ -220,15 +199,15 @@ $(OPENAL_TIMESTAMP) : openal_download
|
|||
openal_download :
|
||||
@if [ ! -d ${OPENAL_DIR} ] ; then \
|
||||
echo "openal sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
cd ${ROOT}/deps ; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd ${ANDR_ROOT}/deps ; \
|
||||
git clone ${OPENAL_URL_GIT} || exit 1; \
|
||||
fi
|
||||
|
||||
openal : $(OPENAL_LIB)
|
||||
|
||||
$(OPENAL_LIB): $(OPENAL_TIMESTAMP)
|
||||
@REFRESH=0; \
|
||||
+ @REFRESH=0; \
|
||||
if [ ! -e ${OPENAL_TIMESTAMP_INT} ] ; then \
|
||||
REFRESH=1; \
|
||||
fi; \
|
||||
|
@ -236,14 +215,14 @@ $(OPENAL_LIB): $(OPENAL_TIMESTAMP)
|
|||
REFRESH=1; \
|
||||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
export PATH=$$PATH:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \
|
||||
echo "changed timestamp for openal detected building..."; \
|
||||
cd ${OPENAL_DIR}; \
|
||||
ndk-build NDEBUG=${NDEBUG} NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_ABI=${TARGET_ABI} TARGET_ARCH_ABI=${TARGET_ABI} \
|
||||
APP_PLATFORM=${APP_PLATFORM} TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} APP_ABI=${TARGET_ABI} \
|
||||
TARGET_ARCH_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
touch ${OPENAL_TIMESTAMP}; \
|
||||
touch ${OPENAL_TIMESTAMP_INT}; \
|
||||
else \
|
||||
|
@ -262,18 +241,18 @@ $(OGG_TIMESTAMP) : ogg_download
|
|||
ogg_download :
|
||||
@if [ ! -d ${OGG_DIR} ] ; then \
|
||||
echo "ogg sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
cd ${ROOT}/deps ; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd ${ANDR_ROOT}/deps ; \
|
||||
git clone ${OGG_URL_GIT}|| exit 1; \
|
||||
cd libvorbis-libogg-android ; \
|
||||
patch -p1 < ../../libvorbis-libogg-fpu.patch || exit 1; \
|
||||
patch -p1 < ${ANDR_ROOT}/patches/libvorbis-libogg-fpu.patch || exit 1; \
|
||||
sed -i 's-:-?-' jni/Application.mk; \
|
||||
fi
|
||||
|
||||
ogg : $(OGG_LIB)
|
||||
|
||||
$(OGG_LIB): $(OGG_TIMESTAMP)
|
||||
@REFRESH=0; \
|
||||
+ @REFRESH=0; \
|
||||
if [ ! -e ${OGG_TIMESTAMP_INT} ] ; then \
|
||||
echo "${OGG_TIMESTAMP_INT} doesn't exist"; \
|
||||
REFRESH=1; \
|
||||
|
@ -282,14 +261,14 @@ $(OGG_LIB): $(OGG_TIMESTAMP)
|
|||
REFRESH=1; \
|
||||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
export PATH=$$PATH:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \
|
||||
echo "changed timestamp for ogg detected building..."; \
|
||||
cd ${OGG_DIR}; \
|
||||
ndk-build NDEBUG=${NDEBUG} NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
touch ${OGG_TIMESTAMP}; \
|
||||
touch ${OGG_TIMESTAMP_INT}; \
|
||||
else \
|
||||
|
@ -308,17 +287,17 @@ $(OPENSSL_TIMESTAMP) : openssl_download
|
|||
openssl_download :
|
||||
@if [ ! -d ${OPENSSL_DIR} ] ; then \
|
||||
echo "openssl sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
cd ${ROOT}/deps ; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd ${ANDR_ROOT}/deps ; \
|
||||
wget ${OPENSSL_URL} || exit 1; \
|
||||
tar -xzf ${OPENSSL_BASEDIR}.tar.gz; \
|
||||
cd ${OPENSSL_BASEDIR}; \
|
||||
patch -p1 < ../../openssl_arch.patch; \
|
||||
patch -p1 < ${ANDR_ROOT}/patches/openssl_arch.patch; \
|
||||
fi
|
||||
|
||||
openssl : $(OPENSSL_LIB)
|
||||
|
||||
$(OPENSSL_LIB): $(OPENSSL_TIMESTAMP)
|
||||
$(OPENSSL_LIB): $(OPENSSL_TIMESTAMP) $(GMP_LIB)
|
||||
@REFRESH=0; \
|
||||
if [ ! -e ${OPENSSL_TIMESTAMP_INT} ] ; then \
|
||||
echo "${OPENSSL_TIMESTAMP_INT} doesn't exist"; \
|
||||
|
@ -333,10 +312,11 @@ $(OPENSSL_LIB): $(OPENSSL_TIMESTAMP)
|
|||
ln -s ${OPENSSL_DIR} ../openssl; \
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-openssl; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
CC=${CROSS_PREFIX}gcc ./Configure android-${TARGET_ARCH} no-idea no-seed -no-sha0 -DL_ENDIAN;\
|
||||
CC=${CROSS_PREFIX}gcc ./Configure enable-gmp -DL_ENDIAN -I${GMP_DIR} -L${GMP_DIR}/usr/lib android-${TARGET_ARCH};\
|
||||
CC=${CROSS_PREFIX}gcc ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make depend; \
|
||||
CC=${CROSS_PREFIX}gcc ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make build_libs; \
|
||||
touch ${OPENSSL_TIMESTAMP}; \
|
||||
touch ${OPENSSL_TIMESTAMP_INT}; \
|
||||
|
@ -347,8 +327,8 @@ $(OPENSSL_LIB): $(OPENSSL_TIMESTAMP)
|
|||
|
||||
clean_openssl :
|
||||
$(RM) -rf ${OPENSSL_DIR}; \
|
||||
$(RM) -rf $(ROOT)/deps/${OPENSSL_BASEDIR}.tar.gz; \
|
||||
$(RM) -rf $(ROOT)/deps/openssl
|
||||
$(RM) -rf $(ANDR_ROOT)/deps/${OPENSSL_BASEDIR}.tar.gz; \
|
||||
$(RM) -rf $(ANDR_ROOT)/deps/openssl
|
||||
|
||||
$(LEVELDB_TIMESTAMP) : leveldb_download
|
||||
@LAST_MODIF=$$(find ${LEVELDB_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
|
||||
|
@ -359,9 +339,11 @@ $(LEVELDB_TIMESTAMP) : leveldb_download
|
|||
leveldb_download :
|
||||
@if [ ! -d ${LEVELDB_DIR} ] ; then \
|
||||
echo "leveldb sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
cd ${ROOT}/deps ; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd ${ANDR_ROOT}/deps ; \
|
||||
git clone ${LEVELDB_URL_GIT} || exit 1; \
|
||||
cd ${LEVELDB_DIR} || exit 1; \
|
||||
git checkout ${LEVELDB_COMMIT} || exit 1; \
|
||||
fi
|
||||
|
||||
leveldb : $(LEVELDB_LIB)
|
||||
|
@ -375,22 +357,21 @@ $(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
|
|||
REFRESH=1; \
|
||||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
export PATH=$${PATH}:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \
|
||||
echo "changed timestamp for leveldb detected building..."; \
|
||||
cd deps/leveldb; \
|
||||
export CROSS_PREFIX=${CROSS_PREFIX}; \
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-leveldb; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
export CXX=${CROSS_PREFIX}g++; \
|
||||
export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
|
||||
export CPPFLAGS="$${CPPFLAGS} ${TARGET_CFLAGS_ADDON}"; \
|
||||
export CPPFLAGS="$${CPPFLAGS} ${TARGET_CXXFLAGS_ADDON}"; \
|
||||
export LDFLAGS="$${LDFLAGS} ${TARGET_LDFLAGS_ADDON}"; \
|
||||
export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
|
||||
$(MAKE) -s || exit 1; \
|
||||
$(MAKE) || exit 1; \
|
||||
touch ${LEVELDB_TIMESTAMP}; \
|
||||
touch ${LEVELDB_TIMESTAMP_INT}; \
|
||||
$(RM) -rf $${TOOLCHAIN}; \
|
||||
|
@ -410,7 +391,7 @@ $(FREETYPE_TIMESTAMP) : freetype_download
|
|||
freetype_download :
|
||||
@if [ ! -d ${FREETYPE_DIR} ] ; then \
|
||||
echo "freetype sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd deps; \
|
||||
git clone ${FREETYPE_URL_GIT} || exit 1; \
|
||||
fi
|
||||
|
@ -418,7 +399,7 @@ freetype_download :
|
|||
freetype : $(FREETYPE_LIB)
|
||||
|
||||
$(FREETYPE_LIB) : $(FREETYPE_TIMESTAMP)
|
||||
@REFRESH=0; \
|
||||
+ @REFRESH=0; \
|
||||
if [ ! -e ${FREETYPE_TIMESTAMP_INT} ] ; then \
|
||||
REFRESH=1; \
|
||||
fi; \
|
||||
|
@ -430,14 +411,14 @@ $(FREETYPE_LIB) : $(FREETYPE_TIMESTAMP)
|
|||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
mkdir -p ${FREETYPE_DIR}; \
|
||||
export PATH=$$PATH:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \
|
||||
echo "changed timestamp for freetype detected building..."; \
|
||||
cd ${FREETYPE_DIR}/Android/jni; \
|
||||
ndk-build NDEBUG=${NDEBUG} NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_PLATFORM=${APP_PLATFORM} APP_ABI=${TARGET_ABI} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_PLATFORM=${APP_PLATFORM} APP_ABI=${TARGET_ABI} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
touch ${FREETYPE_TIMESTAMP}; \
|
||||
touch ${FREETYPE_TIMESTAMP_INT}; \
|
||||
else \
|
||||
|
@ -456,15 +437,15 @@ $(ICONV_TIMESTAMP) : iconv_download
|
|||
iconv_download :
|
||||
@if [ ! -d ${ICONV_DIR} ] ; then \
|
||||
echo "iconv sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
cd ${ROOT}/deps; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd ${ANDR_ROOT}/deps; \
|
||||
wget ${ICONV_URL_HTTP} || exit 1; \
|
||||
tar -xzf libiconv-${ICONV_VERSION}.tar.gz || exit 1; \
|
||||
rm libiconv-${ICONV_VERSION}.tar.gz; \
|
||||
ln -s libiconv-${ICONV_VERSION} libiconv; \
|
||||
cd ${ICONV_DIR}; \
|
||||
patch -p1 < ${ROOT}/libiconv_android.patch; \
|
||||
patch -p1 < ${ROOT}/libiconv_stdio.patch; \
|
||||
patch -p1 < ${ANDR_ROOT}/patches/libiconv_android.patch; \
|
||||
patch -p1 < ${ANDR_ROOT}/patches/libiconv_stdio.patch; \
|
||||
fi
|
||||
|
||||
iconv : $(ICONV_LIB)
|
||||
|
@ -482,14 +463,13 @@ $(ICONV_LIB) : $(ICONV_TIMESTAMP)
|
|||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
mkdir -p ${ICONV_DIR}; \
|
||||
export PATH=$$PATH:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \
|
||||
echo "changed timestamp for iconv detected building..."; \
|
||||
cd ${ICONV_DIR}; \
|
||||
\
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-iconv; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
export CXX=${CROSS_PREFIX}g++; \
|
||||
|
@ -516,13 +496,13 @@ clean_iconv :
|
|||
irrlicht_download :
|
||||
@if [ ! -d "deps/irrlicht" ] ; then \
|
||||
echo "irrlicht sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd deps; \
|
||||
svn co ${IRRLICHT_URL_SVN} irrlicht || exit 1; \
|
||||
cd irrlicht; \
|
||||
patch -p1 < ../../irrlicht-touchcount.patch || exit 1; \
|
||||
patch -p1 < ../../irrlicht-back_button.patch || exit 1; \
|
||||
patch -p1 < ../../irrlicht-texturehack.patch || exit 1; \
|
||||
patch -p1 < ${ANDR_ROOT}/patches/irrlicht-touchcount.patch || exit 1; \
|
||||
patch -p1 < ${ANDR_ROOT}/patches/irrlicht-back_button.patch || exit 1; \
|
||||
patch -p1 < ${ANDR_ROOT}/patches/irrlicht-texturehack.patch || exit 1; \
|
||||
fi
|
||||
|
||||
$(IRRLICHT_TIMESTAMP) : irrlicht_download
|
||||
|
@ -534,7 +514,7 @@ $(IRRLICHT_TIMESTAMP) : irrlicht_download
|
|||
irrlicht : $(IRRLICHT_LIB)
|
||||
|
||||
$(IRRLICHT_LIB): $(IRRLICHT_TIMESTAMP) $(FREETYPE_LIB)
|
||||
@REFRESH=0; \
|
||||
+ @REFRESH=0; \
|
||||
if [ ! -e ${IRRLICHT_TIMESTAMP_INT} ] ; then \
|
||||
REFRESH=1; \
|
||||
fi; \
|
||||
|
@ -546,14 +526,14 @@ $(IRRLICHT_LIB): $(IRRLICHT_TIMESTAMP) $(FREETYPE_LIB)
|
|||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
mkdir -p ${IRRLICHT_DIR}; \
|
||||
export PATH=$$PATH:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \
|
||||
echo "changed timestamp for irrlicht detected building..."; \
|
||||
cd deps/irrlicht/source/Irrlicht/Android; \
|
||||
ndk-build NDEBUG=${NDEBUG} NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
touch ${IRRLICHT_TIMESTAMP}; \
|
||||
touch ${IRRLICHT_TIMESTAMP_INT}; \
|
||||
else \
|
||||
|
@ -572,7 +552,7 @@ $(CURL_TIMESTAMP) : curl_download
|
|||
curl_download :
|
||||
@if [ ! -d "deps/curl-${CURL_VERSION}" ] ; then \
|
||||
echo "curl sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd deps; \
|
||||
wget ${CURL_URL_HTTP} || exit 1; \
|
||||
tar -xjf curl-${CURL_VERSION}.tar.bz2 || exit 1; \
|
||||
|
@ -595,20 +575,18 @@ $(CURL_LIB): $(CURL_TIMESTAMP) $(OPENSSL_LIB)
|
|||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
mkdir -p ${CURL_DIR}; \
|
||||
export PATH="$${PATH}:${SDKFOLDER}/platform-tools:${ANDROID_NDK}"; \
|
||||
echo "changed timestamp for curl detected building..."; \
|
||||
cd deps/curl-${CURL_VERSION}; \
|
||||
export CROSS_PREFIX=${CROSS_PREFIX}; \
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-curl; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
export CXX=${CROSS_PREFIX}g++; \
|
||||
export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
|
||||
export CPPFLAGS="$${CPPFLAGS} -I${OPENSSL_DIR}/include \
|
||||
-L${OPENSSL_DIR} ${TARGET_CFLAGS_ADDON}"; \
|
||||
export CPPFLAGS="$${CPPFLAGS} -I${OPENSSL_DIR}/include ${TARGET_CFLAGS_ADDON}"; \
|
||||
export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
|
||||
export LDFLAGS="$${LDFLAGS} -L${OPENSSL_DIR} ${TARGET_LDFLAGS_ADDON}"; \
|
||||
./configure --host=${TARGET_HOST} --disable-shared --enable-static --with-ssl; \
|
||||
|
@ -624,18 +602,6 @@ clean_curl :
|
|||
$(RM) -rf deps/curl-${CURL_VERSION} \
|
||||
$(RM) -f deps/curl
|
||||
|
||||
|
||||
curl_binary:
|
||||
@if [ ! -d "deps/curl-${CURL_VERSION_BINARY}" ] ; then \
|
||||
echo "curl binary missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
cd deps; \
|
||||
wget http://curl.haxx.se/gknw.net/7.34.0/dist-android/curl-7.34.0-rtmp-ssh2-ssl-zlib-static-bin-android.tar.gz || exit 1;\
|
||||
tar -xzf curl-7.34.0-rtmp-ssh2-ssl-zlib-static-bin-android.tar.gz || exit 1;\
|
||||
mv curl-7.34.0-rtmp-ssh2-ssl-zlib-static-bin-android curl-${CURL_VERSION_BINARY};\
|
||||
rm curl-7.34.0-rtmp-ssh2-ssl-zlib-static-bin-android.tar.gz; \
|
||||
fi
|
||||
|
||||
$(GMP_TIMESTAMP) : gmp_download
|
||||
@LAST_MODIF=$$(find ${GMP_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
|
||||
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
|
||||
|
@ -645,7 +611,7 @@ $(GMP_TIMESTAMP) : gmp_download
|
|||
gmp_download :
|
||||
@if [ ! -d "${GMP_DIR}" ] ; then \
|
||||
echo "gmp sources missing, downloading..."; \
|
||||
mkdir -p ${ROOT}/deps; \
|
||||
mkdir -p ${ANDR_ROOT}/deps; \
|
||||
cd deps; \
|
||||
wget ${GMP_URL_HTTP} || exit 1; \
|
||||
tar -xjf gmp-${GMP_VERSION}.tar.bz2 || exit 1; \
|
||||
|
@ -668,14 +634,13 @@ $(GMP_LIB): $(GMP_TIMESTAMP)
|
|||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
mkdir -p ${GMP_DIR}; \
|
||||
export PATH="$${PATH}:${SDKFOLDER}/platform-tools:${ANDROID_NDK}"; \
|
||||
echo "changed timestamp for gmp detected building..."; \
|
||||
cd deps/gmp-${GMP_VERSION}; \
|
||||
export CROSS_PREFIX=${CROSS_PREFIX}; \
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-gmp; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
export CXX=${CROSS_PREFIX}g++; \
|
||||
|
@ -707,11 +672,11 @@ clean_sqlite3:
|
|||
$(RM) -f sqlite
|
||||
|
||||
$(ASSETS_TIMESTAMP) : $(IRRLICHT_LIB)
|
||||
@mkdir -p ${ROOT}/deps; \
|
||||
@mkdir -p ${ANDR_ROOT}/deps; \
|
||||
for DIRNAME in {builtin,client,doc,fonts,games,mods,po,textures}; do \
|
||||
LAST_MODIF=$$(find ${ROOT}/../../${DIRNAME} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
|
||||
LAST_MODIF=$$(find ${PROJ_ROOT}/${DIRNAME} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
|
||||
if [ $$(basename $$LAST_MODIF) != "timestamp" ]; then \
|
||||
touch ${ROOT}/../../${DIRNAME}/timestamp; \
|
||||
touch ${PROJ_ROOT}/${DIRNAME}/timestamp; \
|
||||
touch ${ASSETS_TIMESTAMP}; \
|
||||
echo ${DIRNAME} changed $$LAST_MODIF; \
|
||||
fi; \
|
||||
|
@ -721,11 +686,11 @@ $(ASSETS_TIMESTAMP) : $(IRRLICHT_LIB)
|
|||
touch ${IRRLICHT_DIR}/media/timestamp; \
|
||||
touch ${ASSETS_TIMESTAMP}; \
|
||||
fi; \
|
||||
if [ ${ROOT}/../../minetest.conf.example -nt ${ASSETS_TIMESTAMP} ] ; then \
|
||||
if [ ${PROJ_ROOT}/minetest.conf.example -nt ${ASSETS_TIMESTAMP} ] ; then \
|
||||
echo "conf changed"; \
|
||||
touch ${ASSETS_TIMESTAMP}; \
|
||||
fi; \
|
||||
if [ ${ROOT}/../../README.txt -nt ${ASSETS_TIMESTAMP} ] ; then \
|
||||
if [ ${PROJ_ROOT}/README.txt -nt ${ASSETS_TIMESTAMP} ] ; then \
|
||||
touch ${ASSETS_TIMESTAMP}; \
|
||||
fi; \
|
||||
if [ ! -e $(ASSETS_TIMESTAMP) ] ; then \
|
||||
|
@ -740,32 +705,34 @@ assets : $(ASSETS_TIMESTAMP)
|
|||
if [ ${ASSETS_TIMESTAMP} -nt ${ASSETS_TIMESTAMP}.old ] ; then \
|
||||
REFRESH=1; \
|
||||
fi; \
|
||||
if [ ! -d ${ROOT}/assets ] ; then \
|
||||
if [ ! -d ${APP_ROOT}/assets ] ; then \
|
||||
REFRESH=1; \
|
||||
fi; \
|
||||
if [ $$REFRESH -ne 0 ] ; then \
|
||||
echo "assets changed, refreshing..."; \
|
||||
$(MAKE) clean_assets; \
|
||||
mkdir -p ${ROOT}/assets/Minetest; \
|
||||
cp ${ROOT}/../../minetest.conf.example ${ROOT}/assets/Minetest; \
|
||||
cp ${ROOT}/../../README.txt ${ROOT}/assets/Minetest; \
|
||||
cp -r ${ROOT}/../../builtin ${ROOT}/assets/Minetest; \
|
||||
cp -r ${ROOT}/../../client ${ROOT}/assets/Minetest; \
|
||||
cp -r ${ROOT}/../../doc ${ROOT}/assets/Minetest; \
|
||||
cp -r ${ROOT}/../../fonts ${ROOT}/assets/Minetest; \
|
||||
mkdir ${ROOT}/assets/Minetest/games; \
|
||||
mkdir -p ${APP_ROOT}/assets/Minetest; \
|
||||
cp ${PROJ_ROOT}/minetest.conf.example ${APP_ROOT}/assets/Minetest; \
|
||||
cp ${PROJ_ROOT}/README.txt ${APP_ROOT}/assets/Minetest; \
|
||||
cp -r ${PROJ_ROOT}/builtin ${APP_ROOT}/assets/Minetest; \
|
||||
mkdir -p ${APP_ROOT}/assets/Minetest/client; \
|
||||
cp -r ${PROJ_ROOT}/client/shaders ${APP_ROOT}/assets/Minetest/client; \
|
||||
cp ${PROJ_ROOT}/doc/lgpl-2.1.txt ${APP_ROOT}/assets/Minetest/LICENSE.txt; \
|
||||
mkdir -p ${APP_ROOT}/assets/Minetest/fonts; \
|
||||
cp -r ${PROJ_ROOT}/fonts/*.ttf ${APP_ROOT}/assets/Minetest/fonts/; \
|
||||
mkdir -p ${APP_ROOT}/assets/Minetest/games; \
|
||||
for game in ${GAMES_TO_COPY}; do \
|
||||
cp -r ${ROOT}/../../games/$$game ${ROOT}/assets/Minetest/games/; \
|
||||
cp -r ${PROJ_ROOT}/games/$$game ${APP_ROOT}/assets/Minetest/games/; \
|
||||
done; \
|
||||
mkdir ${ROOT}/assets/Minetest/mods; \
|
||||
mkdir -p ${APP_ROOT}/assets/Minetest/mods; \
|
||||
for mod in ${MODS_TO_COPY}; do \
|
||||
cp -r ${ROOT}/../../mods/$$mod ${ROOT}/assets/Minetest/mods/; \
|
||||
cp -r ${PROJ_ROOT}/mods/$$mod ${APP_ROOT}/assets/Minetest/mods/; \
|
||||
done; \
|
||||
cp -r ${ROOT}/../../po ${ROOT}/assets/Minetest; \
|
||||
cp -r ${ROOT}/../../textures ${ROOT}/assets/Minetest; \
|
||||
mkdir -p ${ROOT}/assets/Minetest/media; \
|
||||
cp -r ${IRRLICHT_DIR}/media/Shaders ${ROOT}/assets/Minetest/media; \
|
||||
cd ${ROOT}/assets || exit 1; \
|
||||
cp -r ${PROJ_ROOT}/po ${APP_ROOT}/assets/Minetest; \
|
||||
cp -r ${PROJ_ROOT}/textures ${APP_ROOT}/assets/Minetest; \
|
||||
mkdir -p ${APP_ROOT}/assets/Minetest/media; \
|
||||
cp -r ${IRRLICHT_DIR}/media/Shaders ${APP_ROOT}/assets/Minetest/media; \
|
||||
cd ${APP_ROOT}/assets || exit 1; \
|
||||
find . -name "timestamp" -exec rm {} \; ; \
|
||||
find . -name "*.blend" -exec rm {} \; ; \
|
||||
find . -name "*~" -exec rm {} \; ; \
|
||||
|
@ -773,8 +740,8 @@ assets : $(ASSETS_TIMESTAMP)
|
|||
find . -type d -path "*.svn" -exec rm -rf {} \; ; \
|
||||
find . -type f -path "*.gitignore" -exec rm -rf {} \; ; \
|
||||
ls -R | grep ":$$" | sed -e 's/:$$//' -e 's/\.//' -e 's/^\///' > "index.txt"; \
|
||||
find Minetest >"filelist.txt"; \
|
||||
cp ${ROOT}/${ASSETS_TIMESTAMP} ${ROOT}/${ASSETS_TIMESTAMP}.old; \
|
||||
find -L Minetest > filelist.txt; \
|
||||
cp ${ANDR_ROOT}/${ASSETS_TIMESTAMP} ${ANDR_ROOT}/${ASSETS_TIMESTAMP}.old; \
|
||||
else \
|
||||
echo "nothing to be done for assets"; \
|
||||
fi
|
||||
|
@ -782,56 +749,50 @@ assets : $(ASSETS_TIMESTAMP)
|
|||
clean_assets :
|
||||
@$(RM) -r assets
|
||||
|
||||
apk: $(PATHCFGFILE) assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(GMP_LIB) $(LEVELDB_TARGET) \
|
||||
$(OPENAL_LIB) $(OGG_LIB) prep_srcdir $(ROOT)/jni/src/android_version.h \
|
||||
$(ROOT)/jni/src/android_version_githash.h sqlite3_download
|
||||
@export NDEBUG=$$NDEBUG; $(MAKE) manifest; \
|
||||
export PATH=$$PATH:${SDKFOLDER}/platform-tools:${ANDROID_NDK}; \
|
||||
export ANDROID_HOME=${SDKFOLDER}; \
|
||||
mkdir -p ${ROOT}/src; \
|
||||
ndk-build NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
GPROF=${GPROF} APP_ABI=${TARGET_ABI} HAVE_LEVELDB=${HAVE_LEVELDB} \
|
||||
APP_PLATFORM=${APP_PLATFORM} \
|
||||
TARGET_LIBDIR=${TARGET_LIBDIR} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" && \
|
||||
ant $$BUILD_TYPE && \
|
||||
echo "++ Success!" && \
|
||||
echo "APK: bin/Minetest-$$BUILD_TYPE.apk" && \
|
||||
echo "You can install it with \`adb install -r bin/Minetest-$$BUILD_TYPE.apk\`"
|
||||
apk: local.properties assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(GMP_LIB) $(LEVELDB_TARGET) \
|
||||
$(OPENAL_LIB) $(OGG_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \
|
||||
$(ANDR_ROOT)/jni/src/android_version_githash.h sqlite3_download
|
||||
+ @${ANDROID_NDK}/ndk-build NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
GPROF=${GPROF} APP_ABI=${TARGET_ABI} HAVE_LEVELDB=${HAVE_LEVELDB} \
|
||||
APP_PLATFORM=${APP_PLATFORM} \
|
||||
TARGET_LIBDIR=${TARGET_LIBDIR} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
if [ ! -e ${APP_ROOT}/jniLibs ]; then \
|
||||
ln -s ${ANDR_ROOT}/libs ${APP_ROOT}/jniLibs || exit 1; \
|
||||
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 && \
|
||||
echo "APK stored at: build/outputs/apk/Minetest-$$BUILD_TYPE.apk" && \
|
||||
echo "You can install it with \`make install_$$BUILD_TYPE\`"
|
||||
|
||||
# These Intentionally doesn't depend on their respective build steps,
|
||||
# because it takes a while to verify that everything's up-to-date.
|
||||
install_debug:
|
||||
${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/Minetest-debug.apk
|
||||
|
||||
install_release:
|
||||
${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/Minetest-release.apk
|
||||
|
||||
prep_srcdir :
|
||||
@if [ ! -e ${ROOT}/jni/src ]; then \
|
||||
ln -s ${ROOT}/../../src ${ROOT}/jni/src; \
|
||||
@if [ ! -e ${ANDR_ROOT}/jni/src ]; then \
|
||||
ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \
|
||||
fi
|
||||
|
||||
clean_apk : manifest
|
||||
@export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \
|
||||
export ANDROID_HOME=${SDKFOLDER}; \
|
||||
ant clean
|
||||
|
||||
install_debug :
|
||||
@export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \
|
||||
adb install -r ${ROOT}/bin/Minetest-debug.apk
|
||||
|
||||
install :
|
||||
@export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \
|
||||
adb install -r ${ROOT}/bin/Minetest-release.apk
|
||||
|
||||
envpaths :
|
||||
@echo "export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}" > and_env;\
|
||||
echo "export ANDROID_HOME=${SDKFOLDER}" >> and_env;
|
||||
clean_apk :
|
||||
gradle clean
|
||||
|
||||
clean_all :
|
||||
@$(MAKE) clean_apk; \
|
||||
$(MAKE) clean_assets clean_iconv clean_irrlicht clean_leveldb clean_curl clean_openssl \
|
||||
clean_openal clean_ogg clean_gmp clean_manifest; \
|
||||
$(MAKE) clean_assets clean_iconv clean_irrlicht clean_leveldb clean_curl \
|
||||
clean_openssl clean_openal clean_ogg clean_gmp; \
|
||||
sleep 1; \
|
||||
$(RM) -r gen libs obj deps bin Debug and_env
|
||||
|
||||
$(ROOT)/jni/src/android_version_githash.h : prep_srcdir
|
||||
@export VERSION_FILE=${ROOT}/jni/src/android_version_githash.h; \
|
||||
$(ANDR_ROOT)/jni/src/android_version_githash.h : prep_srcdir
|
||||
@export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version_githash.h; \
|
||||
export VERSION_FILE_NEW=$${VERSION_FILE}.new; \
|
||||
{ \
|
||||
echo "#ifndef ANDROID_MT_VERSION_GITHASH_H"; \
|
||||
|
@ -849,8 +810,8 @@ $(ROOT)/jni/src/android_version_githash.h : prep_srcdir
|
|||
fi
|
||||
|
||||
|
||||
$(ROOT)/jni/src/android_version.h : prep_srcdir
|
||||
@export VERSION_FILE=${ROOT}/jni/src/android_version.h; \
|
||||
$(ANDR_ROOT)/jni/src/android_version.h : prep_srcdir
|
||||
@export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version.h; \
|
||||
export VERSION_FILE_NEW=$${VERSION_FILE}.new; \
|
||||
{ \
|
||||
echo "#ifndef ANDROID_MT_VERSION_H"; \
|
||||
|
@ -858,8 +819,8 @@ $(ROOT)/jni/src/android_version.h : prep_srcdir
|
|||
echo "#define VERSION_MAJOR ${VERSION_MAJOR}"; \
|
||||
echo "#define VERSION_MINOR ${VERSION_MINOR}"; \
|
||||
echo "#define VERSION_PATCH ${VERSION_PATCH}"; \
|
||||
echo "#define VERSION_STRING STR(VERSION_MAJOR)\".\"STR(VERSION_MINOR)\
|
||||
\".\"STR(VERSION_PATCH)"; \
|
||||
echo "#define VERSION_STRING STR(VERSION_MAJOR) \".\" STR(VERSION_MINOR) \
|
||||
\".\" STR(VERSION_PATCH)"; \
|
||||
echo "#endif"; \
|
||||
} > $${VERSION_FILE_NEW}; \
|
||||
if ! cmp -s $${VERSION_FILE} $${VERSION_FILE_NEW}; then \
|
||||
|
@ -869,22 +830,5 @@ $(ROOT)/jni/src/android_version.h : prep_srcdir
|
|||
rm "$${VERSION_FILE_NEW}"; \
|
||||
fi
|
||||
|
||||
manifest :
|
||||
@BASE_VERSION="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"; \
|
||||
if [ "${NDEBUG}x" != "x" ] ; then \
|
||||
DBG=''; \
|
||||
DBG_FLAG="android:debuggable=\"false\""; \
|
||||
else \
|
||||
DBG="<uses-permission android:name=\"android.permission.SET_DEBUG_APP\" />"; \
|
||||
DBG_FLAG="android:debuggable=\"true\""; \
|
||||
fi; \
|
||||
cat ${ROOT}/AndroidManifest.xml.template | \
|
||||
sed "s/###ANDROID_VERSION###/${ANDROID_VERSION_CODE}/g" | \
|
||||
sed "s/###BASE_VERSION###/$$BASE_VERSION/g" | \
|
||||
sed -e "s@###DEBUG_BUILD###@$$DBG@g" | \
|
||||
sed -e "s@###DEBUG_FLAG###@$$DBG_FLAG@g" >${ROOT}/AndroidManifest.xml
|
||||
|
||||
clean_manifest :
|
||||
rm -rf ${ROOT}/AndroidManifest.xml
|
||||
|
||||
clean : clean_apk clean_assets
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:1.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.android.application"
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.3"
|
||||
|
||||
defaultConfig {
|
||||
versionCode 14
|
||||
versionName "${System.env.VERSION_STR}.${versionCode}"
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 9
|
||||
applicationId "net.minetest.minetest"
|
||||
manifestPlaceholders = [ package: "net.minetest.minetest", project: project.name ]
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable "OldTargetApi", "GoogleAppIndexingWarning"
|
||||
}
|
||||
|
||||
Properties props = new Properties()
|
||||
props.load(new FileInputStream(file("local.properties")))
|
||||
|
||||
if (props.getProperty("keystore") != null) {
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file(props["keystore"])
|
||||
storePassword props["keystore.password"]
|
||||
keyAlias props["key"]
|
||||
keyPassword props["key.password"]
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Minetest" default="help">
|
||||
<property file="local.properties" />
|
||||
<property file="ant.properties" />
|
||||
<property environment="env" />
|
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||
<isset property="env.ANDROID_HOME" />
|
||||
</condition>
|
||||
<loadproperties srcFile="project.properties" />
|
||||
<fail
|
||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||
unless="sdk.dir"
|
||||
/>
|
||||
<import file="custom_rules.xml" optional="true" />
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
</project>
|
|
@ -69,18 +69,18 @@ GPROF_DEF=-DGPROF
|
|||
endif
|
||||
|
||||
LOCAL_CFLAGS := -D_IRR_ANDROID_PLATFORM_ \
|
||||
-DHAVE_TOUCHSCREENGUI \
|
||||
-DUSE_CURL=1 \
|
||||
-DUSE_SOUND=1 \
|
||||
-DUSE_FREETYPE=1 \
|
||||
-DUSE_LEVELDB=$(HAVE_LEVELDB) \
|
||||
$(GPROF_DEF) \
|
||||
-pipe -fstrict-aliasing
|
||||
-DHAVE_TOUCHSCREENGUI \
|
||||
-DUSE_CURL=1 \
|
||||
-DUSE_SOUND=1 \
|
||||
-DUSE_FREETYPE=1 \
|
||||
-DUSE_LEVELDB=$(HAVE_LEVELDB) \
|
||||
$(GPROF_DEF) \
|
||||
-pipe -fstrict-aliasing
|
||||
|
||||
ifndef NDEBUG
|
||||
LOCAL_CFLAGS += -g -D_DEBUG -O0 -fno-omit-frame-pointer
|
||||
else
|
||||
LOCAL_CFLAGS += -fexpensive-optimizations -O3
|
||||
LOCAL_CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifdef GPROF
|
||||
|
@ -95,8 +95,8 @@ ifeq ($(TARGET_ARCH_ABI),x86)
|
|||
LOCAL_CFLAGS += -fno-stack-protector
|
||||
endif
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/src jni/src/sqlite \
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/src \
|
||||
jni/src/script \
|
||||
jni/src/lua/src \
|
||||
jni/src/json \
|
||||
|
@ -111,8 +111,7 @@ LOCAL_C_INCLUDES := \
|
|||
deps/leveldb/include \
|
||||
deps/sqlite/
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
jni/src/areastore.cpp \
|
||||
LOCAL_SRC_FILES := \
|
||||
jni/src/ban.cpp \
|
||||
jni/src/camera.cpp \
|
||||
jni/src/cavegen.cpp \
|
||||
|
@ -173,11 +172,13 @@ LOCAL_SRC_FILES := \
|
|||
jni/src/mapblock.cpp \
|
||||
jni/src/mapblock_mesh.cpp \
|
||||
jni/src/mapgen.cpp \
|
||||
jni/src/mapgen_flat.cpp \
|
||||
jni/src/mapgen_fractal.cpp \
|
||||
jni/src/mapgen_singlenode.cpp \
|
||||
jni/src/mapgen_v5.cpp \
|
||||
jni/src/mapgen_v6.cpp \
|
||||
jni/src/mapgen_v7.cpp \
|
||||
jni/src/mapgen_valleys.cpp \
|
||||
jni/src/mapnode.cpp \
|
||||
jni/src/mapsector.cpp \
|
||||
jni/src/mesh.cpp \
|
||||
|
@ -219,6 +220,7 @@ LOCAL_SRC_FILES := \
|
|||
jni/src/version.cpp \
|
||||
jni/src/voxel.cpp \
|
||||
jni/src/voxelalgorithms.cpp \
|
||||
jni/src/util/areastore.cpp \
|
||||
jni/src/util/auth.cpp \
|
||||
jni/src/util/base64.cpp \
|
||||
jni/src/util/directiontables.cpp \
|
||||
|
@ -259,7 +261,7 @@ LOCAL_SRC_FILES := \
|
|||
# intentionally kept out (we already build openssl itself): jni/src/util/sha256.c
|
||||
|
||||
# Network
|
||||
LOCAL_SRC_FILES += \
|
||||
LOCAL_SRC_FILES += \
|
||||
jni/src/network/connection.cpp \
|
||||
jni/src/network/networkpacket.cpp \
|
||||
jni/src/network/clientopcodes.cpp \
|
||||
|
@ -268,7 +270,7 @@ LOCAL_SRC_FILES += \
|
|||
jni/src/network/serverpackethandler.cpp \
|
||||
|
||||
# lua api
|
||||
LOCAL_SRC_FILES += \
|
||||
LOCAL_SRC_FILES += \
|
||||
jni/src/script/common/c_content.cpp \
|
||||
jni/src/script/common/c_converter.cpp \
|
||||
jni/src/script/common/c_internal.cpp \
|
||||
|
@ -301,17 +303,17 @@ 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_http.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_mainmenu.cpp
|
||||
|
||||
#freetype2 support
|
||||
LOCAL_SRC_FILES += \
|
||||
jni/src/cguittfont/xCGUITTFont.cpp
|
||||
LOCAL_SRC_FILES += jni/src/cguittfont/xCGUITTFont.cpp
|
||||
|
||||
# lua
|
||||
LOCAL_SRC_FILES += \
|
||||
# Lua
|
||||
LOCAL_SRC_FILES += \
|
||||
jni/src/lua/src/lapi.c \
|
||||
jni/src/lua/src/lauxlib.c \
|
||||
jni/src/lua/src/lbaselib.c \
|
||||
|
@ -348,6 +350,7 @@ LOCAL_SRC_FILES += deps/sqlite/sqlite3.c
|
|||
|
||||
# Threading
|
||||
LOCAL_SRC_FILES += \
|
||||
jni/src/threading/event.cpp \
|
||||
jni/src/threading/mutex.cpp \
|
||||
jni/src/threading/semaphore.cpp \
|
||||
jni/src/threading/thread.cpp
|
||||
|
@ -370,3 +373,4 @@ ifdef GPROF
|
|||
$(call import-module,android-ndk-profiler)
|
||||
endif
|
||||
$(call import-module,android/native_app_glue)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# NDK_TOOLCHAIN_VERSION := clang3.3
|
||||
# NDK_TOOLCHAIN_VERSION := clang3.8
|
||||
|
||||
APP_PLATFORM := android-9
|
||||
APP_MODULES := minetest
|
||||
|
@ -6,3 +6,4 @@ APP_STL := gnustl_static
|
|||
|
||||
APP_CPPFLAGS += -fexceptions
|
||||
APP_GNUSTL_FORCE_CPP_FEATURES := rtti
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
--- irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 20:56:21.289559503 +0200
|
||||
+++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp.orig 2014-06-03 20:57:39.281556749 +0200
|
||||
@@ -423,6 +423,7 @@
|
||||
--- irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp.orig 2015-08-29 15:43:09.000000000 +0300
|
||||
+++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2016-05-13 21:36:22.880388505 +0300
|
||||
@@ -486,7 +486,7 @@
|
||||
event.KeyInput.Char = 0;
|
||||
}
|
||||
|
||||
device->postEventFromUser(event);
|
||||
+ status = 1;
|
||||
|
||||
- device->postEventFromUser(event);
|
||||
+ status = device->postEventFromUser(event);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -479,7 +480,7 @@
|
||||
@@ -543,7 +543,7 @@
|
||||
KeyMap[1] = KEY_LBUTTON; // AKEYCODE_SOFT_LEFT
|
||||
KeyMap[2] = KEY_RBUTTON; // AKEYCODE_SOFT_RIGHT
|
||||
KeyMap[3] = KEY_HOME; // AKEYCODE_HOME
|
|
@ -1,11 +1,13 @@
|
|||
--- openssl-1.0.1j/Configure.orig 2014-10-15 14:53:39.000000000 +0200
|
||||
+++ openssl-1.0.1j/Configure 2015-01-03 22:41:43.505749921 +0100
|
||||
@@ -407,6 +407,8 @@
|
||||
--- openssl-1.0.2e.orig/Configure 2015-12-03 15:04:23.000000000 +0100
|
||||
+++ openssl-1.0.2e/Configure 2015-12-14 21:01:40.351265968 +0100
|
||||
@@ -464,8 +464,10 @@
|
||||
# Android: linux-* but without pointers to headers and libs.
|
||||
"android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
"android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
"android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
+"android-arm","gcc:-march=armv4 -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
+"android-mips32","gcc:-march=mips32 -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
"android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
"android-mips","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
+"android-mips32","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
|
||||
#### *BSD [do see comment about ${BSDthreads} above!]
|
||||
"BSD-generic32","gcc:-DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
||||
"BSD-generic32","gcc:-O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
|
|
@ -1 +0,0 @@
|
|||
target=android-10
|
|
@ -0,0 +1,2 @@
|
|||
rootProject.name = "Minetest"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
|
||||
</manifest>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.minetest.minetest"
|
||||
android:installLocation="auto">
|
||||
<uses-feature android:glEsVersion="0x00010000" android:required="true"/>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<application android:icon="@drawable/irr_icon"
|
||||
android:label="${project}"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:allowBackup="true">
|
||||
<activity android:name=".MtNativeActivity"
|
||||
android:label="${project}"
|
||||
android:launchMode="singleTask"
|
||||
android:configChanges="orientation|keyboard|keyboardHidden|navigation"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:clearTaskOnLaunch="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.app.lib_name" android:value="minetest" />
|
||||
</activity>
|
||||
<activity android:name=".MinetestTextEntry"
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:excludeFromRecents="true">
|
||||
</activity>
|
||||
<activity android:name=".MinetestAssetCopy"
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:excludeFromRecents="true">
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
|
@ -254,54 +254,14 @@ public class MinetestAssetCopy extends Activity
|
|||
boolean shortened = false;
|
||||
String todisplay = m_tocopy.get(progress[0]);
|
||||
m_ProgressBar.setProgress(progress[0]);
|
||||
|
||||
// make sure our text doesn't exceed our layout width
|
||||
Rect bounds = new Rect();
|
||||
Paint textPaint = m_Filename.getPaint();
|
||||
textPaint.getTextBounds(todisplay, 0, todisplay.length(), bounds);
|
||||
|
||||
while (bounds.width() > getResources().getDisplayMetrics().widthPixels * 0.7) {
|
||||
if (todisplay.length() < 2) {
|
||||
break;
|
||||
}
|
||||
todisplay = todisplay.substring(1);
|
||||
textPaint.getTextBounds(todisplay, 0, todisplay.length(), bounds);
|
||||
shortened = true;
|
||||
}
|
||||
|
||||
if (! shortened) {
|
||||
m_Filename.setText(todisplay);
|
||||
}
|
||||
else {
|
||||
m_Filename.setText(".." + todisplay);
|
||||
}
|
||||
m_Filename.setText(todisplay);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean shortened = false;
|
||||
String todisplay = m_Foldername;
|
||||
String full_text = "scanning " + todisplay + " ...";
|
||||
// make sure our text doesn't exceed our layout width
|
||||
Rect bounds = new Rect();
|
||||
Paint textPaint = m_Filename.getPaint();
|
||||
textPaint.getTextBounds(full_text, 0, full_text.length(), bounds);
|
||||
|
||||
while (bounds.width() > getResources().getDisplayMetrics().widthPixels * 0.7) {
|
||||
if (todisplay.length() < 2) {
|
||||
break;
|
||||
}
|
||||
todisplay = todisplay.substring(1);
|
||||
full_text = "scanning " + todisplay + " ...";
|
||||
textPaint.getTextBounds(full_text, 0, full_text.length(), bounds);
|
||||
shortened = true;
|
||||
}
|
||||
|
||||
if (! shortened) {
|
||||
m_Filename.setText(full_text);
|
||||
}
|
||||
else {
|
||||
m_Filename.setText("scanning .." + todisplay + " ...");
|
||||
}
|
||||
m_Filename.setText(full_text);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,10 @@ public class MtNativeActivity extends NativeActivity {
|
|||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
}
|
||||
|
||||
|
||||
public void copyAssets() {
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
@ -13,10 +13,12 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="middle"
|
||||
android:singleLine="true"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="preparing media ..."
|
||||
android:text="@string/preparing_media"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="preparing_media">Preparing media...</string>
|
||||
</resources>
|
||||
|
|
@ -189,7 +189,7 @@ function filterlist.process(self)
|
|||
for k,v in pairs(self.m_raw_list) do
|
||||
if self.m_filtercriteria == nil or
|
||||
self.m_filter_fct(v,self.m_filtercriteria) then
|
||||
table.insert(self.m_processed_list,v)
|
||||
self.m_processed_list[#self.m_processed_list + 1] = v
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Localize functions to avoid table lookups (better performance).
|
||||
local table_insert = table.insert
|
||||
local string_sub, string_find = string.sub, string.find
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -94,13 +93,13 @@ function dump2(o, name, dumped)
|
|||
-- the form _G["table: 0xFFFFFFF"]
|
||||
keyStr = string.format("_G[%q]", tostring(k))
|
||||
-- Dump key table
|
||||
table_insert(t, dump2(k, keyStr, dumped))
|
||||
t[#t + 1] = dump2(k, keyStr, dumped)
|
||||
end
|
||||
else
|
||||
keyStr = basic_dump(k)
|
||||
end
|
||||
local vname = string.format("%s[%s]", name, keyStr)
|
||||
table_insert(t, dump2(v, vname, dumped))
|
||||
t[#t + 1] = dump2(v, vname, dumped)
|
||||
end
|
||||
return string.format("%s = {}\n%s", name, table.concat(t))
|
||||
end
|
||||
|
@ -135,7 +134,7 @@ function dump(o, indent, nested, level)
|
|||
local t = {}
|
||||
local dumped_indexes = {}
|
||||
for i, v in ipairs(o) do
|
||||
table_insert(t, dump(v, indent, nested, level + 1))
|
||||
t[#t + 1] = dump(v, indent, nested, level + 1)
|
||||
dumped_indexes[i] = true
|
||||
end
|
||||
for k, v in pairs(o) do
|
||||
|
@ -144,7 +143,7 @@ function dump(o, indent, nested, level)
|
|||
k = "["..dump(k, indent, nested, level + 1).."]"
|
||||
end
|
||||
v = dump(v, indent, nested, level + 1)
|
||||
table_insert(t, k.." = "..v)
|
||||
t[#t + 1] = k.." = "..v
|
||||
end
|
||||
end
|
||||
nested[o] = nil
|
||||
|
@ -177,7 +176,7 @@ function string.split(str, delim, include_empty, max_splits, sep_is_pattern)
|
|||
local s = string_sub(str, pos, np - 1)
|
||||
if include_empty or (s ~= "") then
|
||||
max_splits = max_splits - 1
|
||||
table_insert(items, s)
|
||||
items[#items + 1] = s
|
||||
end
|
||||
pos = npe + 1
|
||||
until (max_splits == 0) or (pos > (len + 1))
|
||||
|
@ -186,8 +185,8 @@ end
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
function table.indexof(list, val)
|
||||
for i = 1, #list do
|
||||
if list[i] == val then
|
||||
for i, v in ipairs(list) do
|
||||
if v == val then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
@ -324,7 +323,7 @@ function core.splittext(text,charlimit)
|
|||
local last_line = ""
|
||||
while start ~= nil do
|
||||
if string.len(last_line) + (stop-start) > charlimit then
|
||||
table_insert(retval, last_line)
|
||||
retval[#retval + 1] = last_line
|
||||
last_line = ""
|
||||
end
|
||||
|
||||
|
@ -335,7 +334,7 @@ function core.splittext(text,charlimit)
|
|||
last_line = last_line .. string_sub(text, current_idx, stop - 1)
|
||||
|
||||
if gotnewline then
|
||||
table_insert(retval, last_line)
|
||||
retval[#retval + 1] = last_line
|
||||
last_line = ""
|
||||
gotnewline = false
|
||||
end
|
||||
|
@ -353,11 +352,11 @@ function core.splittext(text,charlimit)
|
|||
|
||||
--add last part of text
|
||||
if string.len(last_line) + (string.len(text) - current_idx) > charlimit then
|
||||
table_insert(retval, last_line)
|
||||
table_insert(retval, string_sub(text, current_idx))
|
||||
retval[#retval + 1] = last_line
|
||||
retval[#retval + 1] = string_sub(text, current_idx)
|
||||
else
|
||||
last_line = last_line .. " " .. string_sub(text, current_idx)
|
||||
table_insert(retval, last_line)
|
||||
retval[#retval + 1] = last_line
|
||||
end
|
||||
|
||||
return retval
|
||||
|
@ -430,14 +429,14 @@ if INIT == "game" then
|
|||
|
||||
if iswall then
|
||||
core.set_node(pos, {name = wield_name,
|
||||
param2 = dirs1[fdir+1]})
|
||||
param2 = dirs1[fdir + 1]})
|
||||
elseif isceiling then
|
||||
if orient_flags.force_facedir then
|
||||
core.set_node(pos, {name = wield_name,
|
||||
param2 = 20})
|
||||
else
|
||||
core.set_node(pos, {name = wield_name,
|
||||
param2 = dirs2[fdir+1]})
|
||||
param2 = dirs2[fdir + 1]})
|
||||
end
|
||||
else -- place right side up
|
||||
if orient_flags.force_facedir then
|
||||
|
|
|
@ -104,7 +104,7 @@ function core.serialize(x)
|
|||
local i = local_index
|
||||
local_index = local_index + 1
|
||||
var = "_["..i.."]"
|
||||
table.insert(local_defs, var.." = "..val)
|
||||
local_defs[#local_defs + 1] = var.." = "..val
|
||||
dumped[x] = var
|
||||
return var
|
||||
end
|
||||
|
@ -135,16 +135,15 @@ function core.serialize(x)
|
|||
local np = nest_points[x]
|
||||
for i, v in ipairs(x) do
|
||||
if not np or not np[i] then
|
||||
table.insert(vals, dump_or_ref_val(v))
|
||||
vals[#vals + 1] = dump_or_ref_val(v)
|
||||
end
|
||||
idx_dumped[i] = true
|
||||
end
|
||||
for k, v in pairs(x) do
|
||||
if (not np or not np[k]) and
|
||||
not idx_dumped[k] then
|
||||
table.insert(vals,
|
||||
"["..dump_or_ref_val(k).."] = "
|
||||
..dump_or_ref_val(v))
|
||||
vals[#vals + 1] = "["..dump_or_ref_val(k).."] = "
|
||||
..dump_or_ref_val(v)
|
||||
end
|
||||
end
|
||||
return "{"..table.concat(vals, ", ").."}"
|
||||
|
@ -156,9 +155,9 @@ function core.serialize(x)
|
|||
local function dump_nest_points()
|
||||
for parent, vals in pairs(nest_points) do
|
||||
for k, v in pairs(vals) do
|
||||
table.insert(local_defs, dump_or_ref_val(parent)
|
||||
local_defs[#local_defs + 1] = dump_or_ref_val(parent)
|
||||
.."["..dump_or_ref_val(k).."] = "
|
||||
..dump_or_ref_val(v))
|
||||
..dump_or_ref_val(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -145,7 +145,12 @@ local buttonbar_metatable = {
|
|||
if image == nil then image = "" end
|
||||
if tooltip == nil then tooltip = "" end
|
||||
|
||||
table.insert(self.buttons,{ name=name, caption=caption, image=image, tooltip=tooltip})
|
||||
self.buttons[#self.buttons + 1] = {
|
||||
name = name,
|
||||
caption = caption,
|
||||
image = image,
|
||||
tooltip = tooltip
|
||||
}
|
||||
if self.orientation == "horizontal" then
|
||||
if ( (self.btn_size * #self.buttons) + (self.btn_size * 0.05 *2)
|
||||
> self.size.x ) then
|
||||
|
|
|
@ -46,7 +46,7 @@ local function add_tab(self,tab)
|
|||
tabdata = {},
|
||||
}
|
||||
|
||||
table.insert(self.tablist,newtab)
|
||||
self.tablist[#self.tablist + 1] = newtab
|
||||
|
||||
if self.last_tab_index == #self.tablist then
|
||||
self.current_tab = tab.name
|
||||
|
|
|
@ -20,7 +20,7 @@ function core.privs_to_string(privs, delim)
|
|||
local list = {}
|
||||
for priv, bool in pairs(privs) do
|
||||
if bool then
|
||||
table.insert(list, priv)
|
||||
list[#list + 1] = priv
|
||||
end
|
||||
end
|
||||
return table.concat(list, delim)
|
||||
|
|
|
@ -84,6 +84,18 @@ core.register_chatcommand("me", {
|
|||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("admin", {
|
||||
description = "Show the name of the server owner",
|
||||
func = function(name)
|
||||
local admin = minetest.setting_get("name")
|
||||
if admin then
|
||||
return true, "The administrator of this server is "..admin.."."
|
||||
else
|
||||
return false, "There's no administrator named in the config file."
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("help", {
|
||||
privs = {},
|
||||
params = "[all/privs/<cmd>]",
|
||||
|
@ -104,7 +116,7 @@ core.register_chatcommand("help", {
|
|||
local cmds = {}
|
||||
for cmd, def in pairs(core.chatcommands) do
|
||||
if core.check_player_privs(name, def.privs) then
|
||||
table.insert(cmds, cmd)
|
||||
cmds[#cmds + 1] = cmd
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
|
@ -115,7 +127,7 @@ core.register_chatcommand("help", {
|
|||
local cmds = {}
|
||||
for cmd, def in pairs(core.chatcommands) do
|
||||
if core.check_player_privs(name, def.privs) then
|
||||
table.insert(cmds, format_help_line(cmd, def))
|
||||
cmds[#cmds + 1] = format_help_line(cmd, def)
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
|
@ -123,7 +135,7 @@ core.register_chatcommand("help", {
|
|||
elseif param == "privs" then
|
||||
local privs = {}
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
table.insert(privs, priv .. ": " .. def.description)
|
||||
privs[#privs + 1] = priv .. ": " .. def.description
|
||||
end
|
||||
table.sort(privs)
|
||||
return true, "Available privileges:\n"..table.concat(privs, "\n")
|
||||
|
@ -169,8 +181,10 @@ core.register_chatcommand("grant", {
|
|||
end
|
||||
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")
|
||||
for priv, _ in pairs(grantprivs) do
|
||||
if priv ~= "interact" and priv ~= "shout" and
|
||||
if not basic_privs[priv] and
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
|
@ -211,8 +225,10 @@ core.register_chatcommand("revoke", {
|
|||
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")
|
||||
for priv, _ in pairs(revoke_privs) do
|
||||
if priv ~= "interact" and priv ~= "shout" and
|
||||
if not basic_privs[priv] and
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
|
@ -336,10 +352,16 @@ core.register_chatcommand("teleport", {
|
|||
p.x = tonumber(p.x)
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
teleportee = core.get_player_by_name(name)
|
||||
if teleportee and p.x and p.y and p.z then
|
||||
teleportee:setpos(p)
|
||||
return true, "Teleporting to "..core.pos_to_string(p)
|
||||
if p.x and p.y and p.z then
|
||||
local lm = tonumber(minetest.setting_get("map_generation_limit") or 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
|
||||
teleportee = core.get_player_by_name(name)
|
||||
if teleportee then
|
||||
teleportee:setpos(p)
|
||||
return true, "Teleporting to "..core.pos_to_string(p)
|
||||
end
|
||||
end
|
||||
|
||||
local teleportee = nil
|
||||
|
@ -773,6 +795,13 @@ core.register_chatcommand("time", {
|
|||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("days", {
|
||||
description = "Display day count",
|
||||
func = function(name, param)
|
||||
return true, "Current day is " .. core.get_day_count()
|
||||
end
|
||||
})
|
||||
|
||||
core.register_chatcommand("shutdown", {
|
||||
description = "shutdown server",
|
||||
privs = {server=true},
|
||||
|
@ -836,14 +865,25 @@ core.register_chatcommand("kick", {
|
|||
})
|
||||
|
||||
core.register_chatcommand("clearobjects", {
|
||||
params = "[full|quick]",
|
||||
description = "clear all objects in world",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
core.log("action", name .. " clears all objects.")
|
||||
local options = {}
|
||||
if param == "" or param == "full" then
|
||||
options.mode = "full"
|
||||
elseif param == "quick" then
|
||||
options.mode = "quick"
|
||||
else
|
||||
return false, "Invalid usage, see /help clearobjects."
|
||||
end
|
||||
|
||||
core.log("action", name .. " clears all objects ("
|
||||
.. options.mode .. " mode).")
|
||||
core.chat_send_all("Clearing all objects. This may take long."
|
||||
.. " You may experience a timeout. (by "
|
||||
.. name .. ")")
|
||||
core.clear_objects()
|
||||
core.clear_objects(options)
|
||||
core.log("action", "Object clearing done.")
|
||||
core.chat_send_all("*** Cleared all objects.")
|
||||
end,
|
||||
|
|
|
@ -6,42 +6,49 @@
|
|||
|
||||
core.register_entity(":__builtin:falling_node", {
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||
visual = "wielditem",
|
||||
visual_size = {x = 0.667, y = 0.667},
|
||||
textures = {},
|
||||
visual_size = {x=0.667, y=0.667},
|
||||
physical = true,
|
||||
is_visible = false,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
},
|
||||
|
||||
node = {},
|
||||
|
||||
set_node = function(self, node)
|
||||
self.node = node
|
||||
local prop = {
|
||||
self.object:set_properties({
|
||||
is_visible = true,
|
||||
textures = {node.name},
|
||||
}
|
||||
self.object:set_properties(prop)
|
||||
})
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
return self.node.name
|
||||
return core.serialize(self.node)
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
if staticdata then
|
||||
self:set_node({name=staticdata})
|
||||
self.object:set_armor_groups({immortal = 1})
|
||||
|
||||
local node = core.deserialize(staticdata)
|
||||
if node then
|
||||
self:set_node(node)
|
||||
elseif staticdata ~= "" then
|
||||
self:set_node({name = staticdata})
|
||||
end
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
-- Set gravity
|
||||
self.object:setacceleration({x=0, y=-10, z=0})
|
||||
-- Set gravity
|
||||
local acceleration = self.object:getacceleration()
|
||||
if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
|
||||
self.object:setacceleration({x = 0, y = -10, z = 0})
|
||||
end
|
||||
-- Turn to actual sand when collides to ground or just move
|
||||
local pos = self.object:getpos()
|
||||
local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
|
||||
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z} -- Position of bottom center point
|
||||
local bcn = core.get_node(bcp)
|
||||
local bcd = core.registered_nodes[bcn.name]
|
||||
-- Note: walkable is in the node definition, not in item groups
|
||||
|
@ -52,7 +59,7 @@ core.register_entity(":__builtin:falling_node", {
|
|||
if bcd and bcd.leveled and
|
||||
bcn.name == self.node.name then
|
||||
local addlevel = self.node.level
|
||||
if addlevel == nil or addlevel <= 0 then
|
||||
if not addlevel or addlevel <= 0 then
|
||||
addlevel = bcd.leveled
|
||||
end
|
||||
if core.add_node_level(bcp, addlevel) == 0 then
|
||||
|
@ -65,7 +72,7 @@ core.register_entity(":__builtin:falling_node", {
|
|||
core.remove_node(bcp)
|
||||
return
|
||||
end
|
||||
local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
|
||||
local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
|
||||
-- Check what's here
|
||||
local n2 = core.get_node(np)
|
||||
-- If it's not air or liquid, remove node and replace it with
|
||||
|
@ -76,25 +83,25 @@ core.register_entity(":__builtin:falling_node", {
|
|||
if core.registered_nodes[n2.name].buildable_to == false then
|
||||
-- Add dropped items
|
||||
local drops = core.get_node_drops(n2.name, "")
|
||||
local _, dropped_item
|
||||
for _, dropped_item in ipairs(drops) do
|
||||
core.add_item(np, dropped_item)
|
||||
end
|
||||
end
|
||||
-- Run script hook
|
||||
local _, callback
|
||||
for _, callback in ipairs(core.registered_on_dignodes) do
|
||||
callback(np, n2, nil)
|
||||
callback(np, n2)
|
||||
end
|
||||
end
|
||||
-- Create node and remove entity
|
||||
core.add_node(np, self.node)
|
||||
if core.registered_nodes[self.node.name] then
|
||||
core.add_node(np, self.node)
|
||||
end
|
||||
self.object:remove()
|
||||
nodeupdate(np)
|
||||
return
|
||||
end
|
||||
local vel = self.object:getvelocity()
|
||||
if vector.equals(vel, {x=0,y=0,z=0}) then
|
||||
if vector.equals(vel, {x = 0, y = 0, z = 0}) then
|
||||
local npos = self.object:getpos()
|
||||
self.object:setpos(vector.round(npos))
|
||||
end
|
||||
|
@ -109,7 +116,7 @@ end
|
|||
function drop_attached_node(p)
|
||||
local nn = core.get_node(p).name
|
||||
core.remove_node(p)
|
||||
for _,item in ipairs(core.get_node_drops(nn, "")) do
|
||||
for _, item in ipairs(core.get_node_drops(nn, "")) do
|
||||
local pos = {
|
||||
x = p.x + math.random()/2 - 0.25,
|
||||
y = p.y + math.random()/2 - 0.25,
|
||||
|
@ -121,25 +128,13 @@ end
|
|||
|
||||
function check_attached_node(p, n)
|
||||
local def = core.registered_nodes[n.name]
|
||||
local d = {x=0, y=0, z=0}
|
||||
local d = {x = 0, y = 0, z = 0}
|
||||
if def.paramtype2 == "wallmounted" then
|
||||
if n.param2 == 0 then
|
||||
d.y = 1
|
||||
elseif n.param2 == 1 then
|
||||
d.y = -1
|
||||
elseif n.param2 == 2 then
|
||||
d.x = 1
|
||||
elseif n.param2 == 3 then
|
||||
d.x = -1
|
||||
elseif n.param2 == 4 then
|
||||
d.z = 1
|
||||
elseif n.param2 == 5 then
|
||||
d.z = -1
|
||||
end
|
||||
d = core.wallmounted_to_dir(n.param2)
|
||||
else
|
||||
d.y = -1
|
||||
end
|
||||
local p2 = {x=p.x+d.x, y=p.y+d.y, z=p.z+d.z}
|
||||
local p2 = vector.add(p, d)
|
||||
local nn = core.get_node(p2).name
|
||||
local def2 = core.registered_nodes[nn]
|
||||
if def2 and not def2.walkable then
|
||||
|
@ -152,10 +147,10 @@ end
|
|||
-- Some common functions
|
||||
--
|
||||
|
||||
function nodeupdate_single(p, delay)
|
||||
function nodeupdate_single(p)
|
||||
local n = core.get_node(p)
|
||||
if core.get_item_group(n.name, "falling_node") ~= 0 then
|
||||
local p_bottom = {x=p.x, y=p.y-1, z=p.z}
|
||||
local p_bottom = {x = p.x, y = p.y - 1, z = p.z}
|
||||
local n_bottom = core.get_node(p_bottom)
|
||||
-- Note: walkable is in the node definition, not in item groups
|
||||
if core.registered_nodes[n_bottom.name] and
|
||||
|
@ -165,37 +160,88 @@ function nodeupdate_single(p, delay)
|
|||
core.get_node_level(p_bottom) < core.get_node_max_level(p_bottom))) and
|
||||
(not core.registered_nodes[n_bottom.name].walkable or
|
||||
core.registered_nodes[n_bottom.name].buildable_to) then
|
||||
if delay then
|
||||
core.after(0.1, nodeupdate_single, {x=p.x, y=p.y, z=p.z}, false)
|
||||
else
|
||||
n.level = core.get_node_level(p)
|
||||
core.remove_node(p)
|
||||
spawn_falling_node(p, n)
|
||||
nodeupdate(p)
|
||||
end
|
||||
n.level = core.get_node_level(p)
|
||||
core.remove_node(p)
|
||||
spawn_falling_node(p, n)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if core.get_item_group(n.name, "attached_node") ~= 0 then
|
||||
if not check_attached_node(p, n) then
|
||||
drop_attached_node(p)
|
||||
nodeupdate(p)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function nodeupdate(p, delay)
|
||||
-- Round p to prevent falling entities to get stuck
|
||||
p.x = math.floor(p.x+0.5)
|
||||
p.y = math.floor(p.y+0.5)
|
||||
p.z = math.floor(p.z+0.5)
|
||||
-- This table is specifically ordered.
|
||||
-- We don't walk diagonals, only our direct neighbors, and self.
|
||||
-- Down first as likely case, but always before self. The same with sides.
|
||||
-- Up must come last, so that things above self will also fall all at once.
|
||||
local nodeupdate_neighbors = {
|
||||
{x = -1, y = -1, z = 0},
|
||||
{x = 1, y = -1, z = 0},
|
||||
{x = 0, y = -1, z = -1},
|
||||
{x = 0, y = -1, z = 1},
|
||||
{x = 0, y = -1, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z = -1},
|
||||
{x = 0, y = 0, z = 0},
|
||||
{x = 0, y = 1, z = 0},
|
||||
}
|
||||
|
||||
for x = -1,1 do
|
||||
for y = -1,1 do
|
||||
for z = -1,1 do
|
||||
nodeupdate_single({x=p.x+x, y=p.y+y, z=p.z+z}, delay or not (x==0 and y==0 and z==0))
|
||||
end
|
||||
end
|
||||
function nodeupdate(p)
|
||||
-- Round p to prevent falling entities to get stuck.
|
||||
p = vector.round(p)
|
||||
|
||||
-- We make a stack, and manually maintain size for performance.
|
||||
-- Stored in the stack, we will maintain tables with pos, and
|
||||
-- last neighbor visited. This way, when we get back to each
|
||||
-- node, we know which directions we have already walked, and
|
||||
-- which direction is the next to walk.
|
||||
local s = {}
|
||||
local n = 0
|
||||
-- The neighbor order we will visit from our table.
|
||||
local v = 1
|
||||
|
||||
while true do
|
||||
-- Push current pos onto the stack.
|
||||
n = n + 1
|
||||
s[n] = {p = p, v = v}
|
||||
-- Select next node from neighbor list.
|
||||
p = vector.add(p, nodeupdate_neighbors[v])
|
||||
-- Now we check out the node. If it is in need of an update,
|
||||
-- it will let us know in the return value (true = updated).
|
||||
if not nodeupdate_single(p) then
|
||||
-- If we don't need to "recurse" (walk) to it then pop
|
||||
-- our previous pos off the stack and continue from there,
|
||||
-- with the v value we were at when we last were at that
|
||||
-- node
|
||||
repeat
|
||||
local pop = s[n]
|
||||
p = pop.p
|
||||
v = pop.v
|
||||
s[n] = nil
|
||||
n = n - 1
|
||||
-- If there's nothing left on the stack, and no
|
||||
-- more sides to walk to, we're done and can exit
|
||||
if n == 0 and v == 11 then
|
||||
return
|
||||
end
|
||||
until v < 11
|
||||
-- The next round walk the next neighbor in list.
|
||||
v = v + 1
|
||||
else
|
||||
-- If we did need to walk the neighbor, then
|
||||
-- start walking it from the walk order start (1),
|
||||
-- and not the order we just pushed up the stack.
|
||||
v = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ core.features = {
|
|||
use_texture_alpha = true,
|
||||
no_legacy_abms = true,
|
||||
texture_names_parens = true,
|
||||
area_store_custom_ids = true,
|
||||
}
|
||||
|
||||
function core.has_feature(arg)
|
||||
|
|
|
@ -27,19 +27,11 @@ function core.get_pointed_thing_position(pointed_thing, above)
|
|||
if above then
|
||||
-- The position where a node would be placed
|
||||
return pointed_thing.above
|
||||
else
|
||||
-- The position where a node would be dug
|
||||
return pointed_thing.under
|
||||
end
|
||||
-- The position where a node would be dug
|
||||
return pointed_thing.under
|
||||
elseif pointed_thing.type == "object" then
|
||||
obj = pointed_thing.ref
|
||||
if obj ~= nil then
|
||||
return obj:getpos()
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else
|
||||
return nil
|
||||
return pointed_thing.ref and pointed_thing.ref:getpos()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -96,25 +88,26 @@ function core.dir_to_facedir(dir, is6d)
|
|||
end
|
||||
end
|
||||
|
||||
-- Table of possible dirs
|
||||
local facedir_to_dir = {
|
||||
{x= 0, y=0, z= 1},
|
||||
{x= 1, y=0, z= 0},
|
||||
{x= 0, y=0, z=-1},
|
||||
{x=-1, y=0, z= 0},
|
||||
{x= 0, y=-1, z= 0},
|
||||
{x= 0, y=1, z= 0},
|
||||
}
|
||||
-- Mapping from facedir value to index in facedir_to_dir.
|
||||
local facedir_to_dir_map = {
|
||||
[0]=1, 2, 3, 4,
|
||||
5, 2, 6, 4,
|
||||
6, 2, 5, 4,
|
||||
1, 5, 3, 6,
|
||||
1, 6, 3, 5,
|
||||
1, 4, 3, 2,
|
||||
}
|
||||
function core.facedir_to_dir(facedir)
|
||||
--a table of possible dirs
|
||||
return ({{x=0, y=0, z=1},
|
||||
{x=1, y=0, z=0},
|
||||
{x=0, y=0, z=-1},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=0, y=-1, z=0},
|
||||
{x=0, y=1, z=0}})
|
||||
|
||||
--indexed into by a table of correlating facedirs
|
||||
[({[0]=1, 2, 3, 4,
|
||||
5, 2, 6, 4,
|
||||
6, 2, 5, 4,
|
||||
1, 5, 3, 6,
|
||||
1, 6, 3, 5,
|
||||
1, 4, 3, 2})
|
||||
|
||||
--indexed into by the facedir in question
|
||||
[facedir]]
|
||||
return facedir_to_dir[facedir_to_dir_map[facedir]]
|
||||
end
|
||||
|
||||
function core.dir_to_wallmounted(dir)
|
||||
|
@ -139,17 +132,17 @@ function core.dir_to_wallmounted(dir)
|
|||
end
|
||||
end
|
||||
|
||||
-- table of dirs in wallmounted order
|
||||
local wallmounted_to_dir = {
|
||||
[0] = {x = 0, y = 1, z = 0},
|
||||
{x = 0, y = -1, z = 0},
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z = -1},
|
||||
}
|
||||
function core.wallmounted_to_dir(wallmounted)
|
||||
-- table of dirs in wallmounted order
|
||||
return ({[0] = {x = 0, y = 1, z = 0},
|
||||
{x = 0, y = -1, z = 0},
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z = -1}})
|
||||
|
||||
--indexed into by the wallmounted in question
|
||||
[wallmounted]
|
||||
return wallmounted_to_dir[wallmounted]
|
||||
end
|
||||
|
||||
function core.get_node_drops(nodename, toolname)
|
||||
|
@ -240,7 +233,8 @@ 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()) then
|
||||
if core.is_protected(place_to, placer:get_player_name()) and
|
||||
not minetest.check_player_privs(placer, "protection_bypass") then
|
||||
core.log("action", placer:get_player_name()
|
||||
.. " tried to place " .. def.name
|
||||
.. " at protected position "
|
||||
|
@ -347,8 +341,12 @@ function core.item_place(itemstack, placer, pointed_thing, param2)
|
|||
return itemstack
|
||||
end
|
||||
|
||||
function core.item_secondary_use(itemstack, placer)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function core.item_drop(itemstack, dropper, pos)
|
||||
if dropper.is_player then
|
||||
if dropper and dropper:is_player() then
|
||||
local v = dropper:get_look_dir()
|
||||
local p = {x=pos.x, y=pos.y+1.2, z=pos.z}
|
||||
local cs = itemstack:get_count()
|
||||
|
@ -362,6 +360,7 @@ function core.item_drop(itemstack, dropper, pos)
|
|||
v.y = v.y*2 + 2
|
||||
v.z = v.z*2
|
||||
obj:setvelocity(v)
|
||||
obj:get_luaentity().dropped_by = dropper:get_player_name()
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
@ -446,7 +445,8 @@ function core.node_dig(pos, node, digger)
|
|||
return
|
||||
end
|
||||
|
||||
if core.is_protected(pos, digger:get_player_name()) then
|
||||
if core.is_protected(pos, digger:get_player_name()) and
|
||||
not minetest.check_player_privs(digger, "protection_bypass") then
|
||||
core.log("action", digger:get_player_name()
|
||||
.. " tried to dig " .. node.name
|
||||
.. " at protected position "
|
||||
|
@ -577,6 +577,7 @@ core.nodedef_default = {
|
|||
diggable = true,
|
||||
climbable = false,
|
||||
buildable_to = false,
|
||||
floodable = false,
|
||||
liquidtype = "none",
|
||||
liquid_alternative_flowing = "",
|
||||
liquid_alternative_source = "",
|
||||
|
@ -604,6 +605,7 @@ core.craftitemdef_default = {
|
|||
-- Interaction callbacks
|
||||
on_place = redef_wrapper(core, 'item_place'), -- core.item_place
|
||||
on_drop = redef_wrapper(core, 'item_drop'), -- core.item_drop
|
||||
on_secondary_use = redef_wrapper(core, 'item_secondary_use'),
|
||||
on_use = nil,
|
||||
}
|
||||
|
||||
|
@ -621,6 +623,7 @@ core.tooldef_default = {
|
|||
|
||||
-- Interaction callbacks
|
||||
on_place = redef_wrapper(core, 'item_place'), -- core.item_place
|
||||
on_secondary_use = redef_wrapper(core, 'item_secondary_use'),
|
||||
on_drop = redef_wrapper(core, 'item_drop'), -- core.item_drop
|
||||
on_use = nil,
|
||||
}
|
||||
|
@ -639,6 +642,7 @@ core.noneitemdef_default = { -- This is used for the hand and unknown items
|
|||
|
||||
-- Interaction callbacks
|
||||
on_place = redef_wrapper(core, 'item_place'),
|
||||
on_secondary_use = redef_wrapper(core, 'item_secondary_use'),
|
||||
on_drop = nil,
|
||||
on_use = nil,
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ core.register_entity(":__builtin:item", {
|
|||
spritediv = {x = 1, y = 1},
|
||||
initial_sprite_basepos = {x = 0, y = 0},
|
||||
is_visible = false,
|
||||
infotext = "",
|
||||
},
|
||||
|
||||
itemstring = '',
|
||||
|
@ -50,6 +51,7 @@ core.register_entity(":__builtin:item", {
|
|||
local c = s
|
||||
local itemtable = stack:to_table()
|
||||
local itemname = nil
|
||||
local description = ""
|
||||
if itemtable then
|
||||
itemname = stack:to_table().name
|
||||
end
|
||||
|
@ -58,6 +60,7 @@ core.register_entity(":__builtin:item", {
|
|||
if core.registered_items[itemname] then
|
||||
item_texture = core.registered_items[itemname].inventory_image
|
||||
item_type = core.registered_items[itemname].type
|
||||
description = core.registered_items[itemname].description
|
||||
end
|
||||
local prop = {
|
||||
is_visible = true,
|
||||
|
@ -66,6 +69,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,
|
||||
infotext = description,
|
||||
}
|
||||
self.object:set_properties(prop)
|
||||
end,
|
||||
|
@ -74,7 +78,8 @@ core.register_entity(":__builtin:item", {
|
|||
return core.serialize({
|
||||
itemstring = self.itemstring,
|
||||
always_collect = self.always_collect,
|
||||
age = self.age
|
||||
age = self.age,
|
||||
dropped_by = self.dropped_by
|
||||
})
|
||||
end,
|
||||
|
||||
|
@ -89,6 +94,7 @@ core.register_entity(":__builtin:item", {
|
|||
else
|
||||
self.age = dtime_s
|
||||
end
|
||||
self.dropped_by = data.dropped_by
|
||||
end
|
||||
else
|
||||
self.itemstring = staticdata
|
||||
|
|
|
@ -4,73 +4,47 @@
|
|||
-- Misc. API functions
|
||||
--
|
||||
|
||||
local timers = {}
|
||||
local mintime
|
||||
local function update_timers(delay)
|
||||
mintime = false
|
||||
local sub = 0
|
||||
for index = 1, #timers do
|
||||
index = index - sub
|
||||
local timer = timers[index]
|
||||
timer.time = timer.time - delay
|
||||
if timer.time <= 0 then
|
||||
core.set_last_run_mod(timer.mod_origin)
|
||||
timer.func(unpack(timer.args or {}))
|
||||
table.remove(timers, index)
|
||||
sub = sub + 1
|
||||
elseif mintime then
|
||||
mintime = math.min(mintime, timer.time)
|
||||
else
|
||||
mintime = timer.time
|
||||
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
|
||||
|
||||
local timers_to_add
|
||||
local function add_timers()
|
||||
for _, timer in ipairs(timers_to_add) do
|
||||
table.insert(timers, timer)
|
||||
end
|
||||
timers_to_add = false
|
||||
end
|
||||
|
||||
local delay = 0
|
||||
core.register_globalstep(function(dtime)
|
||||
if not mintime then
|
||||
-- abort if no timers are running
|
||||
return
|
||||
end
|
||||
if timers_to_add then
|
||||
add_timers()
|
||||
end
|
||||
delay = delay + dtime
|
||||
if delay < mintime then
|
||||
return
|
||||
end
|
||||
update_timers(delay)
|
||||
delay = 0
|
||||
end)
|
||||
|
||||
function core.after(time, func, ...)
|
||||
function core.after(after, func, ...)
|
||||
assert(tonumber(time) and type(func) == "function",
|
||||
"Invalid core.after invocation")
|
||||
if not mintime then
|
||||
mintime = time
|
||||
timers_to_add = {{
|
||||
time = time+delay,
|
||||
func = func,
|
||||
args = {...},
|
||||
mod_origin = core.get_last_run_mod(),
|
||||
}}
|
||||
return
|
||||
end
|
||||
mintime = math.min(mintime, time)
|
||||
timers_to_add = timers_to_add or {}
|
||||
timers_to_add[#timers_to_add+1] = {
|
||||
time = time+delay,
|
||||
func = func,
|
||||
args = {...},
|
||||
mod_origin = core.get_last_run_mod(),
|
||||
jobs[#jobs + 1] = {
|
||||
func = func,
|
||||
expire = time + after,
|
||||
arg = {...},
|
||||
mod_origin = core.get_last_run_mod()
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -89,14 +63,14 @@ function core.check_player_privs(player_or_name, ...)
|
|||
-- We were provided with a table like { privA = true, privB = true }.
|
||||
for priv, value in pairs(requested_privs[1]) do
|
||||
if value and not player_privs[priv] then
|
||||
table.insert(missing_privileges, priv)
|
||||
missing_privileges[#missing_privileges + 1] = priv
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Only a list, we can process it directly.
|
||||
for key, priv in pairs(requested_privs) do
|
||||
if not player_privs[priv] then
|
||||
table.insert(missing_privileges, priv)
|
||||
missing_privileges[#missing_privileges + 1] = priv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -122,7 +96,7 @@ function core.get_connected_players()
|
|||
local temp_table = {}
|
||||
for index, value in pairs(player_list) do
|
||||
if value:is_player_connected() then
|
||||
table.insert(temp_table, value)
|
||||
temp_table[#temp_table + 1] = value
|
||||
end
|
||||
end
|
||||
return temp_table
|
||||
|
@ -204,3 +178,22 @@ function core.raillike_group(name)
|
|||
end
|
||||
return id
|
||||
end
|
||||
|
||||
-- HTTP callback interface
|
||||
function core.http_add_fetch(httpenv)
|
||||
httpenv.fetch = function(req, callback)
|
||||
local handle = httpenv.fetch_async(req)
|
||||
|
||||
local function update_http_status()
|
||||
local res = httpenv.fetch_async_get(handle)
|
||||
if res.completed then
|
||||
callback(res)
|
||||
else
|
||||
core.after(0, update_http_status)
|
||||
end
|
||||
end
|
||||
core.after(0, update_http_status)
|
||||
end
|
||||
|
||||
return httpenv
|
||||
end
|
||||
|
|
|
@ -32,6 +32,7 @@ core.register_privilege("settime", "Can use /time")
|
|||
core.register_privilege("privs", "Can modify privileges")
|
||||
core.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
|
||||
core.register_privilege("server", "Can do server maintenance stuff")
|
||||
core.register_privilege("protection_bypass", "Can bypass node protection in the world")
|
||||
core.register_privilege("shout", "Can speak in chat")
|
||||
core.register_privilege("ban", "Can ban and unban players")
|
||||
core.register_privilege("kick", "Can kick players")
|
||||
|
|
|
@ -11,10 +11,11 @@ local register_alias_raw = core.register_alias_raw
|
|||
core.register_alias_raw = nil
|
||||
|
||||
--
|
||||
-- Item / entity / ABM registration functions
|
||||
-- Item / entity / ABM / LBM registration functions
|
||||
--
|
||||
|
||||
core.registered_abms = {}
|
||||
core.registered_lbms = {}
|
||||
core.registered_entities = {}
|
||||
core.registered_items = {}
|
||||
core.registered_nodes = {}
|
||||
|
@ -51,27 +52,38 @@ local forbidden_item_names = {
|
|||
|
||||
local function check_modname_prefix(name)
|
||||
if name:sub(1,1) == ":" then
|
||||
-- Escape the modname prefix enforcement mechanism
|
||||
-- If the name starts with a colon, we can skip the modname prefix
|
||||
-- mechanism.
|
||||
return name:sub(2)
|
||||
else
|
||||
-- Modname prefix enforcement
|
||||
-- Enforce that the name starts with the correct mod name.
|
||||
local expected_prefix = core.get_current_modname() .. ":"
|
||||
if name:sub(1, #expected_prefix) ~= expected_prefix then
|
||||
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||
"\"modname:\" or \":\" prefix required")
|
||||
"\"" .. expected_prefix .. "\" or \":\" prefix required")
|
||||
end
|
||||
|
||||
-- Enforce that the name only contains letters, numbers and underscores.
|
||||
local subname = name:sub(#expected_prefix+1)
|
||||
if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
|
||||
if subname:find("[^%w_]") then
|
||||
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||
"contains unallowed characters")
|
||||
end
|
||||
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
function core.register_abm(spec)
|
||||
-- Add to core.registered_abms
|
||||
core.registered_abms[#core.registered_abms+1] = spec
|
||||
core.registered_abms[#core.registered_abms + 1] = spec
|
||||
spec.mod_origin = core.get_current_modname() or "??"
|
||||
end
|
||||
|
||||
function core.register_lbm(spec)
|
||||
-- Add to core.registered_lbms
|
||||
check_modname_prefix(spec.name)
|
||||
core.registered_lbms[#core.registered_lbms + 1] = spec
|
||||
spec.mod_origin = core.get_current_modname() or "??"
|
||||
end
|
||||
|
||||
|
@ -268,6 +280,7 @@ core.register_item(":unknown", {
|
|||
description = "Unknown Item",
|
||||
inventory_image = "unknown_item.png",
|
||||
on_place = core.item_place,
|
||||
on_secondary_use = core.item_secondary_use,
|
||||
on_drop = core.item_drop,
|
||||
groups = {not_in_creative_inventory=1},
|
||||
diggable = true,
|
||||
|
@ -284,6 +297,7 @@ core.register_node(":air", {
|
|||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
floodable = true,
|
||||
air_equivalent = true,
|
||||
drop = "",
|
||||
groups = {not_in_creative_inventory=1},
|
||||
|
@ -385,7 +399,7 @@ end
|
|||
local function make_registration()
|
||||
local t = {}
|
||||
local registerfunc = function(func)
|
||||
table.insert(t, func)
|
||||
t[#t + 1] = func
|
||||
core.callback_origins[func] = {
|
||||
mod = core.get_current_modname() or "??",
|
||||
name = debug.getinfo(1, "n").name or "??"
|
||||
|
@ -461,9 +475,9 @@ end
|
|||
|
||||
function core.register_on_player_hpchange(func, modifier)
|
||||
if modifier then
|
||||
table.insert(core.registered_on_player_hpchanges.modifiers, func)
|
||||
core.registered_on_player_hpchanges.modifiers[#core.registered_on_player_hpchanges.modifiers + 1] = func
|
||||
else
|
||||
table.insert(core.registered_on_player_hpchanges.loggers, func)
|
||||
core.registered_on_player_hpchanges.loggers[#core.registered_on_player_hpchanges.loggers + 1] = func
|
||||
end
|
||||
core.callback_origins[func] = {
|
||||
mod = core.get_current_modname() or "??",
|
||||
|
|
|
@ -3,31 +3,23 @@
|
|||
local function warn_invalid_static_spawnpoint()
|
||||
if core.setting_get("static_spawnpoint") and
|
||||
not core.setting_get_pos("static_spawnpoint") then
|
||||
core.log('error', "The static_spawnpoint setting is invalid: \""..
|
||||
core.log("error", "The static_spawnpoint setting is invalid: \""..
|
||||
core.setting_get("static_spawnpoint").."\"")
|
||||
end
|
||||
end
|
||||
|
||||
warn_invalid_static_spawnpoint()
|
||||
|
||||
local function put_player_in_spawn(obj)
|
||||
warn_invalid_static_spawnpoint()
|
||||
local function put_player_in_spawn(player_obj)
|
||||
local static_spawnpoint = core.setting_get_pos("static_spawnpoint")
|
||||
if not static_spawnpoint then
|
||||
return false
|
||||
end
|
||||
core.log('action', "Moving "..obj:get_player_name()..
|
||||
" to static spawnpoint at "..
|
||||
core.pos_to_string(static_spawnpoint))
|
||||
obj:setpos(static_spawnpoint)
|
||||
core.log("action", "Moving " .. player_obj:get_player_name() ..
|
||||
" to static spawnpoint at " .. core.pos_to_string(static_spawnpoint))
|
||||
player_obj:setpos(static_spawnpoint)
|
||||
return true
|
||||
end
|
||||
|
||||
core.register_on_newplayer(function(obj)
|
||||
put_player_in_spawn(obj)
|
||||
end)
|
||||
|
||||
core.register_on_respawnplayer(function(obj)
|
||||
return put_player_in_spawn(obj)
|
||||
end)
|
||||
|
||||
core.register_on_newplayer(put_player_in_spawn)
|
||||
core.register_on_respawnplayer(put_player_in_spawn)
|
||||
|
|
|
@ -12,7 +12,11 @@ if core.print then
|
|||
-- Override native print and use
|
||||
-- terminal if that's turned on
|
||||
function print(...)
|
||||
core_print(table.concat({...}, "\t"))
|
||||
local n, t = select("#", ...), {...}
|
||||
for i = 1, n do
|
||||
t[i] = tostring(t[i])
|
||||
end
|
||||
core_print(table.concat(t, "\t"))
|
||||
end
|
||||
core.print = nil -- don't pollute our namespace
|
||||
end
|
||||
|
@ -21,26 +25,26 @@ os.setlocale("C", "numeric")
|
|||
minetest = core
|
||||
|
||||
-- Load other files
|
||||
local scriptdir = core.get_builtin_path()..DIR_DELIM
|
||||
local gamepath = scriptdir.."game"..DIR_DELIM
|
||||
local commonpath = scriptdir.."common"..DIR_DELIM
|
||||
local asyncpath = scriptdir.."async"..DIR_DELIM
|
||||
local scriptdir = core.get_builtin_path() .. DIR_DELIM
|
||||
local gamepath = scriptdir .. "game" .. DIR_DELIM
|
||||
local commonpath = scriptdir .. "common" .. DIR_DELIM
|
||||
local asyncpath = scriptdir .. "async" .. DIR_DELIM
|
||||
|
||||
dofile(commonpath.."strict.lua")
|
||||
dofile(commonpath.."serialize.lua")
|
||||
dofile(commonpath.."misc_helpers.lua")
|
||||
dofile(commonpath .. "strict.lua")
|
||||
dofile(commonpath .. "serialize.lua")
|
||||
dofile(commonpath .. "misc_helpers.lua")
|
||||
|
||||
if INIT == "game" then
|
||||
dofile(gamepath.."init.lua")
|
||||
dofile(gamepath .. "init.lua")
|
||||
elseif INIT == "mainmenu" then
|
||||
local mainmenuscript = core.setting_get("main_menu_script")
|
||||
if mainmenuscript ~= nil and mainmenuscript ~= "" then
|
||||
dofile(mainmenuscript)
|
||||
else
|
||||
dofile(core.get_mainmenu_path()..DIR_DELIM.."init.lua")
|
||||
dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
|
||||
end
|
||||
elseif INIT == "async" then
|
||||
dofile(asyncpath.."init.lua")
|
||||
dofile(asyncpath .. "init.lua")
|
||||
else
|
||||
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
|
||||
end
|
||||
|
|
|
@ -22,40 +22,37 @@ menudata = {}
|
|||
--------------------------------------------------------------------------------
|
||||
-- Local cached values
|
||||
--------------------------------------------------------------------------------
|
||||
local min_supp_proto = core.get_min_supp_proto()
|
||||
local max_supp_proto = core.get_max_supp_proto()
|
||||
local min_supp_proto, max_supp_proto
|
||||
|
||||
function common_update_cached_supp_proto()
|
||||
min_supp_proto = core.get_min_supp_proto()
|
||||
max_supp_proto = core.get_max_supp_proto()
|
||||
end
|
||||
common_update_cached_supp_proto()
|
||||
--------------------------------------------------------------------------------
|
||||
-- Menu helper functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function render_client_count(n)
|
||||
if n > 99 then
|
||||
return '99+'
|
||||
elseif n >= 0 then
|
||||
return tostring(n)
|
||||
else
|
||||
return '?'
|
||||
end
|
||||
if n > 99 then return '99+'
|
||||
elseif n >= 0 then return tostring(n)
|
||||
else return '?' end
|
||||
end
|
||||
|
||||
local function configure_selected_world_params(idx)
|
||||
local worldconfig = modmgr.get_worldconfig(
|
||||
menudata.worldlist:get_list()[idx].path)
|
||||
|
||||
if worldconfig.creative_mode ~= nil then
|
||||
local worldconfig = modmgr.get_worldconfig(menudata.worldlist:get_list()[idx].path)
|
||||
if worldconfig.creative_mode then
|
||||
core.setting_set("creative_mode", worldconfig.creative_mode)
|
||||
end
|
||||
if worldconfig.enable_damage ~= nil then
|
||||
if worldconfig.enable_damage then
|
||||
core.setting_set("enable_damage", worldconfig.enable_damage)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function image_column(tooltip, flagname)
|
||||
return "image," ..
|
||||
"tooltip=" .. core.formspec_escape(tooltip) .. "," ..
|
||||
return "image,tooltip=" .. core.formspec_escape(tooltip) .. "," ..
|
||||
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
|
||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
||||
end
|
||||
|
@ -64,76 +61,60 @@ end
|
|||
function order_favorite_list(list)
|
||||
local res = {}
|
||||
--orders the favorite list after support
|
||||
for i=1,#list,1 do
|
||||
for i = 1, #list do
|
||||
local fav = list[i]
|
||||
if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
table.insert(res, fav)
|
||||
res[#res + 1] = fav
|
||||
end
|
||||
end
|
||||
for i=1,#list,1 do
|
||||
for i = 1, #list do
|
||||
local fav = list[i]
|
||||
if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
table.insert(res, fav)
|
||||
res[#res + 1] = fav
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function render_favorite(spec,render_details)
|
||||
function render_favorite(spec, is_favorite)
|
||||
local text = ""
|
||||
|
||||
if spec.name ~= nil then
|
||||
if spec.name then
|
||||
text = text .. core.formspec_escape(spec.name:trim())
|
||||
|
||||
-- if spec.description ~= nil and
|
||||
-- core.formspec_escape(spec.description):trim() ~= "" then
|
||||
-- text = text .. " (" .. core.formspec_escape(spec.description) .. ")"
|
||||
-- end
|
||||
else
|
||||
if spec.address ~= nil then
|
||||
text = text .. spec.address:trim()
|
||||
|
||||
if spec.port ~= nil then
|
||||
text = text .. ":" .. spec.port
|
||||
end
|
||||
elseif spec.address then
|
||||
text = text .. spec.address:trim()
|
||||
if spec.port then
|
||||
text = text .. ":" .. spec.port
|
||||
end
|
||||
end
|
||||
|
||||
if not render_details then
|
||||
return text
|
||||
local details = ""
|
||||
local grey_out = not is_server_protocol_compat(spec.proto_min, spec.proto_max)
|
||||
|
||||
if is_favorite then
|
||||
details = "1,"
|
||||
else
|
||||
details = "0,"
|
||||
end
|
||||
|
||||
local details = ""
|
||||
local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min)
|
||||
|
||||
if spec.clients ~= nil and spec.clients_max ~= nil then
|
||||
if spec.clients and spec.clients_max then
|
||||
local clients_color = ''
|
||||
local clients_percent = 100 * spec.clients / spec.clients_max
|
||||
|
||||
-- Choose a color depending on how many clients are connected
|
||||
-- (relatively to clients_max)
|
||||
if spec.clients == 0 then
|
||||
clients_color = '' -- 0 players: default/white
|
||||
elseif spec.clients == spec.clients_max then
|
||||
clients_color = '#dd5b5b' -- full server: red (darker)
|
||||
elseif clients_percent <= 60 then
|
||||
clients_color = '#a1e587' -- 0-60%: green
|
||||
elseif clients_percent <= 90 then
|
||||
clients_color = '#ffdc97' -- 60-90%: yellow
|
||||
else
|
||||
clients_color = '#ffba97' -- 90-100%: orange
|
||||
if grey_out then clients_color = '#aaaaaa'
|
||||
elseif spec.clients == 0 then clients_color = '' -- 0 players: default/white
|
||||
elseif clients_percent <= 60 then clients_color = '#a1e587' -- 0-60%: green
|
||||
elseif clients_percent <= 90 then clients_color = '#ffdc97' -- 60-90%: yellow
|
||||
elseif clients_percent == 100 then clients_color = '#dd5b5b' -- full server: red (darker)
|
||||
else clients_color = '#ffba97' -- 90-100%: orange
|
||||
end
|
||||
|
||||
if grey_out then
|
||||
clients_color = '#aaaaaa'
|
||||
end
|
||||
details = details .. clients_color .. ',' ..
|
||||
render_client_count(spec.clients) .. ',/,' ..
|
||||
render_client_count(spec.clients_max) .. ','
|
||||
|
||||
details = details ..
|
||||
clients_color .. ',' ..
|
||||
render_client_count(spec.clients) .. ',' ..
|
||||
'/,' ..
|
||||
render_client_count(spec.clients_max) .. ','
|
||||
elseif grey_out then
|
||||
details = details .. '#aaaaaa,?,/,?,'
|
||||
else
|
||||
|
@ -184,56 +165,36 @@ end
|
|||
--------------------------------------------------------------------------------
|
||||
function menu_render_worldlist()
|
||||
local retval = ""
|
||||
|
||||
local current_worldlist = menudata.worldlist:get_list()
|
||||
|
||||
for i,v in ipairs(current_worldlist) do
|
||||
if retval ~= "" then
|
||||
retval = retval ..","
|
||||
end
|
||||
|
||||
for i, v in ipairs(current_worldlist) do
|
||||
if retval ~= "" then retval = retval .. "," end
|
||||
retval = retval .. core.formspec_escape(v.name) ..
|
||||
" \\[" .. core.formspec_escape(v.gameid) .. "\\]"
|
||||
" \\[" .. core.formspec_escape(v.gameid) .. "\\]"
|
||||
end
|
||||
|
||||
return retval
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function menu_handle_key_up_down(fields,textlist,settingname)
|
||||
if fields["key_up"] then
|
||||
local oldidx = core.get_textlist_index(textlist)
|
||||
|
||||
if oldidx ~= nil and oldidx > 1 then
|
||||
local newidx = oldidx -1
|
||||
core.setting_set(settingname,
|
||||
menudata.worldlist:get_raw_index(newidx))
|
||||
|
||||
configure_selected_world_params(newidx)
|
||||
function menu_handle_key_up_down(fields, textlist, settingname)
|
||||
local oldidx, newidx = core.get_textlist_index(textlist), 1
|
||||
if fields.key_up or fields.key_down then
|
||||
if fields.key_up and oldidx and oldidx > 1 then
|
||||
newidx = oldidx - 1
|
||||
elseif fields.key_down and oldidx and
|
||||
oldidx < menudata.worldlist:size() then
|
||||
newidx = oldidx + 1
|
||||
end
|
||||
core.setting_set(settingname, menudata.worldlist:get_raw_index(newidx))
|
||||
configure_selected_world_params(newidx)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["key_down"] then
|
||||
local oldidx = core.get_textlist_index(textlist)
|
||||
|
||||
if oldidx ~= nil and oldidx < menudata.worldlist:size() then
|
||||
local newidx = oldidx + 1
|
||||
core.setting_set(settingname,
|
||||
menudata.worldlist:get_raw_index(newidx))
|
||||
|
||||
configure_selected_world_params(newidx)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function asyncOnlineFavourites()
|
||||
|
||||
if not menudata.public_known then
|
||||
menudata.public_known = {{
|
||||
name = fgettext("Loading..."),
|
||||
|
@ -241,43 +202,45 @@ function asyncOnlineFavourites()
|
|||
}}
|
||||
end
|
||||
menudata.favorites = menudata.public_known
|
||||
menudata.favorites_is_public = true
|
||||
|
||||
if not menudata.public_downloading then
|
||||
menudata.public_downloading = true
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
core.handle_async(
|
||||
function(param)
|
||||
return core.get_favorites("online")
|
||||
end,
|
||||
nil,
|
||||
function(result)
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
local favs = order_favorite_list(result)
|
||||
if favs[1] then
|
||||
menudata.public_known = favs
|
||||
menudata.favorites = menudata.public_known
|
||||
end
|
||||
core.event_handler("Refresh")
|
||||
menudata.public_downloading = nil
|
||||
local favs = order_favorite_list(result)
|
||||
if favs[1] then
|
||||
menudata.public_known = favs
|
||||
menudata.favorites = menudata.public_known
|
||||
menudata.favorites_is_public = true
|
||||
end
|
||||
core.event_handler("Refresh")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
|
||||
local textlines = core.splittext(text,textlen)
|
||||
function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency)
|
||||
local textlines = core.splittext(text, textlen)
|
||||
local retval = "textlist[" .. xpos .. "," .. ypos .. ";" .. width ..
|
||||
"," .. height .. ";" .. tl_name .. ";"
|
||||
|
||||
local retval = "textlist[" .. xpos .. "," .. ypos .. ";"
|
||||
.. width .. "," .. height .. ";"
|
||||
.. tl_name .. ";"
|
||||
|
||||
for i=1, #textlines, 1 do
|
||||
textlines[i] = textlines[i]:gsub("\r","")
|
||||
for i = 1, #textlines do
|
||||
textlines[i] = textlines[i]:gsub("\r", "")
|
||||
retval = retval .. core.formspec_escape(textlines[i]) .. ","
|
||||
end
|
||||
|
||||
retval = retval .. ";0;"
|
||||
|
||||
if transparency then
|
||||
retval = retval .. "true"
|
||||
end
|
||||
|
||||
if transparency then retval = retval .. "true" end
|
||||
retval = retval .. "]"
|
||||
|
||||
return retval
|
||||
|
@ -285,19 +248,21 @@ end
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
function is_server_protocol_compat(server_proto_min, server_proto_max)
|
||||
return not ((min_supp_proto > (server_proto_max or 24)) or (max_supp_proto < (server_proto_min or 13)))
|
||||
return min_supp_proto <= (server_proto_max or 24) and max_supp_proto >= (server_proto_min or 13)
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
function is_server_protocol_compat_or_error(server_proto_min, server_proto_max)
|
||||
if not is_server_protocol_compat(server_proto_min, server_proto_max) then
|
||||
local server_prot_ver_info
|
||||
local client_prot_ver_info
|
||||
if server_proto_min ~= server_proto_max then
|
||||
local server_prot_ver_info, client_prot_ver_info
|
||||
local s_p_min = server_proto_min or 13
|
||||
local s_p_max = server_proto_max or 24
|
||||
|
||||
if s_p_min ~= s_p_max then
|
||||
server_prot_ver_info = fgettext_ne("Server supports protocol versions between $1 and $2. ",
|
||||
server_proto_min or 13, server_proto_max or 24)
|
||||
s_p_min, s_p_max)
|
||||
else
|
||||
server_prot_ver_info = fgettext_ne("Server enforces protocol version $1. ",
|
||||
server_proto_min or 13)
|
||||
s_p_min)
|
||||
end
|
||||
if min_supp_proto ~= max_supp_proto then
|
||||
client_prot_ver_info= fgettext_ne("We support protocol versions between version $1 and $2.",
|
||||
|
@ -320,7 +285,7 @@ function menu_worldmt(selected, setting, value)
|
|||
local filename = world.path .. DIR_DELIM .. "world.mt"
|
||||
local world_conf = Settings(filename)
|
||||
|
||||
if value ~= nil then
|
||||
if value then
|
||||
if not world_conf:write() then
|
||||
core.log("error", "Failed to write world config file")
|
||||
end
|
||||
|
@ -338,7 +303,7 @@ function menu_worldmt_legacy(selected)
|
|||
local modes_names = {"creative_mode", "enable_damage", "server_announce"}
|
||||
for _, mode_name in pairs(modes_names) do
|
||||
local mode_val = menu_worldmt(selected, mode_name)
|
||||
if mode_val ~= nil then
|
||||
if mode_val then
|
||||
core.setting_set(mode_name, mode_val)
|
||||
else
|
||||
menu_worldmt(selected, mode_name, core.setting_get(mode_name))
|
||||
|
|
|
@ -25,20 +25,20 @@ local function get_formspec(data)
|
|||
local mod = data.list:get_list()[data.selected_mod]
|
||||
|
||||
local retval =
|
||||
"size[11,6.5,true]" ..
|
||||
"label[0.5,-0.25;" .. fgettext("World:") .. "]" ..
|
||||
"label[1.75,-0.25;" .. data.worldspec.name .. "]"
|
||||
"size[11.5,7.5,true]" ..
|
||||
"label[0.5,0;" .. fgettext("World:") .. "]" ..
|
||||
"label[1.75,0;" .. data.worldspec.name .. "]"
|
||||
|
||||
if data.hide_gamemods then
|
||||
retval = retval .. "checkbox[0,5.75;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]"
|
||||
retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]"
|
||||
else
|
||||
retval = retval .. "checkbox[0,5.75;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]"
|
||||
retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]"
|
||||
end
|
||||
|
||||
if data.hide_modpackcontents then
|
||||
retval = retval .. "checkbox[2,5.75;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]"
|
||||
retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]"
|
||||
else
|
||||
retval = retval .. "checkbox[2,5.75;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]"
|
||||
retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]"
|
||||
end
|
||||
|
||||
if mod == nil then
|
||||
|
@ -46,13 +46,13 @@ local function get_formspec(data)
|
|||
end
|
||||
|
||||
retval = retval ..
|
||||
"label[0,0.45;" .. fgettext("Mod:") .. "]" ..
|
||||
"label[0.75,0.45;" .. mod.name .. "]" ..
|
||||
"label[0,1;" .. fgettext("Depends:") .. "]" ..
|
||||
"textlist[0,1.5;5,4.25;world_config_depends;" ..
|
||||
"label[0,0.7;" .. fgettext("Mod:") .. "]" ..
|
||||
"label[0.75,0.7;" .. mod.name .. "]" ..
|
||||
"label[0,1.25;" .. fgettext("Depends:") .. "]" ..
|
||||
"textlist[0,1.75;5,4.25;world_config_depends;" ..
|
||||
modmgr.get_dependencies(mod.path) .. ";0]" ..
|
||||
"button[9.25,6.35;2,0.5;btn_config_world_save;" .. fgettext("Save") .. "]" ..
|
||||
"button[7.4,6.35;2,0.5;btn_config_world_cancel;" .. fgettext("Cancel") .. "]"
|
||||
"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.is_modpack then
|
||||
|
@ -68,22 +68,22 @@ local function get_formspec(data)
|
|||
end
|
||||
|
||||
if all_enabled == false then
|
||||
retval = retval .. "button[5.5,-0.125;2,0.5;btn_mp_enable;" .. fgettext("Enable MP") .. "]"
|
||||
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_enable;" .. fgettext("Enable MP") .. "]"
|
||||
else
|
||||
retval = retval .. "button[5.5,-0.125;2,0.5;btn_mp_disable;" .. fgettext("Disable MP") .. "]"
|
||||
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_disable;" .. fgettext("Disable MP") .. "]"
|
||||
end
|
||||
else
|
||||
if mod.enabled then
|
||||
retval = retval .. "checkbox[5.5,-0.375;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.375;cb_mod_enable;" .. fgettext("enabled") .. ";false]"
|
||||
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. ";false]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
retval = retval ..
|
||||
"button[8.5,-0.125;2.5,0.5;btn_all_mods;" .. fgettext("Enable all") .. "]" ..
|
||||
"textlist[5.5,0.5;5.5,5.75;world_config_modlist;"
|
||||
"button[8.75,0.125;2.5,0.5;btn_all_mods;" .. fgettext("Enable all") .. "]" ..
|
||||
"textlist[5.5,0.75;5.75,5.25;world_config_modlist;"
|
||||
|
||||
retval = retval .. modmgr.render_modlist(data.list)
|
||||
retval = retval .. ";" .. data.selected_mod .."]"
|
||||
|
|
|
@ -46,7 +46,7 @@ local function create_world_formspec(dialogdata)
|
|||
|
||||
current_seed = core.formspec_escape(current_seed)
|
||||
local retval =
|
||||
"size[12,6,true]" ..
|
||||
"size[11.5,6.5,true]" ..
|
||||
"label[2,0;" .. fgettext("World name") .. "]"..
|
||||
"field[4.5,0.4;6,0.5;te_world_name;;]" ..
|
||||
|
||||
|
@ -60,8 +60,8 @@ local function create_world_formspec(dialogdata)
|
|||
"textlist[4.2,3;5.8,2.3;games;" .. gamemgr.gamelist() ..
|
||||
";" .. gameidx .. ";true]" ..
|
||||
|
||||
"button[5,5.5;2.6,0.5;world_create_confirm;" .. fgettext("Create") .. "]" ..
|
||||
"button[7.5,5.5;2.8,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
|
||||
"button[3.25,6;2.5,0.5;world_create_confirm;" .. fgettext("Create") .. "]" ..
|
||||
"button[5.75,6;2.5,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
|
||||
|
||||
if #gamemgr.games == 0 then
|
||||
retval = retval .. "box[2,4;8,1;#ff8800]label[2.25,4;" ..
|
||||
|
|
|
@ -22,10 +22,11 @@ local function delete_mod_formspec(dialogdata)
|
|||
dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected]
|
||||
|
||||
local retval =
|
||||
"size[12.4,5,true]" ..
|
||||
"field[1.75,1;10,3;;" .. fgettext("Are you sure you want to delete \"$1\"?", dialogdata.mod.name) .. ";]"..
|
||||
"button[4,4.2;1,0.5;dlg_delete_mod_confirm;" .. fgettext("Yes") .. "]" ..
|
||||
"button[6.5,4.2;3,0.5;dlg_delete_mod_cancel;" .. fgettext("No of course not!") .. "]"
|
||||
"size[11.5,4.5,true]" ..
|
||||
"label[2,2;" ..
|
||||
fgettext("Are you sure you want to delete \"$1\"?", dialogdata.mod.name) .. "]"..
|
||||
"button[3.25,3.5;2.5,0.5;dlg_delete_mod_confirm;" .. fgettext("Delete") .. "]" ..
|
||||
"button[5.75,3.5;2.5,0.5;dlg_delete_mod_cancel;" .. fgettext("Cancel") .. "]"
|
||||
|
||||
return retval
|
||||
end
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
local function delete_world_formspec(dialogdata)
|
||||
|
||||
local retval =
|
||||
"size[12,6,true]" ..
|
||||
"size[11.5,4.5,true]" ..
|
||||
"label[2,2;" ..
|
||||
fgettext("Delete World \"$1\"?", dialogdata.delete_name) .. "]"..
|
||||
"button[3.5,4.2;2.6,0.5;world_delete_confirm;" .. fgettext("Yes").. "]" ..
|
||||
"button[6,4.2;2.8,0.5;world_delete_cancel;" .. fgettext("No") .. "]"
|
||||
fgettext("Delete World \"$1\"?", dialogdata.delete_name) .. "]" ..
|
||||
"button[3.25,3.5;2.5,0.5;world_delete_confirm;" .. fgettext("Delete") .. "]" ..
|
||||
"button[5.75,3.5;2.5,0.5;world_delete_cancel;" .. fgettext("Cancel") .. "]"
|
||||
return retval
|
||||
end
|
||||
|
||||
|
|
|
@ -22,14 +22,12 @@ local function rename_modpack_formspec(dialogdata)
|
|||
dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected]
|
||||
|
||||
local retval =
|
||||
"size[12.4,5,true]" ..
|
||||
"label[1.75,1;".. fgettext("Rename Modpack:") .. "]"..
|
||||
"field[4.5,1.4;6,0.5;te_modpack_name;;" ..
|
||||
dialogdata.mod.name ..
|
||||
"]" ..
|
||||
"button[5,4.2;2.6,0.5;dlg_rename_modpack_confirm;"..
|
||||
"size[11.5,4.5,true]" ..
|
||||
"field[2.5,2;7,0.5;te_modpack_name;".. fgettext("Rename Modpack:") .. ";" ..
|
||||
dialogdata.mod.name .. "]" ..
|
||||
"button[3.25,3.5;2.5,0.5;dlg_rename_modpack_confirm;"..
|
||||
fgettext("Accept") .. "]" ..
|
||||
"button[7.5,4.2;2.8,0.5;dlg_rename_modpack_cancel;"..
|
||||
"button[5.75,3.5;2.5,0.5;dlg_rename_modpack_cancel;"..
|
||||
fgettext("Cancel") .. "]"
|
||||
|
||||
return retval
|
||||
|
|
|
@ -0,0 +1,760 @@
|
|||
--Minetest
|
||||
--Copyright (C) 2015 PilzAdam
|
||||
--
|
||||
--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 FILENAME = "settingtypes.txt"
|
||||
|
||||
local CHAR_CLASSES = {
|
||||
SPACE = "[%s]",
|
||||
VARIABLE = "[%w_%-%.]",
|
||||
INTEGER = "[+-]?[%d]",
|
||||
FLOAT = "[+-]?[%d%.]",
|
||||
FLAGS = "[%w_%-%.,]",
|
||||
}
|
||||
|
||||
-- returns error message, or nil
|
||||
local function parse_setting_line(settings, line, read_all, base_level, allow_secure)
|
||||
-- comment
|
||||
local comment = line:match("^#" .. CHAR_CLASSES.SPACE .. "*(.*)$")
|
||||
if comment then
|
||||
if settings.current_comment == "" then
|
||||
settings.current_comment = comment
|
||||
else
|
||||
settings.current_comment = settings.current_comment .. "\n" .. comment
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- clear current_comment so only comments directly above a setting are bound to it
|
||||
-- but keep a local reference to it for variables in the current line
|
||||
local current_comment = settings.current_comment
|
||||
settings.current_comment = ""
|
||||
|
||||
-- empty lines
|
||||
if line:match("^" .. CHAR_CLASSES.SPACE .. "*$") then
|
||||
return
|
||||
end
|
||||
|
||||
-- category
|
||||
local stars, category = line:match("^%[([%*]*)([^%]]+)%]$")
|
||||
if category then
|
||||
table.insert(settings, {
|
||||
name = category,
|
||||
level = stars:len() + base_level,
|
||||
type = "category",
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
-- settings
|
||||
local first_part, name, readable_name, setting_type = line:match("^"
|
||||
-- this first capture group matches the whole first part,
|
||||
-- so we can later strip it from the rest of the line
|
||||
.. "("
|
||||
.. "([" .. CHAR_CLASSES.VARIABLE .. "+)" -- variable name
|
||||
.. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "%(([^%)]*)%)" -- readable name
|
||||
.. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "(" .. CHAR_CLASSES.VARIABLE .. "+)" -- type
|
||||
.. CHAR_CLASSES.SPACE .. "*"
|
||||
.. ")")
|
||||
|
||||
if not first_part then
|
||||
return "Invalid line"
|
||||
end
|
||||
|
||||
if name:match("secure%.[.]*") and not allow_secure then
|
||||
return "Tried to add \"secure.\" setting"
|
||||
end
|
||||
|
||||
if readable_name == "" then
|
||||
readable_name = nil
|
||||
end
|
||||
local remaining_line = line:sub(first_part:len() + 1)
|
||||
|
||||
if setting_type == "int" then
|
||||
local default, min, max = remaining_line:match("^"
|
||||
-- first int is required, the last 2 are optional
|
||||
.. "(" .. CHAR_CLASSES.INTEGER .. "+)" .. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "(" .. CHAR_CLASSES.INTEGER .. "*)" .. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "(" .. CHAR_CLASSES.INTEGER .. "*)"
|
||||
.. "$")
|
||||
|
||||
if not default or not tonumber(default) then
|
||||
return "Invalid integer setting"
|
||||
end
|
||||
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
table.insert(settings, {
|
||||
name = name,
|
||||
readable_name = readable_name,
|
||||
type = "int",
|
||||
default = default,
|
||||
min = min,
|
||||
max = max,
|
||||
comment = current_comment,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
if setting_type == "string" or setting_type == "noise_params"
|
||||
or setting_type == "key" or setting_type == "v3f" then
|
||||
local default = remaining_line:match("^(.*)$")
|
||||
|
||||
if not default then
|
||||
return "Invalid string setting"
|
||||
end
|
||||
if setting_type == "key" and not read_all then
|
||||
-- ignore key type if read_all is false
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(settings, {
|
||||
name = name,
|
||||
readable_name = readable_name,
|
||||
type = setting_type,
|
||||
default = default,
|
||||
comment = current_comment,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
if setting_type == "bool" then
|
||||
if remaining_line ~= "false" and remaining_line ~= "true" then
|
||||
return "Invalid boolean setting"
|
||||
end
|
||||
|
||||
table.insert(settings, {
|
||||
name = name,
|
||||
readable_name = readable_name,
|
||||
type = "bool",
|
||||
default = remaining_line,
|
||||
comment = current_comment,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
if setting_type == "float" then
|
||||
local default, min, max = remaining_line:match("^"
|
||||
-- first float is required, the last 2 are optional
|
||||
.. "(" .. CHAR_CLASSES.FLOAT .. "+)" .. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "(" .. CHAR_CLASSES.FLOAT .. "*)" .. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "(" .. CHAR_CLASSES.FLOAT .. "*)"
|
||||
.."$")
|
||||
|
||||
if not default or not tonumber(default) then
|
||||
return "Invalid float setting"
|
||||
end
|
||||
|
||||
min = tonumber(min)
|
||||
max = tonumber(max)
|
||||
table.insert(settings, {
|
||||
name = name,
|
||||
readable_name = readable_name,
|
||||
type = "float",
|
||||
default = default,
|
||||
min = min,
|
||||
max = max,
|
||||
comment = current_comment,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
if setting_type == "enum" then
|
||||
local default, values = remaining_line:match("^"
|
||||
-- first value (default) may be empty (i.e. is optional)
|
||||
.. "(" .. CHAR_CLASSES.VARIABLE .. "*)" .. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "(" .. CHAR_CLASSES.FLAGS .. "+)"
|
||||
.. "$")
|
||||
|
||||
if not default or values == "" then
|
||||
return "Invalid enum setting"
|
||||
end
|
||||
|
||||
table.insert(settings, {
|
||||
name = name,
|
||||
readable_name = readable_name,
|
||||
type = "enum",
|
||||
default = default,
|
||||
values = values:split(",", true),
|
||||
comment = current_comment,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
if setting_type == "path" then
|
||||
local default = remaining_line:match("^(.*)$")
|
||||
|
||||
if not default then
|
||||
return "Invalid path setting"
|
||||
end
|
||||
|
||||
table.insert(settings, {
|
||||
name = name,
|
||||
readable_name = readable_name,
|
||||
type = "path",
|
||||
default = default,
|
||||
comment = current_comment,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
if setting_type == "flags" then
|
||||
local default, possible = remaining_line:match("^"
|
||||
-- first value (default) may be empty (i.e. is optional)
|
||||
-- this is implemented by making the last value optional, and
|
||||
-- swapping them around if it turns out empty.
|
||||
.. "(" .. CHAR_CLASSES.FLAGS .. "+)" .. CHAR_CLASSES.SPACE .. "*"
|
||||
.. "(" .. CHAR_CLASSES.FLAGS .. "*)"
|
||||
.. "$")
|
||||
|
||||
if not default or not possible then
|
||||
return "Invalid flags setting"
|
||||
end
|
||||
|
||||
if possible == "" then
|
||||
possible = default
|
||||
default = ""
|
||||
end
|
||||
|
||||
table.insert(settings, {
|
||||
name = name,
|
||||
readable_name = readable_name,
|
||||
type = "flags",
|
||||
default = default,
|
||||
possible = possible,
|
||||
comment = current_comment,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
return "Invalid setting type \"" .. setting_type .. "\""
|
||||
end
|
||||
|
||||
local function parse_single_file(file, filepath, read_all, result, base_level, allow_secure)
|
||||
-- store this helper variable in the table so it's easier to pass to parse_setting_line()
|
||||
result.current_comment = ""
|
||||
|
||||
local line = file:read("*line")
|
||||
while line do
|
||||
local error_msg = parse_setting_line(result, line, read_all, base_level, allow_secure)
|
||||
if error_msg then
|
||||
core.log("error", error_msg .. " in " .. filepath .. " \"" .. line .. "\"")
|
||||
end
|
||||
line = file:read("*line")
|
||||
end
|
||||
|
||||
result.current_comment = nil
|
||||
end
|
||||
|
||||
-- read_all: whether to ignore certain setting types for GUI or not
|
||||
-- parse_mods: whether to parse settingtypes.txt in mods and games
|
||||
local function parse_config_file(read_all, parse_mods)
|
||||
local builtin_path = core.get_builtin_path() .. DIR_DELIM .. FILENAME
|
||||
local file = io.open(builtin_path, "r")
|
||||
local settings = {}
|
||||
if not file then
|
||||
core.log("error", "Can't load " .. FILENAME)
|
||||
return settings
|
||||
end
|
||||
|
||||
parse_single_file(file, builtin_path, read_all, settings, 0, true)
|
||||
|
||||
file:close()
|
||||
|
||||
if parse_mods then
|
||||
-- Parse games
|
||||
local games_category_initialized = false
|
||||
local index = 1
|
||||
local game = gamemgr.get_game(index)
|
||||
while game do
|
||||
local path = game.path .. DIR_DELIM .. FILENAME
|
||||
local file = io.open(path, "r")
|
||||
if file then
|
||||
if not games_category_initialized then
|
||||
local translation = fgettext_ne("Games"), -- not used, but needed for xgettext
|
||||
table.insert(settings, {
|
||||
name = "Games",
|
||||
level = 0,
|
||||
type = "category",
|
||||
})
|
||||
games_category_initialized = true
|
||||
end
|
||||
|
||||
table.insert(settings, {
|
||||
name = game.name,
|
||||
level = 1,
|
||||
type = "category",
|
||||
})
|
||||
|
||||
parse_single_file(file, path, read_all, settings, 2, false)
|
||||
|
||||
file:close()
|
||||
end
|
||||
|
||||
index = index + 1
|
||||
game = gamemgr.get_game(index)
|
||||
end
|
||||
|
||||
-- Parse mods
|
||||
local mods_category_initialized = false
|
||||
local mods = {}
|
||||
get_mods(core.get_modpath(), mods)
|
||||
for _, mod in ipairs(mods) do
|
||||
local path = mod.path .. DIR_DELIM .. FILENAME
|
||||
local file = io.open(path, "r")
|
||||
if file then
|
||||
if not mods_category_initialized then
|
||||
local translation = fgettext_ne("Mods"), -- not used, but needed for xgettext
|
||||
table.insert(settings, {
|
||||
name = "Mods",
|
||||
level = 0,
|
||||
type = "category",
|
||||
})
|
||||
mods_category_initialized = true
|
||||
end
|
||||
|
||||
table.insert(settings, {
|
||||
name = mod.name,
|
||||
level = 1,
|
||||
type = "category",
|
||||
})
|
||||
|
||||
parse_single_file(file, path, read_all, settings, 2, false)
|
||||
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return settings
|
||||
end
|
||||
|
||||
local settings = parse_config_file(false, true)
|
||||
local selected_setting = 1
|
||||
|
||||
local function get_current_value(setting)
|
||||
local value = core.setting_get(setting.name)
|
||||
if value == nil then
|
||||
value = setting.default
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local function create_change_setting_formspec(dialogdata)
|
||||
local setting = settings[selected_setting]
|
||||
local formspec = "size[10,5.2,true]" ..
|
||||
"button[5,4.5;2,1;btn_done;" .. fgettext("Save") .. "]" ..
|
||||
"button[3,4.5;2,1;btn_cancel;" .. fgettext("Cancel") .. "]" ..
|
||||
"tablecolumns[color;text]" ..
|
||||
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
||||
"table[0,0;10,3;info;"
|
||||
|
||||
if setting.readable_name then
|
||||
formspec = formspec .. "#FFFF00," .. fgettext(setting.readable_name)
|
||||
.. " (" .. core.formspec_escape(setting.name) .. "),"
|
||||
else
|
||||
formspec = formspec .. "#FFFF00," .. core.formspec_escape(setting.name) .. ","
|
||||
end
|
||||
|
||||
formspec = formspec .. ",,"
|
||||
|
||||
local comment_text = ""
|
||||
|
||||
if setting.comment == "" then
|
||||
comment_text = fgettext_ne("(No description of setting given)")
|
||||
else
|
||||
comment_text = fgettext_ne(setting.comment)
|
||||
end
|
||||
for _, comment_line in ipairs(comment_text:split("\n", true)) do
|
||||
formspec = formspec .. "," .. core.formspec_escape(comment_line) .. ","
|
||||
end
|
||||
|
||||
if setting.type == "flags" then
|
||||
formspec = formspec .. ",,"
|
||||
.. "," .. fgettext("Please enter a comma seperated list of flags.") .. ","
|
||||
.. "," .. fgettext("Possible values are: ")
|
||||
.. core.formspec_escape(setting.possible:gsub(",", ", ")) .. ","
|
||||
elseif setting.type == "noise_params" then
|
||||
formspec = formspec .. ",,"
|
||||
.. "," .. fgettext("Format: <offset>, <scale>, (<spreadX>, <spreadY>, <spreadZ>), <seed>, <octaves>, <persistence>") .. ","
|
||||
.. "," .. fgettext("Optionally the lacunarity can be appended with a leading comma.") .. ","
|
||||
elseif setting.type == "v3f" then
|
||||
formspec = formspec .. ",,"
|
||||
.. "," .. fgettext_ne("Format is 3 numbers separated by commas and inside brackets.") .. ","
|
||||
end
|
||||
|
||||
formspec = formspec:sub(1, -2) -- remove trailing comma
|
||||
|
||||
formspec = formspec .. ";1]"
|
||||
|
||||
if setting.type == "bool" then
|
||||
local selected_index
|
||||
if core.is_yes(get_current_value(setting)) then
|
||||
selected_index = 2
|
||||
else
|
||||
selected_index = 1
|
||||
end
|
||||
formspec = formspec .. "dropdown[0.5,3.5;3,1;dd_setting_value;"
|
||||
.. fgettext("Disabled") .. "," .. fgettext("Enabled") .. ";"
|
||||
.. selected_index .. "]"
|
||||
|
||||
elseif setting.type == "enum" then
|
||||
local selected_index = 0
|
||||
formspec = formspec .. "dropdown[0.5,3.5;3,1;dd_setting_value;"
|
||||
for index, value in ipairs(setting.values) do
|
||||
-- translating value is not possible, since it's the value
|
||||
-- that we set the setting to
|
||||
formspec = formspec .. core.formspec_escape(value) .. ","
|
||||
if get_current_value(setting) == value then
|
||||
selected_index = index
|
||||
end
|
||||
end
|
||||
if #setting.values > 0 then
|
||||
formspec = formspec:sub(1, -2) -- remove trailing comma
|
||||
end
|
||||
formspec = formspec .. ";" .. selected_index .. "]"
|
||||
|
||||
elseif setting.type == "path" then
|
||||
local current_value = dialogdata.selected_path
|
||||
if not current_value then
|
||||
current_value = get_current_value(setting)
|
||||
end
|
||||
formspec = formspec .. "field[0.5,4;7.5,1;te_setting_value;;"
|
||||
.. core.formspec_escape(current_value) .. "]"
|
||||
.. "button[8,3.75;2,1;btn_browser_path;" .. fgettext("Browse") .. "]"
|
||||
|
||||
else
|
||||
-- TODO: fancy input for float, int, flags, noise_params, v3f
|
||||
local width = 10
|
||||
local text = get_current_value(setting)
|
||||
if dialogdata.error_message then
|
||||
formspec = formspec .. "tablecolumns[color;text]" ..
|
||||
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
||||
"table[5,3.9;5,0.6;error_message;#FF0000,"
|
||||
.. core.formspec_escape(dialogdata.error_message) .. ";0]"
|
||||
width = 5
|
||||
if dialogdata.entered_text then
|
||||
text = dialogdata.entered_text
|
||||
end
|
||||
end
|
||||
formspec = formspec .. "field[0.5,4;" .. width .. ",1;te_setting_value;;"
|
||||
.. core.formspec_escape(text) .. "]"
|
||||
end
|
||||
return formspec
|
||||
end
|
||||
|
||||
local function handle_change_setting_buttons(this, fields)
|
||||
if fields["btn_done"] or fields["key_enter"] then
|
||||
local setting = settings[selected_setting]
|
||||
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"))
|
||||
|
||||
elseif setting.type == "enum" then
|
||||
local new_value = fields["dd_setting_value"]
|
||||
core.setting_set(setting.name, new_value)
|
||||
|
||||
elseif setting.type == "int" then
|
||||
local new_value = tonumber(fields["te_setting_value"])
|
||||
if not new_value or math.floor(new_value) ~= new_value then
|
||||
this.data.error_message = fgettext_ne("Please enter a valid integer.")
|
||||
this.data.entered_text = fields["te_setting_value"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
if setting.min and new_value < setting.min then
|
||||
this.data.error_message = fgettext_ne("The value must be greater than $1.", setting.min)
|
||||
this.data.entered_text = fields["te_setting_value"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
if setting.max and new_value > setting.max then
|
||||
this.data.error_message = fgettext_ne("The value must be lower than $1.", setting.max)
|
||||
this.data.entered_text = fields["te_setting_value"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
core.setting_set(setting.name, new_value)
|
||||
|
||||
elseif setting.type == "float" then
|
||||
local new_value = tonumber(fields["te_setting_value"])
|
||||
if not new_value then
|
||||
this.data.error_message = fgettext_ne("Please enter a valid number.")
|
||||
this.data.entered_text = fields["te_setting_value"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
core.setting_set(setting.name, new_value)
|
||||
|
||||
elseif setting.type == "flags" then
|
||||
local new_value = fields["te_setting_value"]
|
||||
for _,value in ipairs(new_value:split(",", true)) do
|
||||
value = value:trim()
|
||||
local possible = "," .. setting.possible .. ","
|
||||
if not possible:find("," .. value .. ",", 0, true) then
|
||||
this.data.error_message = fgettext_ne("\"$1\" is not a valid flag.", value)
|
||||
this.data.entered_text = fields["te_setting_value"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
end
|
||||
core.setting_set(setting.name, new_value)
|
||||
|
||||
else
|
||||
local new_value = fields["te_setting_value"]
|
||||
core.setting_set(setting.name, new_value)
|
||||
end
|
||||
core.setting_save()
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_cancel"] then
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_browser_path"] then
|
||||
core.show_file_open_dialog("dlg_browse_path", fgettext_ne("Select path"))
|
||||
end
|
||||
|
||||
if fields["dlg_browse_path_accepted"] then
|
||||
this.data.selected_path = fields["dlg_browse_path_accepted"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function create_settings_formspec(tabview, name, tabdata)
|
||||
local formspec = "size[12,6.5;true]" ..
|
||||
"tablecolumns[color;tree;text;text]" ..
|
||||
"tableoptions[background=#00000000;border=false]" ..
|
||||
"table[0,0;12,5.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
|
||||
name = fgettext_ne(entry.readable_name)
|
||||
else
|
||||
name = entry.name
|
||||
end
|
||||
|
||||
if entry.type == "category" then
|
||||
current_level = entry.level
|
||||
formspec = formspec .. "#FFFF00," .. current_level .. "," .. fgettext(name) .. ",,"
|
||||
|
||||
elseif entry.type == "bool" then
|
||||
local value = get_current_value(entry)
|
||||
if core.is_yes(value) then
|
||||
value = fgettext("Enabled")
|
||||
else
|
||||
value = fgettext("Disabled")
|
||||
end
|
||||
formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. ","
|
||||
.. value .. ","
|
||||
|
||||
elseif entry.type == "key" then
|
||||
-- ignore key settings, since we have a special dialog for them
|
||||
|
||||
else
|
||||
formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. ","
|
||||
.. core.formspec_escape(get_current_value(entry)) .. ","
|
||||
end
|
||||
end
|
||||
|
||||
if #settings > 0 then
|
||||
formspec = formspec:sub(1, -2) -- remove trailing comma
|
||||
end
|
||||
formspec = formspec .. ";" .. selected_setting .. "]" ..
|
||||
"button[0,6;4,1;btn_back;".. fgettext("< Back to Settings page") .. "]" ..
|
||||
"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")) .. "]"
|
||||
|
||||
return formspec
|
||||
end
|
||||
|
||||
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
|
||||
-- Directly toggle booleans
|
||||
local setting = settings[selected_setting]
|
||||
if 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()
|
||||
return true
|
||||
else
|
||||
list_enter = true
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if fields["btn_edit"] or list_enter then
|
||||
local setting = settings[selected_setting]
|
||||
if setting.type ~= "category" then
|
||||
local edit_dialog = dialog_create("change_setting", create_change_setting_formspec,
|
||||
handle_change_setting_buttons)
|
||||
edit_dialog:set_parent(this)
|
||||
this:hide()
|
||||
edit_dialog:show()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
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()
|
||||
core.update_formspec(this:get_formspec())
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_back"] then
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_tech_settings"] then
|
||||
core.setting_set("main_menu_technical_settings", fields["cb_tech_settings"])
|
||||
core.setting_save()
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function create_adv_settings_dlg()
|
||||
local dlg = dialog_create("settings_advanced",
|
||||
create_settings_formspec,
|
||||
handle_settings_buttons,
|
||||
nil)
|
||||
|
||||
return dlg
|
||||
end
|
||||
|
||||
local function create_minetest_conf_example()
|
||||
local result = "# This file contains a list of all available settings and their default value for minetest.conf\n" ..
|
||||
"\n" ..
|
||||
"# By default, all the settings are commented and not functional.\n" ..
|
||||
"# Uncomment settings by removing the preceding #.\n" ..
|
||||
"\n" ..
|
||||
"# minetest.conf is read by default from:\n" ..
|
||||
"# ../minetest.conf\n" ..
|
||||
"# ../../minetest.conf\n" ..
|
||||
"# Any other path can be chosen by passing the path as a parameter\n" ..
|
||||
"# to the program, eg. \"minetest.exe --config ../minetest.conf.example\".\n" ..
|
||||
"\n" ..
|
||||
"# Further documentation:\n" ..
|
||||
"# http://wiki.minetest.net/\n" ..
|
||||
"\n"
|
||||
|
||||
local settings = parse_config_file(true, false)
|
||||
for _, entry in ipairs(settings) do
|
||||
if entry.type == "category" then
|
||||
if entry.level == 0 then
|
||||
result = result .. "#\n# " .. entry.name .. "\n#\n\n"
|
||||
else
|
||||
for i = 1, entry.level do
|
||||
result = result .. "#"
|
||||
end
|
||||
result = result .. "# " .. entry.name .. "\n\n"
|
||||
end
|
||||
else
|
||||
if entry.comment ~= "" then
|
||||
for _, comment_line in ipairs(entry.comment:split("\n", true)) do
|
||||
result = result .."# " .. comment_line .. "\n"
|
||||
end
|
||||
end
|
||||
result = result .. "# type: " .. entry.type
|
||||
if entry.min then
|
||||
result = result .. " min: " .. entry.min
|
||||
end
|
||||
if entry.max then
|
||||
result = result .. " max: " .. entry.max
|
||||
end
|
||||
if entry.values then
|
||||
result = result .. " values: " .. table.concat(entry.values, ", ")
|
||||
end
|
||||
if entry.possible then
|
||||
result = result .. " possible values: " .. entry.possible:gsub(",", ", ")
|
||||
end
|
||||
result = result .. "\n"
|
||||
local append = ""
|
||||
if entry.default ~= "" then
|
||||
append = " " .. entry.default
|
||||
end
|
||||
result = result .. "# " .. entry.name .. " =" .. append .. "\n\n"
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local function create_translation_file()
|
||||
local result = "// This file is automatically generated\n" ..
|
||||
"// It conatins a bunch of fake gettext calls, to tell xgettext about the strings in config files\n" ..
|
||||
"// To update it, refer to the bottom of builtin/mainmenu/tab_settings.lua\n\n" ..
|
||||
"fake_function() {\n"
|
||||
|
||||
local settings = parse_config_file(true, false)
|
||||
for _, entry in ipairs(settings) do
|
||||
if entry.type == "category" then
|
||||
local name_escaped = entry.name:gsub("\"", "\\\"")
|
||||
result = result .. "\tgettext(\"" .. name_escaped .. "\");\n"
|
||||
else
|
||||
if entry.readable_name then
|
||||
local readable_name_escaped = entry.readable_name:gsub("\"", "\\\"")
|
||||
result = result .. "\tgettext(\"" .. readable_name_escaped .. "\");\n"
|
||||
end
|
||||
if entry.comment ~= "" then
|
||||
local comment_escaped = entry.comment:gsub("\n", "\\n")
|
||||
comment_escaped = comment_escaped:gsub("\"", "\\\"")
|
||||
result = result .. "\tgettext(\"" .. comment_escaped .. "\");\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
result = result .. "}\n"
|
||||
return result
|
||||
end
|
||||
|
||||
if false then
|
||||
local file = io.open("minetest.conf.example", "w")
|
||||
if file then
|
||||
file:write(create_minetest_conf_example())
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
if false then
|
||||
local file = io.open("src/settings_translation_file.cpp", "w")
|
||||
if file then
|
||||
file:write(create_translation_file())
|
||||
file:close()
|
||||
end
|
||||
end
|
|
@ -37,22 +37,29 @@ dofile(menupath .. DIR_DELIM .. "common.lua")
|
|||
dofile(menupath .. DIR_DELIM .. "gamemgr.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "modmgr.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "store.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "textures.lua")
|
||||
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua")
|
||||
if PLATFORM ~= "Android" then
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_server.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
|
||||
dofile(menupath .. DIR_DELIM .. "textures.lua")
|
||||
end
|
||||
|
||||
local tabs = {}
|
||||
|
||||
tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
|
||||
tabs.mods = dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
|
||||
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
|
||||
dofile(menupath .. DIR_DELIM .. "tab_simple_main.lua")
|
||||
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.texturepacks = dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -68,8 +75,34 @@ local function init_globals()
|
|||
-- Init gamedata
|
||||
gamedata.worldindex = 0
|
||||
|
||||
if PLATFORM == "Android" then
|
||||
local world_list = core.get_worlds()
|
||||
local world_index
|
||||
|
||||
if PLATFORM ~= "Android" then
|
||||
local found_singleplayerworld = false
|
||||
for i, world in ipairs(world_list) do
|
||||
if world.name == "singleplayerworld" then
|
||||
found_singleplayerworld = true
|
||||
world_index = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found_singleplayerworld then
|
||||
core.create_world("singleplayerworld", 1)
|
||||
|
||||
world_list = core.get_worlds()
|
||||
|
||||
for i, world in ipairs(world_list) do
|
||||
if world.name == "singleplayerworld" then
|
||||
world_index = i
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
gamedata.worldindex = world_index
|
||||
else
|
||||
menudata.worldlist = filterlist.create(
|
||||
core.get_worlds,
|
||||
compare_worlds,
|
||||
|
@ -88,61 +121,34 @@ local function init_globals()
|
|||
|
||||
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 )
|
||||
core.setting_set("menu_last_game", default_game)
|
||||
end
|
||||
|
||||
mm_texture.init()
|
||||
else
|
||||
local world_list = core.get_worlds()
|
||||
|
||||
local found_singleplayerworld = false
|
||||
|
||||
for i,world in pairs(world_list) do
|
||||
if world.name == "singleplayerworld" then
|
||||
found_singleplayerworld = true
|
||||
gamedata.worldindex = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found_singleplayerworld then
|
||||
core.create_world("singleplayerworld", 1)
|
||||
|
||||
local world_list = core.get_worlds()
|
||||
|
||||
for i,world in pairs(world_list) do
|
||||
if world.name == "singleplayerworld" then
|
||||
gamedata.worldindex = i
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Create main tabview
|
||||
local tv_main = tabview_create("maintab",{x=12,y=5.2},{x=0,y=0})
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:set_autosave_tab(true)
|
||||
end
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:add(tab_singleplayer)
|
||||
tv_main:add(tab_multiplayer)
|
||||
tv_main:add(tab_server)
|
||||
local tv_main = tabview_create("maintab", {x = 12, y = 5.2}, {x = 0, y = 0})
|
||||
|
||||
if PLATFORM == "Android" then
|
||||
tv_main:add(tabs.simple_main)
|
||||
tv_main:add(tabs.settings)
|
||||
else
|
||||
tv_main:add(tab_simple_main)
|
||||
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.settings)
|
||||
tv_main:add(tabs.texturepacks)
|
||||
end
|
||||
tv_main:add(tab_settings)
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:add(tab_texturepacks)
|
||||
end
|
||||
tv_main:add(tab_mods)
|
||||
tv_main:add(tab_credits)
|
||||
|
||||
tv_main:add(tabs.mods)
|
||||
tv_main:add(tabs.credits)
|
||||
|
||||
tv_main:set_global_event_handler(main_event_handler)
|
||||
|
||||
tv_main:set_fixed_size(false)
|
||||
|
||||
if not (PLATFORM == "Android") then
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||
end
|
||||
ui.set_default("maintab")
|
||||
|
@ -150,9 +156,9 @@ local function init_globals()
|
|||
|
||||
-- Create modstore ui
|
||||
if PLATFORM == "Android" then
|
||||
modstore.init({x=12, y=6}, 3, 2)
|
||||
modstore.init({x = 12, y = 6}, 3, 2)
|
||||
else
|
||||
modstore.init({x=12, y=8}, 4, 3)
|
||||
modstore.init({x = 12, y = 8}, 4, 3)
|
||||
end
|
||||
|
||||
ui.update()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- helper file to be able to debug the simple menu on PC
|
||||
-- without messing around with actual menu code!
|
||||
PLATFORM="Android"
|
||||
PLATFORM = "Android"
|
||||
dofile("builtin/mainmenu/init.lua")
|
||||
|
|
|
@ -19,29 +19,29 @@
|
|||
function get_mods(path,retval,modpack)
|
||||
local mods = core.get_dir_list(path, true)
|
||||
|
||||
for i=1, #mods, 1 do
|
||||
if mods[i]:sub(1,1) ~= "." then
|
||||
for _, name in ipairs(mods) do
|
||||
if name:sub(1, 1) ~= "." then
|
||||
local prefix = path .. DIR_DELIM .. name .. DIR_DELIM
|
||||
local toadd = {}
|
||||
local modpackfile = nil
|
||||
retval[#retval + 1] = toadd
|
||||
|
||||
toadd.name = mods[i]
|
||||
toadd.path = path .. DIR_DELIM .. mods[i] .. DIR_DELIM
|
||||
if modpack ~= nil and
|
||||
modpack ~= "" then
|
||||
toadd.modpack = modpack
|
||||
else
|
||||
local filename = path .. DIR_DELIM .. mods[i] .. DIR_DELIM .. "modpack.txt"
|
||||
local error = nil
|
||||
modpackfile,error = io.open(filename,"r")
|
||||
local mod_conf = Settings(prefix .. "mod.conf"):to_table()
|
||||
if mod_conf.name then
|
||||
name = mod_conf.name
|
||||
end
|
||||
|
||||
if modpackfile ~= nil then
|
||||
modpackfile:close()
|
||||
toadd.is_modpack = true
|
||||
table.insert(retval,toadd)
|
||||
get_mods(path .. DIR_DELIM .. mods[i],retval,mods[i])
|
||||
toadd.name = name
|
||||
toadd.path = prefix
|
||||
|
||||
if modpack ~= nil and modpack ~= "" then
|
||||
toadd.modpack = modpack
|
||||
else
|
||||
table.insert(retval,toadd)
|
||||
local modpackfile = io.open(prefix .. "modpack.txt")
|
||||
if modpackfile then
|
||||
modpackfile:close()
|
||||
toadd.is_modpack = true
|
||||
get_mods(prefix, retval, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -412,7 +412,7 @@ function modmgr.preparemodlist(data)
|
|||
|
||||
for i=1,#global_mods,1 do
|
||||
global_mods[i].typ = "global_mod"
|
||||
table.insert(retval,global_mods[i])
|
||||
retval[#retval + 1] = global_mods[i]
|
||||
end
|
||||
|
||||
--read game mods
|
||||
|
@ -421,7 +421,7 @@ function modmgr.preparemodlist(data)
|
|||
|
||||
for i=1,#game_mods,1 do
|
||||
game_mods[i].typ = "game_mod"
|
||||
table.insert(retval,game_mods[i])
|
||||
retval[#retval + 1] = game_mods[i]
|
||||
end
|
||||
|
||||
if data.worldpath == nil then
|
||||
|
|
|
@ -17,64 +17,84 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
tab_credits = {
|
||||
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>",
|
||||
"Craig Robbins (Zeno)",
|
||||
}
|
||||
|
||||
local active_contributors = {
|
||||
"Auke Kok (sofar) <sofar@foo-projects.org>",
|
||||
"Duane Robertson <duane@duanerobertson.com>",
|
||||
"SmallJoker <mk939@ymail.com>",
|
||||
"Andrew Ward (rubenwardy) <rubenwardy@gmail.com>",
|
||||
"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>",
|
||||
}
|
||||
|
||||
local previous_core_developers = {
|
||||
"BlockMen",
|
||||
"Maciej Kasatkin (RealBadAngel) <maciej.kasatkin@o2.pl>",
|
||||
"Lisa Milne (darkrose) <lisa@ltmnet.com>",
|
||||
"proller",
|
||||
"Ilya Zhuravlev (xyz) <xyz@minetest.net>",
|
||||
}
|
||||
|
||||
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>",
|
||||
}
|
||||
|
||||
return {
|
||||
name = "credits",
|
||||
caption = fgettext("Credits"),
|
||||
cbf_formspec = function (tabview, name, tabdata)
|
||||
local logofile = defaulttexturedir .. "logo.png"
|
||||
return "label[0.5,3.2;Minetest " .. core.get_version() .. "]" ..
|
||||
"label[0.5,3.5;http://minetest.net]" ..
|
||||
"image[0.5,1;" .. core.formspec_escape(logofile) .. "]" ..
|
||||
"tablecolumns[color;text]" ..
|
||||
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
||||
"table[3.5,-0.25;8.5,5.8;list_credits;" ..
|
||||
"#FFFF00," .. fgettext("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>,"..
|
||||
",Nathanael Courant (Nore/Ekdohibs) <nore@mesecons.net>,"..
|
||||
",BlockMen,"..
|
||||
",Craig Robbins (Zeno),"..
|
||||
",Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>,"..
|
||||
",Mat Gregory (paramat),"..
|
||||
",est31 <MTest31@outlook.com>," ..
|
||||
",,"..
|
||||
"#FFFF00," .. fgettext("Active Contributors") .. "," ..
|
||||
",SmallJoker <mk939@ymail.com>," ..
|
||||
",Andrew Ward (rubenwardy) <rubenwardy@gmail.com>," ..
|
||||
",Aaron Suen <warr1024@gmail.com>," ..
|
||||
",Sokomine <wegwerf@anarres.dyndns.org>," ..
|
||||
",Břetislav Štec (t0suj4/TBC_x)," ..
|
||||
",TeTpaAka," ..
|
||||
",Jean-Patrick G (kilbith) <jeanpatrick.guerrero@gmail.com>," ..
|
||||
",Diego Martinez (kaeza) <kaeza@users.sf.net>," ..
|
||||
",," ..
|
||||
"#FFFF00," .. fgettext("Previous Core Developers") .."," ..
|
||||
",Maciej Kasatkin (RealBadAngel) <maciej.kasatkin@o2.pl>,"..
|
||||
",Lisa Milne (darkrose) <lisa@ltmnet.com>," ..
|
||||
",proller," ..
|
||||
",Ilya Zhuravlev (xyz) <xyz@minetest.net>," ..
|
||||
",," ..
|
||||
"#FFFF00," .. fgettext("Previous Contributors") .. "," ..
|
||||
",Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
|
||||
",Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
|
||||
",Gregory Currie (gregorycu)," ..
|
||||
",Jeija <jeija@mesecons.net>,"..
|
||||
",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>,"..
|
||||
",Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
|
||||
",matttpt <matttpt@gmail.com>,"..
|
||||
",JacobF <queatz@gmail.com>,"..
|
||||
",TriBlade9 <triblade9@mail.com>,"..
|
||||
",Zefram <zefram@fysh.org>,"..
|
||||
";1]"
|
||||
end
|
||||
}
|
||||
cbf_formspec = function(tabview, name, tabdata)
|
||||
local logofile = defaulttexturedir .. "logo.png"
|
||||
return "image[0.5,1;" .. core.formspec_escape(logofile) .. "]" ..
|
||||
"label[0.5,3.2;Minetest " .. core.get_version() .. "]" ..
|
||||
"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;" ..
|
||||
"#FFFF00," .. "Dedication of the current release" .. ",," ..
|
||||
"The 0.4.14 release is dedicated to the memory of" .. ",," ..
|
||||
"Minetest developer Maciej Kasatkin (RealBadAngel)" .. ",," ..
|
||||
"who died on March 24 2016." .. ",," ..
|
||||
"Our thoughts are with his family and friends." .. ",,," ..
|
||||
"#FFFF00," .. fgettext("Core Developers") .. ",," ..
|
||||
table.concat(core_developers, ",,") .. ",,," ..
|
||||
"#FFFF00," .. fgettext("Active Contributors") .. ",," ..
|
||||
table.concat(active_contributors, ",,") .. ",,," ..
|
||||
"#FFFF00," .. fgettext("Previous Core Developers") ..",," ..
|
||||
table.concat(previous_core_developers, ",,") .. ",,," ..
|
||||
"#FFFF00," .. fgettext("Previous Contributors") .. ",," ..
|
||||
table.concat(previous_contributors, ",,") .. "," ..
|
||||
";1]"
|
||||
end
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
|
||||
local retval =
|
||||
"label[0.05,-0.25;".. fgettext("Installed Mods:") .. "]" ..
|
||||
"textlist[0,0.25;5.1,4.35;modlist;" ..
|
||||
"textlist[0,0.25;5.1,5;modlist;" ..
|
||||
modmgr.render_modlist(modmgr.global_mods) ..
|
||||
";" .. tabdata.selected_mod .. "]"
|
||||
|
||||
|
@ -78,7 +78,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
descriptionfile:close()
|
||||
else
|
||||
descriptionlines = {}
|
||||
table.insert(descriptionlines,fgettext("No mod description available"))
|
||||
descriptionlines[#descriptionlines + 1] = fgettext("No mod description available")
|
||||
end
|
||||
|
||||
retval = retval ..
|
||||
|
@ -163,7 +163,7 @@ local function handle_buttons(tabview, fields, tabname, tabdata)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_mods = {
|
||||
return {
|
||||
name = "mods",
|
||||
caption = fgettext("Mods"),
|
||||
cbf_formspec = get_formspec,
|
||||
|
|
|
@ -17,68 +17,71 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function get_formspec(tabview, name, tabdata)
|
||||
local render_details = core.is_yes(core.setting_getbool("public_serverlist"))
|
||||
|
||||
-- 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 retval =
|
||||
"label[7.75,-0.15;" .. fgettext("Address / Port :") .. "]" ..
|
||||
"label[7.75,1.05;" .. fgettext("Name / Password :") .. "]" ..
|
||||
"field[8,0.75;3.4,0.5;te_address;;" ..
|
||||
core.formspec_escape(core.setting_get("address")) .. "]" ..
|
||||
"field[11.25,0.75;1.3,0.5;te_port;;" ..
|
||||
core.formspec_escape(core.setting_get("remote_port")) .. "]" ..
|
||||
"checkbox[0,4.85;cb_public_serverlist;" .. fgettext("Public Serverlist") .. ";" ..
|
||||
dump(core.setting_getbool("public_serverlist")) .. "]"
|
||||
|
||||
if not core.setting_getbool("public_serverlist") then
|
||||
retval = retval ..
|
||||
"button[8,4.9;2,0.5;btn_delete_favorite;" .. fgettext("Delete") .. "]"
|
||||
end
|
||||
|
||||
retval = retval ..
|
||||
"button[10,4.9;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]" ..
|
||||
"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")) .. "]" ..
|
||||
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]" ..
|
||||
"textarea[8.1,2.4;4.26,2.6;;"
|
||||
|
||||
if tabdata.fav_selected ~= nil and
|
||||
menudata.favorites[tabdata.fav_selected] ~= nil and
|
||||
menudata.favorites[tabdata.fav_selected].description ~= nil then
|
||||
retval = retval ..
|
||||
core.formspec_escape(menudata.favorites[tabdata.fav_selected].description,true)
|
||||
end
|
||||
"box[7.73,2.35;4.3,2.28;#999999]"
|
||||
|
||||
retval = retval ..
|
||||
";]"
|
||||
|
||||
--favourites
|
||||
if render_details then
|
||||
retval = retval .. "tablecolumns[" ..
|
||||
"color,span=3;" ..
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
"text,padding=1]" -- name
|
||||
else
|
||||
retval = retval .. "tablecolumns[text]"
|
||||
end
|
||||
retval = retval ..
|
||||
"table[-0.15,-0.1;7.75,5;favourites;"
|
||||
|
||||
if #menudata.favorites > 0 then
|
||||
retval = retval .. render_favorite(menudata.favorites[1],render_details)
|
||||
|
||||
for i=2,#menudata.favorites,1 do
|
||||
retval = retval .. "," .. render_favorite(menudata.favorites[i],render_details)
|
||||
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;" ..
|
||||
fgettext("Del. Favorite") .. "]"
|
||||
end
|
||||
if fav_selected.description then
|
||||
retval = retval .. "textarea[8.1,2.4;4.26,2.6;;" ..
|
||||
core.formspec_escape((gamedata.serverdescription or ""), true) .. ";]"
|
||||
end
|
||||
end
|
||||
|
||||
if tabdata.fav_selected ~= nil then
|
||||
--favourites
|
||||
retval = retval .. "tablecolumns[" ..
|
||||
image_column(fgettext("Favorite"), "favorite") .. ";" ..
|
||||
"color,span=3;" ..
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
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;"
|
||||
|
||||
if #menudata.favorites > 0 then
|
||||
local favs = core.get_favorites("local")
|
||||
if #favs > 0 then
|
||||
for i = 1, #favs do
|
||||
for j = 1, #menudata.favorites do
|
||||
if menudata.favorites[j].address == favs[i].address and
|
||||
menudata.favorites[j].port == favs[i].port then
|
||||
table.insert(menudata.favorites, i, table.remove(menudata.favorites, j))
|
||||
end
|
||||
end
|
||||
if favs[i].address ~= menudata.favorites[i].address then
|
||||
table.insert(menudata.favorites, i, favs[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
retval = retval .. render_favorite(menudata.favorites[1], (#favs > 0))
|
||||
for i = 2, #menudata.favorites do
|
||||
retval = retval .. "," .. render_favorite(menudata.favorites[i], (i <= #favs))
|
||||
end
|
||||
end
|
||||
|
||||
if tabdata.fav_selected then
|
||||
retval = retval .. ";" .. tabdata.fav_selected .. "]"
|
||||
else
|
||||
retval = retval .. ";0]"
|
||||
|
@ -89,36 +92,38 @@ end
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
if fields["te_name"] ~= nil then
|
||||
gamedata.playername = fields["te_name"]
|
||||
core.setting_set("name", fields["te_name"])
|
||||
if fields.te_name then
|
||||
gamedata.playername = fields.te_name
|
||||
core.setting_set("name", fields.te_name)
|
||||
end
|
||||
|
||||
if fields["favourites"] ~= nil then
|
||||
local event = core.explode_table_event(fields["favourites"])
|
||||
if fields.favourites then
|
||||
local event = core.explode_table_event(fields.favourites)
|
||||
local fav = menudata.favorites[event.row]
|
||||
|
||||
if event.type == "DCL" then
|
||||
if event.row <= #menudata.favorites then
|
||||
if not is_server_protocol_compat_or_error(menudata.favorites[event.row].proto_min,
|
||||
menudata.favorites[event.row].proto_max) then
|
||||
if menudata.favorites_is_public and
|
||||
not is_server_protocol_compat_or_error(
|
||||
fav.proto_min, fav.proto_max) then
|
||||
return true
|
||||
end
|
||||
gamedata.address = menudata.favorites[event.row].address
|
||||
gamedata.port = menudata.favorites[event.row].port
|
||||
gamedata.playername = fields["te_name"]
|
||||
if fields["te_pwd"] ~= nil then
|
||||
gamedata.password = fields["te_pwd"]
|
||||
end
|
||||
|
||||
gamedata.address = fav.address
|
||||
gamedata.port = fav.port
|
||||
gamedata.playername = fields.te_name
|
||||
gamedata.selected_world = 0
|
||||
|
||||
if menudata.favorites ~= nil then
|
||||
gamedata.servername = menudata.favorites[event.row].name
|
||||
gamedata.serverdescription = menudata.favorites[event.row].description
|
||||
if fields.te_pwd then
|
||||
gamedata.password = fields.te_pwd
|
||||
end
|
||||
|
||||
if gamedata.address ~= nil and
|
||||
gamedata.port ~= nil then
|
||||
core.setting_set("address",gamedata.address)
|
||||
core.setting_set("remote_port",gamedata.port)
|
||||
gamedata.servername = fav.name
|
||||
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.start()
|
||||
end
|
||||
end
|
||||
|
@ -127,101 +132,92 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
|
||||
if event.type == "CHG" then
|
||||
if event.row <= #menudata.favorites then
|
||||
local address = menudata.favorites[event.row].address
|
||||
local port = menudata.favorites[event.row].port
|
||||
gamedata.fav = false
|
||||
local favs = core.get_favorites("local")
|
||||
local address = fav.address
|
||||
local port = fav.port
|
||||
gamedata.serverdescription = fav.description
|
||||
|
||||
if address ~= nil and
|
||||
port ~= nil then
|
||||
core.setting_set("address",address)
|
||||
core.setting_set("remote_port",port)
|
||||
for i = 1, #favs do
|
||||
if fav.address == favs[i].address and
|
||||
fav.port == favs[i].port then
|
||||
gamedata.fav = true
|
||||
end
|
||||
end
|
||||
|
||||
if address and port then
|
||||
core.setting_set("address", address)
|
||||
core.setting_set("remote_port", port)
|
||||
end
|
||||
tabdata.fav_selected = event.row
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if fields["key_up"] ~= nil or
|
||||
fields["key_down"] ~= nil then
|
||||
|
||||
if fields.key_up or fields.key_down then
|
||||
local fav_idx = core.get_table_index("favourites")
|
||||
local fav = menudata.favorites[fav_idx]
|
||||
|
||||
if fav_idx ~= nil then
|
||||
if fields["key_up"] ~= nil and fav_idx > 1 then
|
||||
fav_idx = fav_idx -1
|
||||
else if fields["key_down"] and fav_idx < #menudata.favorites then
|
||||
fav_idx = fav_idx +1
|
||||
end end
|
||||
if fav_idx then
|
||||
if fields.key_up and fav_idx > 1 then
|
||||
fav_idx = fav_idx - 1
|
||||
elseif fields.key_down and fav_idx < #menudata.favorites then
|
||||
fav_idx = fav_idx + 1
|
||||
end
|
||||
else
|
||||
fav_idx = 1
|
||||
end
|
||||
|
||||
if menudata.favorites == nil or
|
||||
menudata.favorites[fav_idx] == nil then
|
||||
|
||||
if not menudata.favorites or not fav then
|
||||
tabdata.fav_selected = 0
|
||||
return true
|
||||
end
|
||||
|
||||
local address = menudata.favorites[fav_idx].address
|
||||
local port = menudata.favorites[fav_idx].port
|
||||
|
||||
if address ~= nil and
|
||||
port ~= nil then
|
||||
core.setting_set("address",address)
|
||||
core.setting_set("remote_port",port)
|
||||
local address = fav.address
|
||||
local port = fav.port
|
||||
|
||||
if address and port then
|
||||
core.setting_set("address", address)
|
||||
core.setting_set("remote_port", port)
|
||||
end
|
||||
|
||||
tabdata.fav_selected = fav_idx
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_public_serverlist"] ~= nil then
|
||||
core.setting_set("public_serverlist", fields["cb_public_serverlist"])
|
||||
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
asyncOnlineFavourites()
|
||||
else
|
||||
menudata.favorites = core.get_favorites("local")
|
||||
end
|
||||
tabdata.fav_selected = nil
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_delete_favorite"] ~= nil then
|
||||
if fields.btn_delete_favorite then
|
||||
local current_favourite = core.get_table_index("favourites")
|
||||
if current_favourite == nil then return end
|
||||
if not current_favourite then return end
|
||||
|
||||
core.delete_favorite(current_favourite)
|
||||
menudata.favorites = order_favorite_list(core.get_favorites())
|
||||
asyncOnlineFavourites()
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.setting_set("address","")
|
||||
core.setting_set("remote_port","30000")
|
||||
|
||||
core.setting_set("address", "")
|
||||
core.setting_set("remote_port", "30000")
|
||||
return true
|
||||
end
|
||||
|
||||
if (fields["btn_mp_connect"] ~= nil or
|
||||
fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and
|
||||
fields["te_port"] ~= nil then
|
||||
|
||||
gamedata.playername = fields["te_name"]
|
||||
gamedata.password = fields["te_pwd"]
|
||||
gamedata.address = fields["te_address"]
|
||||
gamedata.port = fields["te_port"]
|
||||
|
||||
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]
|
||||
|
||||
if fav_idx ~= nil and fav_idx <= #menudata.favorites and
|
||||
menudata.favorites[fav_idx].address == fields["te_address"] and
|
||||
menudata.favorites[fav_idx].port == fields["te_port"] then
|
||||
if fav_idx and fav_idx <= #menudata.favorites and
|
||||
fav.address == fields.te_address and
|
||||
fav.port == fields.te_port then
|
||||
|
||||
gamedata.servername = menudata.favorites[fav_idx].name
|
||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
||||
gamedata.servername = fav.name
|
||||
gamedata.serverdescription = fav.description
|
||||
|
||||
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
|
||||
menudata.favorites[fav_idx].proto_max)then
|
||||
if menudata.favorites_is_public and
|
||||
not is_server_protocol_compat_or_error(
|
||||
fav.proto_min, fav.proto_max) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
|
@ -229,10 +225,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
gamedata.serverdescription = ""
|
||||
end
|
||||
|
||||
gamedata.selected_world = 0
|
||||
|
||||
core.setting_set("address", fields["te_address"])
|
||||
core.setting_set("remote_port",fields["te_port"])
|
||||
core.setting_set("address", fields.te_address)
|
||||
core.setting_set("remote_port", fields.te_port)
|
||||
|
||||
core.start()
|
||||
return true
|
||||
|
@ -240,22 +234,16 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
return false
|
||||
end
|
||||
|
||||
local function on_change(type,old_tab,new_tab)
|
||||
if type == "LEAVE" then
|
||||
return
|
||||
end
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
asyncOnlineFavourites()
|
||||
else
|
||||
menudata.favorites = core.get_favorites("local")
|
||||
end
|
||||
local function on_change(type, old_tab, new_tab)
|
||||
if type == "LEAVE" then return end
|
||||
asyncOnlineFavourites()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_multiplayer = {
|
||||
return {
|
||||
name = "multiplayer",
|
||||
caption = fgettext("Client"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = on_change
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,10 +186,10 @@ local function main_button_handler(this, fields, name, tabdata)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_server = {
|
||||
return {
|
||||
name = "server",
|
||||
caption = fgettext("Server"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,66 +17,80 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function get_formspec(tabview, name, tabdata)
|
||||
local retval = ""
|
||||
-- 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 render_details = dump(core.setting_getbool("public_serverlist"))
|
||||
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")) .."]" ..
|
||||
"field[5.75,3.35;2.25,0.5;te_port;;" ..
|
||||
core.formspec_escape(core.setting_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")) .."]" ..
|
||||
"pwdfield[9.8,2;2.6,0.5;te_pwd;]"
|
||||
|
||||
retval = retval ..
|
||||
"label[8,0.5;".. fgettext("Name/Password") .. "]" ..
|
||||
"field[0.25,3.25;5.5,0.5;te_address;;" ..
|
||||
core.formspec_escape(core.setting_get("address")) .."]" ..
|
||||
"field[5.75,3.25;2.25,0.5;te_port;;" ..
|
||||
core.formspec_escape(core.setting_get("remote_port")) .."]" ..
|
||||
"checkbox[8,-0.25;cb_public_serverlist;".. fgettext("Public Serverlist") .. ";" ..
|
||||
render_details .. "]"
|
||||
|
||||
retval = retval ..
|
||||
"button[8,2.5;4,1.5;btn_mp_connect;".. fgettext("Connect") .. "]" ..
|
||||
"field[8.75,1.5;3.5,0.5;te_name;;" ..
|
||||
core.formspec_escape(core.setting_get("name")) .."]" ..
|
||||
"pwdfield[8.75,2.3;3.5,0.5;te_pwd;]"
|
||||
|
||||
if render_details then
|
||||
retval = retval .. "tablecolumns[" ..
|
||||
"color,span=3;" ..
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
"text,padding=1]" -- name
|
||||
else
|
||||
retval = retval .. "tablecolumns[text]"
|
||||
end
|
||||
retval = retval ..
|
||||
"table[-0.05,0;7.55,2.75;favourites;"
|
||||
|
||||
if #menudata.favorites > 0 then
|
||||
retval = retval .. render_favorite(menudata.favorites[1],render_details)
|
||||
|
||||
for i=2,#menudata.favorites,1 do
|
||||
retval = retval .. "," .. render_favorite(menudata.favorites[i],render_details)
|
||||
if tabdata.fav_selected and fav_selected then
|
||||
if gamedata.fav then
|
||||
retval = retval .. "button[7.7,2.6;2.3,1.5;btn_delete_favorite;" ..
|
||||
fgettext("Del. Favorite") .. "]"
|
||||
end
|
||||
end
|
||||
|
||||
if tabdata.fav_selected ~= nil then
|
||||
retval = retval .. "tablecolumns[" ..
|
||||
image_column(fgettext("Favorite"), "favorite") .. ";" ..
|
||||
"color,span=3;" ..
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
"text,padding=1]" .. -- name
|
||||
"table[-0.05,0;9.2,2.75;favourites;"
|
||||
|
||||
if #menudata.favorites > 0 then
|
||||
local favs = core.get_favorites("local")
|
||||
if #favs > 0 then
|
||||
for i = 1, #favs do
|
||||
for j = 1, #menudata.favorites do
|
||||
if menudata.favorites[j].address == favs[i].address and
|
||||
menudata.favorites[j].port == favs[i].port then
|
||||
table.insert(menudata.favorites, i,
|
||||
table.remove(menudata.favorites, j))
|
||||
end
|
||||
end
|
||||
if favs[i].address ~= menudata.favorites[i].address then
|
||||
table.insert(menudata.favorites, i, favs[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
retval = retval .. render_favorite(menudata.favorites[1], (#favs > 0))
|
||||
for i = 2, #menudata.favorites do
|
||||
retval = retval .. "," .. render_favorite(menudata.favorites[i], (i <= #favs))
|
||||
end
|
||||
end
|
||||
|
||||
if tabdata.fav_selected then
|
||||
retval = retval .. ";" .. tabdata.fav_selected .. "]"
|
||||
else
|
||||
retval = retval .. ";0]"
|
||||
end
|
||||
|
||||
-- separator
|
||||
retval = retval ..
|
||||
"box[-0.28,3.75;12.4,0.1;#FFFFFF]"
|
||||
retval = retval .. "box[-0.28,3.75;12.4,0.1;#FFFFFF]"
|
||||
|
||||
-- checkboxes
|
||||
retval = retval ..
|
||||
"checkbox[8.0,3.9;cb_creative;".. fgettext("Creative Mode") .. ";" ..
|
||||
dump(core.setting_getbool("creative_mode")) .. "]"..
|
||||
dump(core.setting_getbool("creative_mode")) .. "]"..
|
||||
"checkbox[8.0,4.4;cb_damage;".. fgettext("Enable Damage") .. ";" ..
|
||||
dump(core.setting_getbool("enable_damage")) .. "]"
|
||||
dump(core.setting_getbool("enable_damage")) .. "]"
|
||||
-- buttons
|
||||
retval = retval ..
|
||||
"button[0,3.7;8,1.5;btn_start_singleplayer;" .. fgettext("Start Singleplayer") .. "]" ..
|
||||
|
@ -87,94 +101,100 @@ end
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
if fields["btn_start_singleplayer"] then
|
||||
if fields.btn_start_singleplayer then
|
||||
gamedata.selected_world = gamedata.worldindex
|
||||
gamedata.singleplayer = true
|
||||
core.start()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["favourites"] ~= nil then
|
||||
local event = core.explode_table_event(fields["favourites"])
|
||||
|
||||
if fields.favourites then
|
||||
local event = core.explode_table_event(fields.favourites)
|
||||
if event.type == "CHG" then
|
||||
if event.row <= #menudata.favorites then
|
||||
local address = menudata.favorites[event.row].address
|
||||
local port = menudata.favorites[event.row].port
|
||||
gamedata.fav = false
|
||||
local favs = core.get_favorites("local")
|
||||
local fav = menudata.favorites[event.row]
|
||||
local address = fav.address
|
||||
local port = fav.port
|
||||
gamedata.serverdescription = fav.description
|
||||
|
||||
if address ~= nil and
|
||||
port ~= nil then
|
||||
core.setting_set("address",address)
|
||||
core.setting_set("remote_port",port)
|
||||
for i = 1, #favs do
|
||||
if fav.address == favs[i].address and
|
||||
fav.port == favs[i].port then
|
||||
gamedata.fav = true
|
||||
end
|
||||
end
|
||||
|
||||
if address and port then
|
||||
core.setting_set("address", address)
|
||||
core.setting_set("remote_port", port)
|
||||
end
|
||||
tabdata.fav_selected = event.row
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if fields.btn_delete_favorite then
|
||||
local current_favourite = core.get_table_index("favourites")
|
||||
if not current_favourite then return end
|
||||
|
||||
core.delete_favorite(current_favourite)
|
||||
asyncOnlineFavourites()
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.setting_set("address", "")
|
||||
core.setting_set("remote_port", "30000")
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_public_serverlist"] ~= nil then
|
||||
core.setting_set("public_serverlist", fields["cb_public_serverlist"])
|
||||
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
asyncOnlineFavourites()
|
||||
else
|
||||
menudata.favorites = core.get_favorites("local")
|
||||
end
|
||||
if fields.cb_creative then
|
||||
core.setting_set("creative_mode", fields.cb_creative)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_creative"] then
|
||||
core.setting_set("creative_mode", fields["cb_creative"])
|
||||
if fields.cb_damage then
|
||||
core.setting_set("enable_damage", fields.cb_damage)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_damage"] then
|
||||
core.setting_set("enable_damage", fields["cb_damage"])
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_mp_connect"] ~= nil or
|
||||
fields["key_enter"] ~= nil then
|
||||
|
||||
gamedata.playername = fields["te_name"]
|
||||
gamedata.password = fields["te_pwd"]
|
||||
gamedata.address = fields["te_address"]
|
||||
gamedata.port = fields["te_port"]
|
||||
|
||||
if fields.btn_mp_connect or fields.key_enter then
|
||||
gamedata.playername = fields.te_name
|
||||
gamedata.password = fields.te_pwd
|
||||
gamedata.address = fields.te_address
|
||||
gamedata.port = fields.te_port
|
||||
local fav_idx = core.get_textlist_index("favourites")
|
||||
|
||||
if fav_idx ~= nil and fav_idx <= #menudata.favorites and
|
||||
menudata.favorites[fav_idx].address == fields["te_address"] and
|
||||
menudata.favorites[fav_idx].port == fields["te_port"] then
|
||||
if fav_idx and fav_idx <= #menudata.favorites and
|
||||
menudata.favorites[fav_idx].address == fields.te_address and
|
||||
menudata.favorites[fav_idx].port == fields.te_port then
|
||||
local fav = menudata.favorites[fav_idx]
|
||||
gamedata.servername = fav.name
|
||||
gamedata.serverdescription = fav.description
|
||||
|
||||
gamedata.servername = menudata.favorites[fav_idx].name
|
||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
||||
|
||||
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
|
||||
menudata.favorites[fav_idx].proto_max) then
|
||||
if menudata.favorites_is_public and
|
||||
not is_server_protocol_compat_or_error(
|
||||
fav.proto_min, fav.proto_max) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
end
|
||||
|
||||
gamedata.selected_world = 0
|
||||
|
||||
core.setting_set("address",fields["te_address"])
|
||||
core.setting_set("remote_port",fields["te_port"])
|
||||
core.setting_set("address", fields.te_address)
|
||||
core.setting_set("remote_port", fields.te_port)
|
||||
|
||||
core.start()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_config_sp_world"] ~= nil then
|
||||
if fields.btn_config_sp_world then
|
||||
local configdialog = create_configure_world_dlg(1)
|
||||
|
||||
if (configdialog ~= nil) then
|
||||
if configdialog then
|
||||
configdialog:set_parent(tabview)
|
||||
tabview:hide()
|
||||
configdialog:show()
|
||||
|
@ -185,21 +205,15 @@ end
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function on_activate(type,old_tab,new_tab)
|
||||
if type == "LEAVE" then
|
||||
return
|
||||
end
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
asyncOnlineFavourites()
|
||||
else
|
||||
menudata.favorites = core.get_favorites("local")
|
||||
end
|
||||
if type == "LEAVE" then return end
|
||||
asyncOnlineFavourites()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_simple_main = {
|
||||
return {
|
||||
name = "main",
|
||||
caption = fgettext("Main"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = on_activate
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,10 +241,10 @@ local function on_change(type, old_tab, new_tab)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_singleplayer = {
|
||||
return {
|
||||
name = "singleplayer",
|
||||
caption = fgettext("Singleplayer"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = on_change
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,17 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function filter_texture_pack_list(list)
|
||||
local retval = {fgettext("None")}
|
||||
local retval = {}
|
||||
|
||||
for _, item in ipairs(list) do
|
||||
if item ~= "base" then
|
||||
table.insert(retval, item)
|
||||
retval[#retval + 1] = item
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(retval)
|
||||
table.insert(retval, 1, fgettext("None"))
|
||||
|
||||
return retval
|
||||
end
|
||||
|
||||
|
@ -31,9 +36,9 @@ local function render_texture_pack_list(list)
|
|||
local retval = ""
|
||||
|
||||
for i, v in ipairs(list) do
|
||||
if v:sub(1,1) ~= "." then
|
||||
if v:sub(1, 1) ~= "." then
|
||||
if retval ~= "" then
|
||||
retval = retval ..","
|
||||
retval = retval .. ","
|
||||
end
|
||||
|
||||
retval = retval .. core.formspec_escape(v)
|
||||
|
@ -46,14 +51,14 @@ end
|
|||
--------------------------------------------------------------------------------
|
||||
local function get_formspec(tabview, name, tabdata)
|
||||
|
||||
local retval = "label[4,-0.25;".. fgettext("Select texture pack:") .. "]"..
|
||||
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 list = filter_texture_pack_list(core.get_dir_list(core.get_texturepath(), true))
|
||||
local index = tonumber(core.setting_get("mainmenu_last_selected_TP"))
|
||||
|
||||
if index == nil then index = 1 end
|
||||
if not index then index = 1 end
|
||||
|
||||
if current_texture_path == "" then
|
||||
retval = retval ..
|
||||
|
@ -62,15 +67,16 @@ local function get_formspec(tabview, name, tabdata)
|
|||
return retval
|
||||
end
|
||||
|
||||
local infofile = current_texture_path ..DIR_DELIM.."description.txt"
|
||||
local infofile = current_texture_path .. DIR_DELIM .. "description.txt"
|
||||
-- This adds backwards compatibility for old texture pack description files named
|
||||
-- "info.txt", and should be removed once all such texture packs have been updated
|
||||
if not file_exists(infofile) then
|
||||
infofile = current_texture_path ..DIR_DELIM.."info.txt"
|
||||
infofile = current_texture_path .. DIR_DELIM .. "info.txt"
|
||||
if file_exists(infofile) then
|
||||
core.log("info.txt is depreciated. description.txt should be used instead.");
|
||||
core.log("info.txt is depreciated. description.txt should be used instead.")
|
||||
end
|
||||
end
|
||||
|
||||
local infotext = ""
|
||||
local f = io.open(infofile, "r")
|
||||
if not f then
|
||||
|
@ -80,8 +86,8 @@ local function get_formspec(tabview, name, tabdata)
|
|||
f:close()
|
||||
end
|
||||
|
||||
local screenfile = current_texture_path..DIR_DELIM.."screenshot.png"
|
||||
local no_screenshot = nil
|
||||
local screenfile = current_texture_path .. DIR_DELIM .. "screenshot.png"
|
||||
local no_screenshot
|
||||
if not file_exists(screenfile) then
|
||||
screenfile = nil
|
||||
no_screenshot = defaulttexturedir .. "no_screenshot.png"
|
||||
|
@ -90,24 +96,24 @@ local function get_formspec(tabview, name, tabdata)
|
|||
return retval ..
|
||||
render_texture_pack_list(list) ..
|
||||
";" .. index .. "]" ..
|
||||
"image[0.25,0.25;4.0,3.7;"..core.formspec_escape(screenfile or no_screenshot).."]"..
|
||||
"textarea[0.6,3.25;3.7,1.5;;"..core.formspec_escape(infotext or "")..";]"
|
||||
"image[0.25,0.25;4.0,3.7;" .. core.formspec_escape(screenfile or no_screenshot) .. "]" ..
|
||||
"textarea[0.6,3.5;3.7,1.5;;" .. core.formspec_escape(infotext or "") .. ";]"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
if fields["TPs"] ~= nil then
|
||||
if fields["TPs"] then
|
||||
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.setting_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 ~= nil and #list >= current_index then
|
||||
local new_path = core.get_texturepath()..DIR_DELIM..list[current_index]
|
||||
if list[current_index] == fgettext("None") then new_path = "" end
|
||||
|
||||
if current_index and #list >= current_index then
|
||||
local new_path = core.get_texturepath() .. DIR_DELIM .. list[current_index]
|
||||
if list[current_index] == fgettext("None") then
|
||||
new_path = ""
|
||||
end
|
||||
core.setting_set("texture_path", new_path)
|
||||
end
|
||||
end
|
||||
|
@ -117,10 +123,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
tab_texturepacks = {
|
||||
return {
|
||||
name = "texturepacks",
|
||||
caption = fgettext("Texturepacks"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ function mm_texture.set_dirt_bg()
|
|||
end
|
||||
end
|
||||
|
||||
--use base pack
|
||||
local minimalpath = defaulttexturedir .. "dirt_bg.png"
|
||||
-- Use universal fallback texture in textures/base/pack
|
||||
local minimalpath = defaulttexturedir .. "menu_bg.png"
|
||||
core.set_background("background", minimalpath, true, 128)
|
||||
end
|
||||
|
|
|
@ -209,11 +209,11 @@ keymap_toggle_profiler (Profiler toggle key) key KEY_F6
|
|||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_camera_mode (Toggle camera mode key) key KEY_F7
|
||||
|
||||
# Key for increasing the viewing range. Modifies the minimum viewing range.
|
||||
# Key for increasing the viewing range.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_increase_viewing_range_min (View range increase key) key +
|
||||
|
||||
# Key for decreasing the viewing range. Modifies the minimum viewing range.
|
||||
# Key for decreasing the viewing range.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_decrease_viewing_range_min (View range decrease key) key -
|
||||
|
||||
|
@ -232,9 +232,18 @@ address (Server address) string
|
|||
# Note that the port field in the main menu overrides this setting.
|
||||
remote_port (Remote port) int 30000 1 65535
|
||||
|
||||
# Whether to support older servers before protocol version 25.
|
||||
# Enable if you want to connect to 0.4.12 servers and before.
|
||||
# Servers starting with 0.4.13 will work, 0.4.12-dev servers may work.
|
||||
# Disabling this option will protect your password better.
|
||||
send_pre_v25_init (Support older servers) bool true
|
||||
|
||||
# Save the map received by the client on disk.
|
||||
enable_local_map_saving (Saving map received from server) bool false
|
||||
|
||||
# Show entity selection boxes
|
||||
show_entity_selectionbox (Show entity selection boxes) bool true
|
||||
|
||||
# Enable usage of remote media server (if provided by server).
|
||||
# Remote servers offer a significantly faster way to download media (e.g. textures)
|
||||
# when connecting to the server.
|
||||
|
@ -252,14 +261,12 @@ serverlist_file (Serverlist file) string favoriteservers.txt
|
|||
|
||||
[***Basic]
|
||||
|
||||
# Enable VBO
|
||||
enable_vbo (VBO) bool true
|
||||
|
||||
# Whether to fog out the end of the visible area.
|
||||
enable_fog (Fog) bool true
|
||||
|
||||
# Enable a bit lower water surface, so it doesn't "fill" the node completely.
|
||||
# Note that this is not quite optimized and that smooth lighting on the
|
||||
# water surface doesn't work with this.
|
||||
new_style_water (New style water) bool false
|
||||
|
||||
# Leaves style:
|
||||
# - Fancy: all faces visible
|
||||
# - Simple: only outer faces, if defined special_tiles are used
|
||||
|
@ -279,6 +286,9 @@ enable_clouds (Clouds) bool true
|
|||
# Use 3D cloud look instead of flat.
|
||||
enable_3d_clouds (3D clouds) bool true
|
||||
|
||||
# Method used to highlight selected object.
|
||||
node_highlighting (Node highlighting) enum box box,halo
|
||||
|
||||
[***Filtering]
|
||||
|
||||
# Use mip mapping to scale textures. May slightly increase performance.
|
||||
|
@ -308,11 +318,6 @@ texture_clean_transparent (Clean transparent textures) bool false
|
|||
# enabled.
|
||||
texture_min_size (Minimum texture size for filters) int 64
|
||||
|
||||
# Pre-generate all item visuals used in the inventory.
|
||||
# This increases startup time, but runs smoother in-game.
|
||||
# The generated textures can easily exceed your VRAM, causing artifacts in the inventory.
|
||||
preload_item_visuals (Preload inventory textures) bool false
|
||||
|
||||
# Experimental option, might cause visible spaces between blocks
|
||||
# when set to higher number than 0.
|
||||
fsaa (FSAA) enum 0 0,1,2,4,8,16
|
||||
|
@ -323,6 +328,11 @@ fsaa (FSAA) enum 0 0,1,2,4,8,16
|
|||
# Thy only work with the OpenGL video backend.
|
||||
enable_shaders (Shaders) bool true
|
||||
|
||||
[****Tone Mapping]
|
||||
|
||||
# Enables filmic tone mapping
|
||||
tone_mapping (Filmic tone mapping) bool false
|
||||
|
||||
[****Bumpmapping]
|
||||
|
||||
# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack
|
||||
|
@ -385,10 +395,6 @@ enable_waving_plants (Waving plants) bool false
|
|||
|
||||
[***Advanced]
|
||||
|
||||
# Minimum wanted FPS.
|
||||
# The amount of rendered stuff is dynamically set according to this. and viewing range min and max.
|
||||
wanted_fps (Wanted FPS) int 30
|
||||
|
||||
# If FPS would go higher than this, limit it by sleeping
|
||||
# to not waste CPU power for no benefit.
|
||||
fps_max (Maximum FPS) int 60
|
||||
|
@ -396,18 +402,14 @@ fps_max (Maximum FPS) int 60
|
|||
# Maximum FPS when game is paused.
|
||||
pause_fps_max (FPS in pause menu) int 20
|
||||
|
||||
# The allowed adjustment range for the automatic rendering range adjustment.
|
||||
# Set this to be equal to viewing range minimum to disable the auto-adjustment algorithm.
|
||||
viewing_range_nodes_max (Viewing range maximum) int 160
|
||||
# View distance in nodes.
|
||||
# Min = 20
|
||||
viewing_range (Viewing range) int 100
|
||||
|
||||
# The allowed adjustment range for the automatic rendering range adjustment.
|
||||
# Set this to be equal to viewing range minimum to disable the auto-adjustment algorithm.
|
||||
viewing_range_nodes_min (Viewing range minimum) int 35
|
||||
|
||||
# Vertical initial window size.
|
||||
# Width component of the initial window size.
|
||||
screenW (Screen width) int 800
|
||||
|
||||
# Horizontal initial window size.
|
||||
# Height component of the initial window size.
|
||||
screenH (Screen height) int 600
|
||||
|
||||
# Fullscreen mode.
|
||||
|
@ -454,7 +456,8 @@ fall_bobbing_amount (Fall bobbing) float 0.0
|
|||
# - interlaced: odd/even line based polarisation screen support.
|
||||
# - topbottom: split screen top/bottom.
|
||||
# - sidebyside: split screen side by side.
|
||||
3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside
|
||||
# - pageflip: quadbuffer based 3d.
|
||||
3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,pageflip
|
||||
|
||||
# In-game chat console background color (R,G,B).
|
||||
console_color (Console color) string (0,0,0)
|
||||
|
@ -481,9 +484,6 @@ 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
|
||||
|
||||
# Enable selection highlighting for nodes (disables selectionbox).
|
||||
enable_node_highlighting (Node highlighting) bool false
|
||||
|
||||
# Enables caching of facedir rotated meshes.
|
||||
enable_mesh_cache (Mesh cache) bool false
|
||||
|
||||
|
@ -507,6 +507,9 @@ directional_colored_fog (Colored fog) bool true
|
|||
# set to the nearest valid value.
|
||||
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
|
||||
|
||||
[**Menus]
|
||||
|
||||
# Use a cloud animation for the main menu background.
|
||||
|
@ -560,6 +563,14 @@ fallback_font_shadow_alpha (Fallback font shadow alpha) int 128 0 255
|
|||
# Path to save screenshots at.
|
||||
screenshot_path (Screenshot folder) path
|
||||
|
||||
# Format of screenshots.
|
||||
screenshot_format (Screenshot format) enum png png,jpg,bmp,pcx,ppm,tga
|
||||
|
||||
# Screenshot quality. Only used for JPEG format.
|
||||
# 1 means worst quality; 100 means best quality.
|
||||
# Use 0 for default quality.
|
||||
screenshot_quality (Screenshot quality) int 0 0 100
|
||||
|
||||
[**Advanced]
|
||||
|
||||
# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens.
|
||||
|
@ -680,6 +691,9 @@ default_password (Default password) string
|
|||
# See /privs in game for a full list on your server and mod configuration.
|
||||
default_privs (Default privileges) string interact, shout
|
||||
|
||||
# Privileges that players with basic_privs can grant
|
||||
basic_privs (Basic Privileges) string interact, shout
|
||||
|
||||
# Whether players are shown to clients without any range limit.
|
||||
# Deprecated, use the setting player_transfer_distance instead.
|
||||
unlimited_player_transfer_distance (Unlimited player transfer distance) bool true
|
||||
|
@ -693,12 +707,6 @@ enable_pvp (Player versus Player) bool true
|
|||
# If this is set, players will always (re)spawn at the given position.
|
||||
static_spawnpoint (Static spawnpoint) string
|
||||
|
||||
# Maximum distance above water level for player spawn.
|
||||
# Larger values result in spawn points closer to (x = 0, z = 0).
|
||||
# Smaller values may result in a suitable spawn point not being found,
|
||||
# resulting in a spawn at (0, 0, 0) possibly buried underground.
|
||||
vertical_spawn_range (Vertical spawn range) int 16
|
||||
|
||||
# If enabled, new players cannot join with an empty password.
|
||||
disallow_empty_password (Disallow empty passwords) bool false
|
||||
|
||||
|
@ -793,6 +801,15 @@ sqlite_synchronous (Synchronous SQLite) enum 2 0,1,2
|
|||
# Length of a server tick and the interval at which objects are generally updated over network.
|
||||
dedicated_server_step (Dedicated server step) float 0.1
|
||||
|
||||
# Time in between active block management cycles
|
||||
active_block_mgmt_interval (Active Block Management interval) float 2.0
|
||||
|
||||
# Length of time between ABM execution cycles
|
||||
abm_interval (Active Block Modifier interval) float 1.0
|
||||
|
||||
# Length of time between NodeTimer execution cycles
|
||||
nodetimer_interval (NodeTimer interval) float 1.0
|
||||
|
||||
# If enabled, invalid world data won't cause the server to shut down.
|
||||
# Only enable this if you know what you are doing.
|
||||
ignore_world_load_errors (Ignore world errors) bool false
|
||||
|
@ -812,7 +829,7 @@ liquid_update (Liquid update tick) float 1.0
|
|||
|
||||
# Name of map generator to be used when creating a new world.
|
||||
# Creating a world in the main menu will override this.
|
||||
mg_name (Mapgen name) enum v6 v5,v6,v7,fractal,singlenode
|
||||
mg_name (Mapgen name) enum v6 v5,v6,v7,flat,valleys,fractal,singlenode
|
||||
|
||||
# Water surface level of the world.
|
||||
water_level (Water level) int 1
|
||||
|
@ -829,10 +846,11 @@ max_block_generate_distance (Max block generate distance) int 6
|
|||
map_generation_limit (Map generation limit) int 31000 0 31000
|
||||
|
||||
# Global map generation attributes.
|
||||
# In Mapgen v6 the 'decorations' flag controls all decorations except trees
|
||||
# and junglegrass, in all other mapgens this flag controls all decorations.
|
||||
# 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.
|
||||
# 'trees' and 'flat' flags only have effect in mgv6.
|
||||
mg_flags (Mapgen flags) flags trees,caves,dungeons,light trees,caves,dungeons,light,flat,notrees,nocaves,nodungeons,nolight,noflat
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mg_flags (Mapgen flags) flags caves,dungeons,light,decorations caves,dungeons,light,decorations,nocaves,nodungeons,nolight,nodecorations
|
||||
|
||||
[**Advanced]
|
||||
|
||||
|
@ -866,6 +884,9 @@ mg_biome_np_humidity_blend (Mapgen biome humidity blend noise parameters) noise_
|
|||
|
||||
[***Mapgen v5]
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgv5_cave_width (Mapgen v5 cave width) float 0.125
|
||||
|
||||
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
|
||||
|
@ -886,10 +907,10 @@ 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 enabled and the jungles flag is ignored.
|
||||
# When snowbiomes are enabled jungles are automatically enabled, 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 jungles,biomeblend,mudflow,snowbiomes,nojungles,nobiomeblend,nomudflow,nosnowbiomes
|
||||
# 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
|
||||
|
||||
# Controls size of deserts and beaches in Mapgen v6.
|
||||
# When snowbiomes are enabled 'mgv6_freq_desert' is ignored.
|
||||
|
@ -911,15 +932,18 @@ mgv6_np_apple_trees (Mapgen v6 apple trees noise parameters) noise_params 0, 1,
|
|||
[***Mapgen v7]
|
||||
|
||||
# Map generation attributes specific to Mapgen v7.
|
||||
# 'ridges' are the rivers.
|
||||
# The 'ridges' flag controls the rivers.
|
||||
# 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.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mgv7_spflags (Mapgen v7 flags) flags mountains,ridges mountains,ridges,nomountains,noridges
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgv7_cave_width (Mapgen v7 cave width) float 0.3
|
||||
|
||||
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 -12, 24, (500, 500, 500), 4213, 6, 0.7, 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 ridge water noise parameters) noise_params 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0
|
||||
|
@ -928,65 +952,107 @@ mgv7_np_ridge (Mapgen v7 ridge noise parameters) noise_params 0, 1, (100, 100, 1
|
|||
mgv7_np_cave1 (Mapgen v7 cave1 noise parameters) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0
|
||||
mgv7_np_cave2 (Mapgen v7 cave2 noise parameters) noise_params 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0
|
||||
|
||||
[***Mapgen flat]
|
||||
|
||||
# Map generation attributes specific to Mapgen flat.
|
||||
# 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
|
||||
|
||||
# Y of flat ground.
|
||||
mgflat_ground_level (Mapgen flat ground level) int 8
|
||||
|
||||
# Y of upper limit of large pseudorandom caves.
|
||||
mgflat_large_cave_depth (Mapgen flat large cave depth) int -33
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgflat_cave_width (Mapgen flat cave width) float 0.3
|
||||
|
||||
# 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
|
||||
|
||||
# Controls steepness/depth of lake depressions.
|
||||
mgflat_lake_steepness (Mapgen flat 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
|
||||
|
||||
# Controls steepness/height of hills.
|
||||
mgflat_hill_steepness (Mapgen flat 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
|
||||
|
||||
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, (128, 128, 128), 52534, 4, 0.5, 2.0
|
||||
mgflat_np_cave2 (Mapgen flat cave2 noise parameters) noise_params 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0
|
||||
|
||||
[***Mapgen fractal]
|
||||
|
||||
# Map generation attributes specific to Mapgen fractal.
|
||||
# 'julia' selects a julia set to be generated instead of a mandelbrot set.
|
||||
# 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.
|
||||
mgfractal_spflags (Mapgen fractal flags) flags nojulia julia,nojulia
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgfractal_cave_width (Mapgen fractal cave width) float 0.3
|
||||
|
||||
# Mandelbrot set: Iterations of the recursive function.
|
||||
# Controls scale of finest detail.
|
||||
mgfractal_m_iterations (Mapgen fractal mandelbrot iterations) int 9
|
||||
# Choice of 18 fractals from 9 formulas.
|
||||
# 1 = 4D "Roundy" mandelbrot set.
|
||||
# 2 = 4D "Roundy" julia set.
|
||||
# 3 = 4D "Squarry" mandelbrot set.
|
||||
# 4 = 4D "Squarry" julia set.
|
||||
# 5 = 4D "Mandy Cousin" mandelbrot set.
|
||||
# 6 = 4D "Mandy Cousin" julia set.
|
||||
# 7 = 4D "Variation" mandelbrot set.
|
||||
# 8 = 4D "Variation" julia set.
|
||||
# 9 = 3D "Mandelbrot/Mandelbar" mandelbrot set.
|
||||
# 10 = 3D "Mandelbrot/Mandelbar" julia set.
|
||||
# 11 = 3D "Christmas Tree" mandelbrot set.
|
||||
# 12 = 3D "Christmas Tree" julia set.
|
||||
# 13 = 3D "Mandelbulb" mandelbrot set.
|
||||
# 14 = 3D "Mandelbulb" julia set.
|
||||
# 15 = 3D "Cosine Mandelbulb" mandelbrot set.
|
||||
# 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
|
||||
|
||||
# Mandelbrot set: Approximate (X,Y,Z) scales in nodes.
|
||||
# Format is 3 numbers separated by commas and inside brackets.
|
||||
mgfractal_m_scale (Mapgen fractal mandelbrot scale) string (1024.0, 256.0, 1024.0)
|
||||
# Type 'string' is currently used for a v3f.
|
||||
# Iterations of the recursive function.
|
||||
# Controls the amount of fine detail.
|
||||
mgfractal_iterations (Mapgen fractal iterations) int 11
|
||||
|
||||
# Mandelbrot set: (X,Y,Z) offsets from world centre.
|
||||
# Format is 3 numbers separated by commas and inside brackets.
|
||||
# Range roughly -2 to 2, multiply by m_scale for offsets in nodes.
|
||||
mgfractal_m_offset (Mapgen fractal mandelbrot offset) string (1.75, 0.0, 0.0)
|
||||
# Type 'string' is currently used for a v3f.
|
||||
# Approximate (X,Y,Z) scale of fractal in nodes.
|
||||
mgfractal_scale (Mapgen fractal scale) v3f (4096.0, 1024.0, 4096.0)
|
||||
|
||||
# Mandelbrot set: W co-ordinate of the generated 3D slice of the 4D shape.
|
||||
# (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)
|
||||
|
||||
# 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_m_slice_w (Mapgen fractal mandelbrot slice w) float 0.0
|
||||
mgfractal_slice_w (Mapgen fractal slice w) float 0.0
|
||||
|
||||
# Julia set: Iterations of the recursive function.
|
||||
# Controls scale of finest detail.
|
||||
mgfractal_j_iterations (Mapgen fractal julia iterations) int 9
|
||||
|
||||
# Julia set: Approximate (X,Y,Z) scales in nodes.
|
||||
# Format is 3 numbers separated by commas and inside brackets.
|
||||
mgfractal_j_scale (Mapgen fractal julia scale) string (2048.0, 512.0, 2048.0)
|
||||
# Type 'string' is currently used for a v3f.
|
||||
|
||||
# Julia set: (X,Y,Z) offsets from world centre.
|
||||
# Format is 3 numbers separated by commas and inside brackets.
|
||||
# Range roughly -2 to 2, multiply by j_scale for offsets in nodes.
|
||||
mgfractal_j_offset (Mapgen fractal julia offset) string (0.0, 1.0, 0.0)
|
||||
# Type 'string' is currently used for a v3f.
|
||||
|
||||
# Julia set: W co-ordinate of the generated 3D slice of the 4D shape.
|
||||
# Range roughly -2 to 2.
|
||||
mgfractal_j_slice_w (Mapgen fractal julia slice w) float 0.0
|
||||
|
||||
# Julia set: X value determining the 4D shape.
|
||||
# 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
|
||||
|
||||
# Julia set: Y value determining the 4D shape.
|
||||
# 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
|
||||
|
||||
# Julia set: Z value determining the 4D shape.
|
||||
# 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
|
||||
|
||||
# Julia set: W value determining the 4D shape.
|
||||
# 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
|
||||
|
||||
|
@ -995,6 +1061,79 @@ mgfractal_np_filler_depth (Mapgen fractal filler depth noise parameters) noise_p
|
|||
mgfractal_np_cave1 (Mapgen fractal cave1 noise parameters) noise_params 0, 12, (128, 128, 128), 52534, 4, 0.5, 2.0
|
||||
mgfractal_np_cave2 (Mapgen fractal cave2 noise parameters) noise_params 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0
|
||||
|
||||
# Mapgen Valleys parameters
|
||||
[***Mapgen Valleys]
|
||||
|
||||
# General parameters
|
||||
[****General]
|
||||
|
||||
# Map generation attributes specific to Mapgen Valleys.
|
||||
# 'altitude_chill' makes higher elevations colder, which may cause biome issues.
|
||||
# 'humid_rivers' modifies the humidity around rivers and in areas where water would tend to pool,
|
||||
# it may interfere with delicately adjusted biomes.
|
||||
# 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.
|
||||
mg_valleys_spflags (Valleys C Flags) flags altitude_chill,humid_rivers altitude_chill,noaltitude_chill,humid_rivers,nohumid_rivers
|
||||
|
||||
# The altitude at which temperature drops by 20C
|
||||
mgvalleys_altitude_chill (Altitude Chill) int 90
|
||||
|
||||
# Depth below which you'll find large caves.
|
||||
mgvalleys_large_cave_depth (Large cave depth) int -33
|
||||
|
||||
# Creates unpredictable lava features in caves.
|
||||
# These can make mining difficult. Zero disables them. (0-10)
|
||||
mgvalleys_lava_features (Lava Features) int 0
|
||||
|
||||
# Depth below which you'll find massive caves.
|
||||
mgvalleys_massive_cave_depth (Massive cave depth) int -256
|
||||
|
||||
# How deep to make rivers
|
||||
mgvalleys_river_depth (River Depth) int 4
|
||||
|
||||
# How wide to make rivers
|
||||
mgvalleys_river_size (River Size) int 5
|
||||
|
||||
# Creates unpredictable water features in caves.
|
||||
# These can make mining difficult. Zero disables them. (0-10)
|
||||
mgvalleys_water_features (Water Features) int 0
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgvalleys_cave_width (Cave width) float 0.3
|
||||
|
||||
# Noise parameters
|
||||
[****Noises]
|
||||
|
||||
# Caves and tunnels form at the intersection of the two noises
|
||||
mgvalleys_np_cave1 (Cave noise #1) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0
|
||||
|
||||
# Caves and tunnels form at the intersection of the two noises
|
||||
mgvalleys_np_cave2 (Cave noise #2) noise_params 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0
|
||||
|
||||
# The depth of dirt or other filler
|
||||
mgvalleys_np_filler_depth (Filler Depth) noise_params 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0
|
||||
|
||||
# Massive caves form here.
|
||||
mgvalleys_np_massive_caves (Massive cave noise) noise_params 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0
|
||||
|
||||
# River noise -- rivers occur close to zero
|
||||
mgvalleys_np_rivers (River Noise) noise_params 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0
|
||||
|
||||
# Base terrain height
|
||||
mgvalleys_np_terrain_height (Terrain Height) noise_params -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0
|
||||
|
||||
# Raises terrain to make valleys around the rivers
|
||||
mgvalleys_np_valley_depth (Valley Depth) noise_params 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0
|
||||
|
||||
# Slope and fill work together to modify the heights
|
||||
mgvalleys_np_inter_valley_fill (Valley Fill) noise_params 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0
|
||||
|
||||
# Amplifies the valleys
|
||||
mgvalleys_np_valley_profile (Valley Profile) noise_params 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0
|
||||
|
||||
# Slope and fill work together to modify the heights
|
||||
mgvalleys_np_inter_valley_slope (Valley Slope) noise_params 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0
|
||||
|
||||
[*Security]
|
||||
|
||||
# Prevent mods from doing insecure things like running shell commands.
|
||||
|
@ -1004,6 +1143,10 @@ secure.enable_security (Enable mod security) bool false
|
|||
# functions even when mod security is on (via request_insecure_environment()).
|
||||
secure.trusted_mods (Trusted mods) string
|
||||
|
||||
# Comma-seperated list of mods that are allowed to access HTTP APIs, which
|
||||
# allow them to upload and download data to/from the internet.
|
||||
secure.http_mods (HTTP Mods) string
|
||||
|
||||
[Client and Server]
|
||||
|
||||
# Name of the player.
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
void main(void)
|
||||
{
|
||||
gl_FragColor = gl_Color;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
uniform mat4 mWorldViewProj;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
|
||||
gl_FrontColor = gl_BackColor = gl_Color;
|
||||
}
|
|
@ -20,6 +20,38 @@ bool normalTexturePresent = false;
|
|||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
#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));
|
||||
|
@ -47,15 +79,29 @@ vec4 get_normal_map(vec2 uv)
|
|||
|
||||
float find_intersection(vec2 dp, vec2 ds)
|
||||
{
|
||||
const float depth_step = 1.0 / 24.0;
|
||||
float depth = 1.0;
|
||||
for (int i = 0 ; i < 24 ; i++) {
|
||||
float best_depth = 0.0;
|
||||
float size = 0.0625;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
depth -= size;
|
||||
float h = texture2D(normalTexture, dp + ds * depth).a;
|
||||
if (h >= depth)
|
||||
if (depth <= h) {
|
||||
best_depth = depth;
|
||||
break;
|
||||
depth -= depth_step;
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
depth = best_depth;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
size *= 0.5;
|
||||
float h = texture2D(normalTexture,dp + ds * depth).a;
|
||||
if (depth <= h) {
|
||||
best_depth = depth;
|
||||
depth += size;
|
||||
} else {
|
||||
depth -= size;
|
||||
}
|
||||
}
|
||||
return best_depth;
|
||||
}
|
||||
|
||||
float find_intersectionRGB(vec2 dp, vec2 ds)
|
||||
|
@ -146,22 +192,26 @@ void main(void)
|
|||
color = base.rgb;
|
||||
#endif
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
|
||||
vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT
|
||||
float alpha = gl_Color.a;
|
||||
vec4 col = vec4(color.rgb, alpha);
|
||||
col *= gl_Color;
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, alpha);
|
||||
col = vec4(col.rgb, alpha);
|
||||
#else
|
||||
vec4 col = vec4(color.rgb, base.a);
|
||||
col *= gl_Color;
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, base.a);
|
||||
col = vec4(col.rgb, base.a);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
gl_FragColor = applyToneMapping(col);
|
||||
#else
|
||||
gl_FragColor = col;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,52 +1,51 @@
|
|||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
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;
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
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;
|
||||
varying float area_enable_parallax;
|
||||
varying float disp;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
|
||||
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;
|
||||
//TODO: make offset depending on view angle and parallax uv displacement
|
||||
//thats for textures that doesnt align vertically, like dirt with grass
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
//TODO: make offset depending on view angle and parallax uv displacement
|
||||
//thats for textures that doesnt align vertically, like dirt with grass
|
||||
//gl_TexCoord[0].y += 0.008;
|
||||
|
||||
//Allow parallax/relief mapping only for certain kind of nodes
|
||||
|
||||
//Allow parallax/relief mapping only for certain kind of nodes
|
||||
//Variable is also used to control area of the effect
|
||||
#if (DRAW_TYPE == NDT_NORMAL || DRAW_TYPE == NDT_LIQUID || DRAW_TYPE == NDT_FLOWINGLIQUID)
|
||||
area_enable_parallax = 1.0;
|
||||
|
@ -55,57 +54,62 @@ void main(void)
|
|||
#endif
|
||||
|
||||
|
||||
float disp_x;
|
||||
float disp_z;
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS)
|
||||
vec4 pos2 = mWorld * gl_Vertex;
|
||||
float tOffset = (pos2.x + pos2.y) * 0.001 + pos2.z * 0.002;
|
||||
disp = (smoothTriangleWave(animationTimer * 31.0 + tOffset) +
|
||||
disp_x = (smoothTriangleWave(animationTimer * 23.0 + tOffset) +
|
||||
smoothTriangleWave(animationTimer * 11.0 + tOffset)) * 0.4;
|
||||
disp_z = (smoothTriangleWave(animationTimer * 31.0 + tOffset) +
|
||||
smoothTriangleWave(animationTimer * 29.0 + tOffset) +
|
||||
smoothTriangleWave(animationTimer * 13.0 + tOffset)) - 0.9;
|
||||
smoothTriangleWave(animationTimer * 13.0 + tOffset)) * 0.5;
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
pos.x += disp * 0.1;
|
||||
pos.y += disp * 0.1;
|
||||
pos.z += disp;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
|
||||
vec4 pos = gl_Vertex;
|
||||
if (gl_TexCoord[0].y < 0.05) {
|
||||
pos.z += disp;
|
||||
}
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#else
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
#endif
|
||||
|
||||
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;
|
||||
pos.x += disp_x;
|
||||
pos.y += disp_z * 0.1;
|
||||
pos.z += disp_z;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
|
||||
vec4 pos = gl_Vertex;
|
||||
if (gl_TexCoord[0].y < 0.05) {
|
||||
pos.x += disp_x;
|
||||
pos.z += disp_z;
|
||||
}
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#else
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
#endif
|
||||
|
||||
vPosition = gl_Position.xyz;
|
||||
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||
|
||||
vPosition = gl_Position.xyz;
|
||||
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||
|
||||
// Don't generate heightmaps when too far from the eye
|
||||
float dist = distance (vec3(0.0, 0.0 ,0.0), vPosition);
|
||||
float dist = distance (vec3(0.0, 0.0, 0.0), vPosition);
|
||||
if (dist > 150.0) {
|
||||
area_enable_parallax = 0.0;
|
||||
}
|
||||
|
||||
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||
|
||||
vec3 normal, tangent, binormal;
|
||||
normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||
|
||||
vec3 normal, tangent, binormal;
|
||||
normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
tangent = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);
|
||||
binormal = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz);
|
||||
|
||||
vec3 v;
|
||||
|
||||
lightVec = sunPosition - worldPosition;
|
||||
|
||||
lightVec = sunPosition - worldPosition;
|
||||
v.x = dot(lightVec, tangent);
|
||||
v.y = dot(lightVec, binormal);
|
||||
v.z = dot(lightVec, normal);
|
||||
|
@ -116,32 +120,32 @@ void main(void)
|
|||
v.y = dot(eyeVec, binormal);
|
||||
v.z = dot(eyeVec, normal);
|
||||
tsEyeVec = normalize (v);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
uniform sampler2D baseTexture;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = gl_TexCoord[0].st;
|
||||
vec4 color = texture2D(baseTexture, uv);
|
||||
color.rgb *= gl_Color.rgb;
|
||||
gl_FragColor = color;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
uniform mat4 mWorldViewProj;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
|
||||
gl_FrontColor = gl_BackColor = gl_Color;
|
||||
}
|
|
@ -22,6 +22,38 @@ bool texSeamless = false;
|
|||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
#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));
|
||||
|
@ -116,22 +148,26 @@ vec4 base = texture2D(baseTexture, uv).rgba;
|
|||
color = base.rgb;
|
||||
#endif
|
||||
|
||||
vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
|
||||
float alpha = gl_Color.a;
|
||||
vec4 col = vec4(color.rgb, alpha);
|
||||
col *= gl_Color;
|
||||
if(fogDistance != 0.0){
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, alpha);
|
||||
col = vec4(col.rgb, alpha);
|
||||
#else
|
||||
vec4 col = vec4(color.rgb, base.a);
|
||||
col *= gl_Color;
|
||||
if(fogDistance != 0.0){
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, base.a);
|
||||
col = vec4(col.rgb, base.a);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
gl_FragColor = applyToneMapping(col);
|
||||
#else
|
||||
gl_FragColor = col;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,144 +1,144 @@
|
|||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
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;
|
||||
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
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;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
|
||||
vPosition = gl_Position.xyz;
|
||||
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
uniform mat4 mWorld;
|
||||
|
||||
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||
|
||||
lightVec = sunPosition - worldPosition;
|
||||
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;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
|
||||
vPosition = gl_Position.xyz;
|
||||
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||
|
||||
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||
|
||||
lightVec = sunPosition - worldPosition;
|
||||
eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||
|
||||
gl_FrontColor = gl_BackColor = gl_Color;
|
||||
}
|
||||
|
||||
gl_FrontColor = gl_BackColor = gl_Color;
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
|
||||
option(ENABLE_LUAJIT "Enable LuaJIT support" TRUE)
|
||||
mark_as_advanced(LUA_LIBRARY LUA_INCLUDE_DIR)
|
||||
set(USE_LUAJIT FALSE)
|
||||
|
||||
if(ENABLE_LUAJIT)
|
||||
find_library(LUA_LIBRARY luajit
|
||||
NAMES luajit-5.1)
|
||||
find_path(LUA_INCLUDE_DIR luajit.h
|
||||
NAMES luajit.h
|
||||
PATH_SUFFIXES luajit-2.0)
|
||||
if(LUA_LIBRARY AND LUA_INCLUDE_DIR)
|
||||
set(USE_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 "${PROJECT_SOURCE_DIR}/lua/src")
|
||||
add_subdirectory(lua)
|
||||
endif()
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# Locate LuaJIT library
|
||||
# This module defines
|
||||
# LUAJIT_FOUND, if false, do not try to link to Lua
|
||||
# LUA_INCLUDE_DIR, where to find lua.h
|
||||
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||
#
|
||||
# This module is similar to FindLua51.cmake except that it finds LuaJit instead.
|
||||
|
||||
FIND_PATH(LUA_INCLUDE_DIR luajit.h
|
||||
HINTS
|
||||
$ENV{LUA_DIR}
|
||||
PATH_SUFFIXES include/luajit-2.0 include/luajit-5_1-2.0 include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUA_LIBRARY
|
||||
NAMES luajit-5.1
|
||||
HINTS
|
||||
$ENV{LUA_DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/luajit.h")
|
||||
FILE(STRINGS "${LUA_INCLUDE_DIR}/luajit.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"LuaJIT .+\"")
|
||||
|
||||
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"LuaJIT ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
||||
UNSET(lua_version_str)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJit
|
||||
REQUIRED_VARS LUA_LIBRARY LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)
|
|
@ -115,7 +115,7 @@ if(CURSES_USE_NCURSESW)
|
|||
get_filename_component(_cursesParentDir "${_cursesLibDir}" PATH)
|
||||
|
||||
find_path(CURSES_INCLUDE_PATH
|
||||
NAMES ncursesw/ncurses.h ncursesw/curses.h
|
||||
NAMES ncursesw/ncurses.h ncursesw/curses.h ncurses.h curses.h
|
||||
HINTS "${_cursesParentDir}/include"
|
||||
)
|
||||
|
||||
|
@ -147,6 +147,21 @@ if(CURSES_USE_NCURSESW)
|
|||
set(CURSES_HAVE_NCURSESW_CURSES_H "CURSES_HAVE_NCURSESW_CURSES_H-NOTFOUND")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT DEFINED CURSES_HAVE_NCURSES_H)
|
||||
if(EXISTS "${CURSES_INCLUDE_PATH}/ncurses.h")
|
||||
set(CURSES_HAVE_NCURSES_H "${CURSES_INCLUDE_PATH}/ncurses.h")
|
||||
else()
|
||||
set(CURSES_HAVE_NCURSES_H "CURSES_HAVE_NCURSES_H-NOTFOUND")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT DEFINED CURSES_HAVE_CURSES_H)
|
||||
if(EXISTS "${CURSES_INCLUDE_PATH}/curses.h")
|
||||
set(CURSES_HAVE_CURSES_H "${CURSES_INCLUDE_PATH}/curses.h")
|
||||
else()
|
||||
set(CURSES_HAVE_CURSES_H "CURSES_HAVE_CURSES_H-NOTFOUND")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}"
|
||||
DOC "Path to libform.so or .lib or .a")
|
||||
|
|
|
@ -1,34 +1,53 @@
|
|||
DOXYFILE_ENCODING = UTF-8
|
||||
|
||||
PROJECT_NAME = "Minetest"
|
||||
# Project properties
|
||||
PROJECT_NAME = @PROJECT_NAME_CAPITALIZED@
|
||||
PROJECT_NUMBER = @VERSION_STRING@
|
||||
PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/misc/minetest.svg
|
||||
|
||||
STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src
|
||||
# Parsing
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
SORT_MEMBERS_CTORS_1ST = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
BUILTIN_STL_SUPPORT = YES
|
||||
PREDEFINED = "USE_SPATIAL=1" \
|
||||
"USE_LEVELDB=1" \
|
||||
"USE_REDIS=1" \
|
||||
"USE_SOUND=1" \
|
||||
"USE_CURL=1" \
|
||||
"USE_FREETYPE=1" \
|
||||
"USE_GETTEXT=1"
|
||||
|
||||
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src/ \
|
||||
# Input
|
||||
RECURSIVE = NO
|
||||
STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src
|
||||
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/doc/main_page.dox \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/ \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/client \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/network \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/util \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/script \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/script/common \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/script/cpp_api \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/script/lua_api
|
||||
RECURSIVE = NO
|
||||
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
GENERATE_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/script/lua_api \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/src/threading
|
||||
|
||||
# Dot graphs
|
||||
HAVE_DOT = @DOXYGEN_DOT_FOUND@
|
||||
CALL_GRAPH = YES
|
||||
CALLER_GRAPH = YES
|
||||
MAX_DOT_GRAPH_DEPTH = 3
|
||||
DOT_MULTI_TARGETS = YES
|
||||
DOT_IMAGE_FORMAT = svg
|
||||
|
||||
# Output
|
||||
GENERATE_LATEX = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
SEARCHENGINE = YES
|
||||
DISABLE_INDEX = YES
|
||||
GENERATE_TREEVIEW = YES
|
||||
HTML_DYNAMIC_SECTIONS = YES
|
||||
HTML_TIMESTAMP = YES
|
||||
|
||||
|
|
305
doc/lua_api.txt
|
@ -1,4 +1,4 @@
|
|||
Minetest Lua Modding API Reference 0.4.13
|
||||
Minetest Lua Modding API Reference 0.4.14
|
||||
=========================================
|
||||
* More information at <http://www.minetest.net/>
|
||||
* Developer Wiki: <http://dev.minetest.net/>
|
||||
|
@ -243,6 +243,7 @@ Example:
|
|||
default_dirt.png^default_grass_side.png
|
||||
|
||||
`default_grass_side.png` is overlayed over `default_dirt.png`.
|
||||
The texture with the lower resolution will be automatically upscaled to the higher resolution texture.
|
||||
|
||||
### Texture grouping
|
||||
Textures can be grouped together by enclosing them in `(` and `)`.
|
||||
|
@ -264,20 +265,27 @@ Example:
|
|||
|
||||
default_cobble.png^[crack:10:1
|
||||
|
||||
#### `[combine:<w>x<h>:<x1>,<y1>=<file1>:<x2>,<y2>=<file2>`
|
||||
#### `[combine:<w>x<h>:<x1>,<y1>=<file1>:<x2>,<y2>=<file2>:...`
|
||||
* `<w>` = width
|
||||
* `<h>` = height
|
||||
* `<x1>`/`<x2>` = x positions
|
||||
* `<y1>`/`<y1>` = y positions
|
||||
* `<file1>`/`<file2>` = textures to combine
|
||||
* `<x>` = x position
|
||||
* `<y>` = y position
|
||||
* `<file>` = texture to combine
|
||||
|
||||
Create a texture of size `<w>` times `<h>` and blit `<file1>` to (`<x1>`,`<y1>`)
|
||||
and blit `<file2>` to (`<x2>`,`<y2>`).
|
||||
Creates a texture of size `<w>` times `<h>` and blits the listed files to their
|
||||
specified coordinates.
|
||||
|
||||
Example:
|
||||
|
||||
[combine:16x32:0,0=default_cobble.png:0,16=default_wood.png
|
||||
|
||||
#### `[resize:<w>x<h>`
|
||||
Resizes the texture to the given dimensions.
|
||||
|
||||
Example:
|
||||
|
||||
default_sandstone.png^[resize:16x16
|
||||
|
||||
#### `[brighten`
|
||||
Brightens the texture.
|
||||
|
||||
|
@ -357,8 +365,13 @@ The mask is applied using binary AND.
|
|||
#### `[colorize:<color>:<ratio>`
|
||||
Colorize the textures with the given color.
|
||||
`<color>` is specified as a `ColorString`.
|
||||
`<ratio>` is an int ranging from 0 to 255, and specifies how much of the
|
||||
color to apply. If ommitted, the alpha will be used.
|
||||
`<ratio>` is an int ranging from 0 to 255 or the word "`alpha`". If
|
||||
it is an int, then it specifies how far to interpolate between the
|
||||
colors where 0 is only the texture color and 255 is only `<color>`. If
|
||||
omitted, the alpha of `<color>` will be used as the ratio. If it is
|
||||
the word "`alpha`", then each texture pixel will contain the RGB of
|
||||
`<color>` and the alpha of `<color>` multiplied by the alpha of the
|
||||
texture pixel.
|
||||
|
||||
Sounds
|
||||
------
|
||||
|
@ -541,9 +554,9 @@ node definition:
|
|||
^ The rotation of the node is stored in param2. Furnaces and chests are
|
||||
rotated this way. Can be made by using minetest.dir_to_facedir().
|
||||
Values range 0 - 23
|
||||
facedir modulo 4 = axisdir
|
||||
facedir / 4 = axis direction:
|
||||
0 = y+ 1 = z+ 2 = z- 3 = x+ 4 = x- 5 = y-
|
||||
facedir's two less significant bits are rotation around the axis
|
||||
facedir modulo 4 = rotation around that axis
|
||||
paramtype2 == "leveled"
|
||||
paramtype2 == "degrotate"
|
||||
^ The rotation of this node is stored in param2. Plants are rotated this way.
|
||||
|
@ -617,6 +630,18 @@ A nodebox is defined as any of:
|
|||
wall_bottom = box,
|
||||
wall_side = box
|
||||
}
|
||||
{
|
||||
-- A node that has optional boxes depending on neighbouring nodes'
|
||||
-- presence and type. See also `connects_to`.
|
||||
type = "connected",
|
||||
fixed = box OR {box1, box2, ...}
|
||||
connect_top = box OR {box1, box2, ...}
|
||||
connect_bottom = box OR {box1, box2, ...}
|
||||
connect_front = box OR {box1, box2, ...}
|
||||
connect_left = box OR {box1, box2, ...}
|
||||
connect_back = box OR {box1, box2, ...}
|
||||
connect_right = box OR {box1, box2, ...}
|
||||
}
|
||||
|
||||
A `box` is defined as:
|
||||
|
||||
|
@ -763,7 +788,7 @@ Creates veins of ore varying in density by according to the intersection of two
|
|||
instances of 3d perlin noise with diffferent seeds, both described by
|
||||
`noise_params`. `random_factor` varies the influence random chance has on
|
||||
placement of an ore inside the vein, which is `1` by default. Note that
|
||||
modifying this parameter may require adjusting `noise_threshhold`.
|
||||
modifying this parameter may require adjusting `noise_threshold`.
|
||||
The parameters `clust_scarcity`, `clust_num_ores`, and `clust_size` are ignored
|
||||
by this ore type. This ore type is difficult to control since it is sensitive
|
||||
to small changes. The following is a decent set of parameters to work from:
|
||||
|
@ -777,7 +802,7 @@ to small changes. The following is a decent set of parameters to work from:
|
|||
persist = 0.5,
|
||||
flags = "eased",
|
||||
},
|
||||
noise_threshhold = 1.6
|
||||
noise_threshold = 1.6
|
||||
|
||||
WARNING: Use this ore type *very* sparingly since it is ~200x more
|
||||
computationally expensive than any other ore.
|
||||
|
@ -928,6 +953,7 @@ Displays a horizontal bar made up of half-images.
|
|||
* `number`: Number of items in the inventory to be displayed.
|
||||
* `item`: Position of item that is selected.
|
||||
* `direction`
|
||||
* `offset`: offset in pixels from position.
|
||||
|
||||
### `waypoint`
|
||||
Displays distance to selected world position.
|
||||
|
@ -1305,10 +1331,12 @@ mentioned in "Nodes". However, it is possible to insert extra data into a
|
|||
node. It is called "node metadata"; See "`NodeMetaRef`".
|
||||
|
||||
Metadata contains two things:
|
||||
|
||||
* A key-value store
|
||||
* An inventory
|
||||
|
||||
Some of the values in the key-value store are handled specially:
|
||||
|
||||
* `formspec`: Defines a right-click inventory menu. See "Formspec".
|
||||
* `infotext`: Text shown on the screen when the node is pointed at
|
||||
|
||||
|
@ -1614,7 +1642,7 @@ examples.
|
|||
* types: `text`, `image`, `color`, `indent`, `tree`
|
||||
* `text`: show cell contents as text
|
||||
* `image`: cell contents are an image index, use column options to define images
|
||||
* `colo`: cell contents are a ColorString and define color of following cell
|
||||
* `color`: cell contents are a ColorString and define color of following cell
|
||||
* `indent`: cell contents are a number and define indentation of following cell
|
||||
* `tree`: same as indent, but user can open and close subtrees (treeview-like)
|
||||
* column options:
|
||||
|
@ -1674,16 +1702,15 @@ or string form, a ColorString (defined above):
|
|||
`colorspec = "green"`
|
||||
|
||||
Spatial Vectors
|
||||
--------------
|
||||
|
||||
* `vector.new([x[, y, z]])`: returns a vector.
|
||||
* `x` is a table or the `x` position.
|
||||
|
||||
---------------
|
||||
* `vector.new(a[, b, c])`: returns a vector:
|
||||
* A copy of `a` if `a` is a vector.
|
||||
* `{x = a, y = b, z = c}`, if all `a, b, c` are defined
|
||||
* `vector.direction(p1, p2)`: returns a vector
|
||||
* `vector.distance(p1, p2)`: returns a number
|
||||
* `vector.length(v)`: returns a number
|
||||
* `vector.normalize(v)`: returns a vector
|
||||
* `vector.round(v)`: returns a vector
|
||||
* `vector.round(v)`: returns a vector, each dimension rounded to floor
|
||||
* `vector.apply(v, func)`: returns a vector
|
||||
* `vector.equals(v1, v2)`: returns a boolean
|
||||
|
||||
|
@ -1695,7 +1722,7 @@ For the following functions `x` can be either a vector or a number:
|
|||
* `vector.divide(v, x)`: returns a scaled vector or Schur quotient
|
||||
|
||||
Helper functions
|
||||
-----------------
|
||||
----------------
|
||||
* `dump2(obj, name="_", dumped={})`
|
||||
* Return object serialized as a string, handles reference loops
|
||||
* `dump(obj, dumped={})`
|
||||
|
@ -1713,8 +1740,9 @@ Helper functions
|
|||
* e.g. `string:split("a,b", ",") == {"a","b"}`
|
||||
* `string:trim()`
|
||||
* e.g. `string.trim("\n \t\tfoo bar\t ") == "foo bar"`
|
||||
* `minetest.pos_to_string({x=X,y=Y,z=Z})`: returns `"(X,Y,Z)"`
|
||||
* `minetest.pos_to_string({x=X,y=Y,z=Z}, decimal_places))`: returns `"(X,Y,Z)"`
|
||||
* Convert position to a printable string
|
||||
Optional: 'decimal_places' will round the x, y and z of the pos to the given decimal place.
|
||||
* `minetest.string_to_pos(string)`: returns a position
|
||||
* Same but in reverse. Returns `nil` if the string can't be parsed to a position.
|
||||
* `minetest.string_to_area("(X1, Y1, Z1) (X2, Y2, Z2)")`: returns two positions
|
||||
|
@ -1724,7 +1752,7 @@ Helper functions
|
|||
* `minetest.is_yes(arg)`
|
||||
* returns whether `arg` can be interpreted as yes
|
||||
* `minetest.get_us_time()`
|
||||
* returns time with microsecond precision
|
||||
* returns time with microsecond precision. May not return wall time.
|
||||
* `table.copy(table)`: returns a table
|
||||
* returns a deep copy of `table`
|
||||
|
||||
|
@ -1790,6 +1818,7 @@ Call these functions only at load time!
|
|||
|
||||
* `minetest.register_entity(name, prototype table)`
|
||||
* `minetest.register_abm(abm definition)`
|
||||
* `minetest.register_lbm(lbm definition)`
|
||||
* `minetest.register_node(name, node definition)`
|
||||
* `minetest.register_tool(name, item definition)`
|
||||
* `minetest.register_craftitem(name, item definition)`
|
||||
|
@ -1850,6 +1879,7 @@ Call these functions only at load time!
|
|||
* `modifier`: when true, the function should return the actual hp_change.
|
||||
Note: modifiers only get a temporary hp_change that can be modified by later modifiers.
|
||||
modifiers can return true as a second argument to stop the execution of further functions.
|
||||
Non-modifiers receive the final hp change calculated by the modifiers.
|
||||
* `minetest.register_on_respawnplayer(func(ObjectRef))`
|
||||
* Called when player is to be respawned
|
||||
* Called _before_ repositioning of player occurs
|
||||
|
@ -1901,6 +1931,7 @@ Call these functions only at load time!
|
|||
* `minetest.register_privilege(name, definition)`
|
||||
* `definition`: `"description text"`
|
||||
* `definition`: `{ description = "description text", give_to_singleplayer = boolean, -- default: true }`
|
||||
* To allow players with basic_privs to grant, see basic_privs minetest.conf setting.
|
||||
* `minetest.register_authentication_handler(handler)`
|
||||
* See `minetest.builtin_auth_handler` in `builtin.lua` for reference
|
||||
|
||||
|
@ -1921,7 +1952,11 @@ Call these functions only at load time!
|
|||
* Should be called by the authentication handler if privileges changes.
|
||||
* To report everybody, set `name=nil`.
|
||||
* `minetest.get_password_hash(name, raw_password)`
|
||||
* Convert a name-password pair to a password hash that Minetest can use
|
||||
* Convert a name-password pair to a password hash that Minetest can use.
|
||||
* The returned value alone is not a good basis for password checks based
|
||||
* on comparing the password hash in the database with the password hash
|
||||
* from the function, with an externally provided password, as the hash
|
||||
* in the db might use the new SRP verifier format.
|
||||
* `minetest.string_to_privs(str)`: returns `{priv1=true,...}`
|
||||
* `minetest.privs_to_string(privs)`: returns `"priv1,priv2,..."`
|
||||
* Convert between two privilege representations
|
||||
|
@ -1952,9 +1987,11 @@ and `minetest.auth_reload` call the authetification handler.
|
|||
* `minetest.remove_node(pos)`
|
||||
* Equivalent to `set_node(pos, "air")`
|
||||
* `minetest.get_node(pos)`
|
||||
* Returns `{name="ignore", ...}` for unloaded area
|
||||
* Returns the node at the given position as table in the format
|
||||
`{name="node_name", param1=0, param2=0}`, returns `{name="ignore", param1=0, param2=0}`
|
||||
for unloaded areas.
|
||||
* `minetest.get_node_or_nil(pos)`
|
||||
* Returns `nil` for unloaded area
|
||||
* Same as `get_node` but returns `nil` for unloaded areas.
|
||||
* `minetest.get_node_light(pos, timeofday)`
|
||||
* Gets the light value at the given position. Note that the light value
|
||||
"inside" the node at the given position is returned, so you usually want
|
||||
|
@ -1988,6 +2025,8 @@ and `minetest.auth_reload` call the authetification handler.
|
|||
* `val` is between `0` and `1`; `0` for midnight, `0.5` for midday
|
||||
* `minetest.get_timeofday()`
|
||||
* `minetest.get_gametime()`: returns the time, in seconds, since the world was created
|
||||
* `minetest.get_day_count()`: returns number days elapsed since world was created,
|
||||
* accounting for time changes.
|
||||
* `minetest.find_node_near(pos, radius, nodenames)`: returns pos or `nil`
|
||||
* `radius`: using a maximum metric
|
||||
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
||||
|
@ -2037,8 +2076,12 @@ and `minetest.auth_reload` call the authetification handler.
|
|||
* `minetest.generate_decorations(vm, pos1, pos2)`
|
||||
* Generate all registered decorations within the VoxelManip `vm` and in the area from `pos1` to `pos2`.
|
||||
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
|
||||
* `minetest.clear_objects()`
|
||||
* clear all objects in the environments
|
||||
* `minetest.clear_objects([options])`
|
||||
* Clear all objects in the environment
|
||||
* Takes an optional table as an argument with the field `mode`.
|
||||
* mode = `"full"`: Load and go through every mapblock, clearing objects (default).
|
||||
* mode = `"quick"`: Clear objects immediately in loaded mapblocks;
|
||||
clear objects in unloaded mapblocks only when the mapblocks are next activated.
|
||||
* `minetest.emerge_area(pos1, pos2, [callback], [param])`
|
||||
* Queue all blocks in the area from `pos1` to `pos2`, inclusive, to be asynchronously
|
||||
* fetched from memory, loaded from disk, or if inexistent, generates them.
|
||||
|
@ -2071,7 +2114,9 @@ and `minetest.auth_reload` call the authetification handler.
|
|||
* `max_drop`: maximum height difference to consider droppable
|
||||
* `algorithm`: One of `"A*_noprefetch"` (default), `"A*"`, `"Dijkstra"`
|
||||
* `minetest.spawn_tree (pos, {treedef})`
|
||||
* spawns L-System tree at given `pos` with definition in `treedef` table
|
||||
* spawns L-system tree at given `pos` with definition in `treedef` table
|
||||
* Warning: L-system generation currently creates lighting bugs in the form of mapblock-sized shadows.
|
||||
Often these bugs appear as subtle shadows in water.
|
||||
* `minetest.transforming_liquid_add(pos)`
|
||||
* add node to liquid update queue
|
||||
* `minetest.get_node_max_level(pos)`
|
||||
|
@ -2140,6 +2185,8 @@ and `minetest.auth_reload` call the authetification handler.
|
|||
* Convert a facedir back into a vector aimed directly out the "back" of a node
|
||||
* `minetest.dir_to_wallmounted(dir)`
|
||||
* Convert a vector to a wallmounted value, used for `paramtype2="wallmounted"`
|
||||
* `minetest.wallmounted_to_dir(wallmounted)`
|
||||
* Convert a wallmounted value back into a vector aimed directly out the "back" of a node
|
||||
* `minetest.get_node_drops(nodename, toolname)`
|
||||
* Returns list of item names.
|
||||
* **Note**: This will be removed or modified in a future version.
|
||||
|
@ -2233,7 +2280,7 @@ These functions return the leftover itemstack.
|
|||
|
||||
### Timing
|
||||
* `minetest.after(time, func, ...)`
|
||||
* Call the function `func` after `time` seconds
|
||||
* Call the function `func` after `time` seconds, may be fractional
|
||||
* Optional: Variable number of arguments that are passed to `func`
|
||||
|
||||
### Server
|
||||
|
@ -2315,6 +2362,26 @@ These functions return the leftover itemstack.
|
|||
* If `lua_num_indent_spaces` is a nonzero number and `format` is "lua", the Lua code generated
|
||||
* will use that number of spaces as indentation instead of a tab character.
|
||||
|
||||
### HTTP Requests:
|
||||
* `minetest.request_http_api()`:
|
||||
* returns `HTTPApiTable` containing http functions if the calling mod has been granted
|
||||
access by being listed in the `secure.http_mods` or `secure.trusted_mods` setting,
|
||||
otherwise returns `nil`.
|
||||
* The returned table contains the functions `fetch`, `fetch_async` and `fetch_async_get`
|
||||
described below.
|
||||
* Only works at init time and must be called from the mod's main scope (not from a function).
|
||||
* Function only exists if minetest server was built with cURL support.
|
||||
* **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED TABLE, STORE IT IN
|
||||
A LOCAL VARIABLE!**
|
||||
* `HTTPApiTable.fetch(HTTPRequest req, callback)`
|
||||
* Performs given request asynchronously and calls callback upon completion
|
||||
* callback: `function(HTTPRequestResult res)`
|
||||
* Use this HTTP function if you are unsure, the others are for advanced use.
|
||||
* `HTTPApiTable.fetch_async(HTTPRequest req)`: returns handle
|
||||
* Performs given request asynchronously and returns handle for `minetest.http_fetch_async_get`
|
||||
* `HTTPApiTable.fetch_async_get(handle)`: returns HTTPRequestResult
|
||||
* Return response data for given asynchronous HTTP request
|
||||
|
||||
### Misc.
|
||||
* `minetest.get_connected_players()`: returns list of `ObjectRefs`
|
||||
* `minetest.hash_node_position({x=,y=,z=})`: returns an 48-bit integer
|
||||
|
@ -2422,7 +2489,7 @@ These functions return the leftover itemstack.
|
|||
* `minetest.request_insecure_environment()`: returns an environment containing
|
||||
insecure functions if the calling mod has been listed as trusted in the
|
||||
`secure.trusted_mods` setting or security is disabled, otherwise returns `nil`.
|
||||
* Only works at init time.
|
||||
* Only works at init time and must be called from the mod's main scope (not from a function).
|
||||
* **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED ENVIRONMENT, STORE IT IN
|
||||
A LOCAL VARIABLE!**
|
||||
|
||||
|
@ -2453,6 +2520,8 @@ These functions return the leftover itemstack.
|
|||
* Map of Lua entities, indexed by active object id
|
||||
* `minetest.registered_ores`
|
||||
* List of registered ore definitions.
|
||||
* `minetest.registered_biomes`
|
||||
* List of registered biome definitions.
|
||||
* `minetest.registered_decorations`
|
||||
* List of registered decoration definitions.
|
||||
|
||||
|
@ -2538,6 +2607,19 @@ This is basically a reference to a C++ `ServerActiveObject`
|
|||
* `set_properties(object property table)`
|
||||
* `get_properties()`: returns object property table
|
||||
* `is_player()`: returns true for players, false otherwise
|
||||
* `get_nametag_attributes()`
|
||||
* returns a table with the attributes of the nametag of an object
|
||||
* {
|
||||
color = {a=0..255, r=0..255, g=0..255, b=0..255},
|
||||
text = "",
|
||||
}
|
||||
* `set_nametag_attributes(attributes)`
|
||||
* sets the attributes of the nametag of an object
|
||||
* `attributes`:
|
||||
{
|
||||
color = ColorSpec,
|
||||
text = "My Nametag",
|
||||
}
|
||||
|
||||
##### LuaEntitySAO-only (no-op for other objects)
|
||||
* `setvelocity({x=num, y=num, z=num})`
|
||||
|
@ -2617,8 +2699,6 @@ This is basically a reference to a C++ `ServerActiveObject`
|
|||
* `"regular"`: Uses 0 textures, `bgcolor` ignored
|
||||
* `"skybox"`: Uses 6 textures, `bgcolor` used
|
||||
* `"plain"`: Uses 0 textures, `bgcolor` used
|
||||
* **Note**: currently does not work directly in `on_joinplayer`; use
|
||||
`minetest.after(0)` in there.
|
||||
* `get_sky()`: returns bgcolor, type and a table with the textures
|
||||
* `override_day_night_ratio(ratio or nil)`
|
||||
* `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount
|
||||
|
@ -2638,17 +2718,6 @@ This is basically a reference to a C++ `ServerActiveObject`
|
|||
* in first person view
|
||||
* in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`)
|
||||
* `get_eye_offset()`: returns offset_first and offset_third
|
||||
* `get_nametag_attributes()`
|
||||
* returns a table with the attributes of the nametag of the player
|
||||
* {
|
||||
color = {a=0..255, r=0..255, g=0..255, b=0..255},
|
||||
}
|
||||
* `set_nametag_attributes(attributes)`
|
||||
* sets the attributes of the nametag of the player
|
||||
* `attributes`:
|
||||
{
|
||||
color = ColorSpec,
|
||||
}
|
||||
|
||||
### `InvRef`
|
||||
An `InvRef` is a reference to an inventory.
|
||||
|
@ -2689,8 +2758,7 @@ If you chose the parameter-less constructor, a fast implementation will be autom
|
|||
* `get_area(id, include_borders, include_data)`: returns the area with the id `id`. (optional) Boolean values `include_borders` and `include_data` control what's copied.
|
||||
* `get_areas_for_pos(pos, include_borders, include_data)`: returns all areas that contain the position `pos`. (optional) Boolean values `include_borders` and `include_data` control what's copied.
|
||||
* `get_areas_in_area(edge1, edge2, accept_overlap, include_borders, include_data)`: returns all areas that contain all nodes inside the area specified by `edge1` and `edge2` (inclusive). If `accept_overlap` is true, also areas are returned that have nodes in common with the specified area. (optional) Boolean values `include_borders` and `include_data` control what's copied.
|
||||
* `insert_area(edge1, edge2, data)`: inserts an area into the store. Returns the id if successful, nil otherwise. The (inclusive) positions `edge1` and `edge2` describe the area, `data`
|
||||
is a string stored with the area.
|
||||
* `insert_area(edge1, edge2, data, [id])`: inserts an area into the store. Returns the new area's ID, or nil if the insertion failed. The (inclusive) positions `edge1` and `edge2` describe the area. `data` is a string stored with the area. If passed, `id` will be used as the internal area ID, it must be a unique number between 0 and 2^32-2. If you use the `id` parameter you must always use it, or insertions are likely to fail due to conflicts.
|
||||
* `reserve(count)`: reserves resources for at most `count` many contained areas. Only needed for efficiency, and only some implementations profit.
|
||||
* `remove_area(id)`: removes the area with the given id from the store, returns success.
|
||||
* `set_cache_params(params)`: sets params for the included prefiltering cache. Calling invalidates the cache, so that its elements have to be newly generated.
|
||||
|
@ -2700,6 +2768,10 @@ is a string stored with the area.
|
|||
block_radius = number, -- the radius (in nodes) of the areas the cache generates prefiltered lists for, minimum 16, default 64
|
||||
limit = number, -- the cache's size, minimum 20, default 1000
|
||||
}
|
||||
* `to_string()`: Experimental. Returns area store serialized as a (binary) string.
|
||||
* `to_file(filename)`: Experimental. Like `to_string()`, but writes the data to a file.
|
||||
* `from_string(str)`: Experimental. Deserializes string and loads it into the AreaStore. Returns success and, optionally, an error message.
|
||||
* `from_file(filename)`: Experimental. Like `from_string()`, but reads the data from a file.
|
||||
|
||||
### `ItemStack`
|
||||
An `ItemStack` is a stack of items.
|
||||
|
@ -2765,6 +2837,15 @@ It can be created via `PcgRandom(seed)` or `PcgRandom(seed, sequence)`.
|
|||
* This is only a rough approximation of a normal distribution with mean=(max-min)/2 and variance=1
|
||||
* Increasing num_trials improves accuracy of the approximation
|
||||
|
||||
### `SecureRandom`
|
||||
Interface for the operating system's crypto-secure PRNG.
|
||||
|
||||
It can be created via `SecureRandom()`. The constructor returns nil if a secure random device cannot be
|
||||
be found on the system.
|
||||
|
||||
#### Methods
|
||||
* `next_bytes([count])`: return next `count` (default 1, capped at 2048) many random bytes, as a string.
|
||||
|
||||
### `PerlinNoise`
|
||||
A perlin noise generator.
|
||||
It can be created via `PerlinNoise(seed, octaves, persistence, scale)`
|
||||
|
@ -2925,6 +3006,7 @@ core.CONTENT_IGNORE (ID for "ignore" nodes)
|
|||
Inside of `on_generated()` callbacks, it is possible to retrieve the same VoxelManip object used by the
|
||||
core's Map Generator (commonly abbreviated Mapgen). Most of the rules previously described still apply
|
||||
but with a few differences:
|
||||
|
||||
* The Mapgen VoxelManip object is retrieved using: `minetest.get_mapgen_object("voxelmanip")`
|
||||
* This VoxelManip object already has the region of map just generated loaded into it; it's not necessary
|
||||
to call `VoxelManip:read_from_map()` before using a Mapgen VoxelManip.
|
||||
|
@ -2983,7 +3065,7 @@ will place the schematic inside of the VoxelManip.
|
|||
* `update_map()`: Update map after writing chunk back to map.
|
||||
* To be used only by `VoxelManip` objects created by the mod itself;
|
||||
not a `VoxelManip` that was retrieved from `minetest.get_mapgen_object`
|
||||
* `set_lighting(light, p1, p2)`: Set the lighting within the `VoxelManip` to a uniform value
|
||||
* `set_lighting(light, [p1, p2])`: Set the lighting within the `VoxelManip` to a uniform value
|
||||
* `light` is a table, `{day=<0...15>, night=<0...15>}`
|
||||
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
||||
* (`p1`, `p2`) is the area in which lighting is set;
|
||||
|
@ -2997,10 +3079,12 @@ will place the schematic inside of the VoxelManip.
|
|||
* expects lighting data in the same format that `get_light_data()` returns
|
||||
* `get_param2_data()`: Gets the raw `param2` data read into the `VoxelManip` object
|
||||
* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in the `VoxelManip`
|
||||
* `calc_lighting(p1, p2)`: Calculate lighting within the `VoxelManip`
|
||||
* `calc_lighting([p1, p2], [propagate_shadow])`: Calculate lighting within the `VoxelManip`
|
||||
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
||||
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area
|
||||
if left out
|
||||
if left out or nil
|
||||
* `propagate_shadow` is an optional boolean deciding whether shadows in a generated
|
||||
mapchunk above are propagated down into the mapchunk; defaults to `true` if left out
|
||||
* `update_liquids()`: Update liquid flow
|
||||
* `was_modified()`: Returns `true` or `false` if the data in the voxel manipulator
|
||||
had been modified since the last read from map, due to a call to
|
||||
|
@ -3121,6 +3205,9 @@ Registered entities
|
|||
|
||||
L-system trees
|
||||
--------------
|
||||
**Warning**
|
||||
L-system generation currently creates lighting bugs in the form of mapblock-sized shadows.
|
||||
Often these bugs appear as subtle shadows in water.
|
||||
|
||||
### Tree definition
|
||||
|
||||
|
@ -3213,7 +3300,12 @@ Definition tables
|
|||
stepheight = 0,
|
||||
automatic_face_movement_dir = 0.0,
|
||||
-- ^ automatically set yaw to movement direction; offset in degrees; false to disable
|
||||
automatic_face_movement_max_rotation_per_sec = -1,
|
||||
-- ^ limit automatic rotation to this value in degrees per second. values < 0 no limit
|
||||
backface_culling = true, -- false to disable backface_culling for model
|
||||
nametag = "", -- by default empty, for players their name is shown if empty
|
||||
nametag_color = <color>, -- sets color of nametag as ColorSpec
|
||||
infotext = "", -- by default empty, text to be shown when pointed at object
|
||||
}
|
||||
|
||||
### Entity definition (`register_entity`)
|
||||
|
@ -3251,6 +3343,21 @@ Definition tables
|
|||
action = func(pos, node, active_object_count, active_object_count_wider),
|
||||
}
|
||||
|
||||
### LBM (LoadingBlockModifier) definition (`register_lbm`)
|
||||
|
||||
{
|
||||
name = "modname:replace_legacy_door",
|
||||
nodenames = {"default:lava_source"},
|
||||
-- ^ List of node names to trigger the LBM on.
|
||||
-- Also non-registered nodes will work.
|
||||
-- Groups (as of group:groupname) will work as well.
|
||||
run_at_every_load = false,
|
||||
-- ^ Whether to run the LBM's action every time a block gets loaded,
|
||||
-- and not just for blocks that were saved last time before LBMs were
|
||||
-- introduced to the world.
|
||||
action = func(pos, node),
|
||||
}
|
||||
|
||||
### Item definition (`register_node`, `register_craftitem`, `register_tool`)
|
||||
|
||||
{
|
||||
|
@ -3294,6 +3401,11 @@ Definition tables
|
|||
--[[
|
||||
^ Shall place item and return the leftover itemstack
|
||||
^ default: minetest.item_place ]]
|
||||
on_secondary_use = func(itemstack, user, pointed_thing),
|
||||
--[[
|
||||
^ Same as on_place but called when pointing at nothing.
|
||||
^ pointed_thing : always { type = "nothing" }
|
||||
]]
|
||||
on_drop = func(itemstack, dropper, pos),
|
||||
--[[
|
||||
^ Shall drop item and return the leftover itemstack
|
||||
|
@ -3325,7 +3437,7 @@ Definition tables
|
|||
* `{name="image.png", animation={Tile Animation definition}}`
|
||||
* `{name="image.png", backface_culling=bool, tileable_vertical=bool,
|
||||
tileable_horizontal=bool}`
|
||||
* backface culling only supported in special tiles.
|
||||
* backface culling enabled by default for most nodes
|
||||
* tileable flags are info for shaders, how they should treat texture
|
||||
when displacement mapping is used
|
||||
Directions are from the point of view of the tile texture,
|
||||
|
@ -3367,6 +3479,7 @@ Definition tables
|
|||
diggable = true, -- If false, can never be dug
|
||||
climbable = false, -- If true, can be climbed on (ladder)
|
||||
buildable_to = false, -- If true, placed nodes can replace this node
|
||||
floodable = false, -- If true, liquids flow into and replace this node
|
||||
liquidtype = "none", -- "none"/"source"/"flowing"
|
||||
liquid_alternative_flowing = "", -- Flowing version of source liquid
|
||||
liquid_alternative_source = "", -- Source version of flowing liquid
|
||||
|
@ -3380,6 +3493,12 @@ Definition tables
|
|||
light_source = 0, -- Amount of light emitted by node
|
||||
damage_per_second = 0, -- If player is inside node, this damage is caused
|
||||
node_box = {type="regular"}, -- See "Node boxes"
|
||||
connects_to = nodenames, --[[
|
||||
* Used for nodebox nodes with the type == "connected"
|
||||
* Specifies to what neighboring nodes connections will be drawn
|
||||
* e.g. `{"group:fence", "default:wood"}` or `"default:stone"` ]]
|
||||
connect_sides = { "top", "bottom", "front", "left", "back", "right" }, --[[
|
||||
^ Tells connected nodebox nodes to connect only to these sides of this node. ]]
|
||||
mesh = "model",
|
||||
selection_box = {type="regular"}, -- See "Node boxes" --[[
|
||||
^ If drawtype "nodebox" is used and selection_box is nil, then node_box is used. ]]
|
||||
|
@ -3554,7 +3673,7 @@ Definition tables
|
|||
y_max = 64,
|
||||
flags = "",
|
||||
-- ^ Attributes for this ore generation
|
||||
noise_threshhold = 0.5,
|
||||
noise_threshold = 0.5,
|
||||
-- ^ If noise is above this threshold, ore is placed. Not needed for a uniform distribution
|
||||
noise_params = {offset=0, scale=1, spread={x=100, y=100, z=100}, seed=23, octaves=3, persist=0.70}
|
||||
-- ^ NoiseParams structure describing the perlin noise used for ore distribution.
|
||||
|
@ -3569,6 +3688,51 @@ Definition tables
|
|||
-- ^ Can be a list of (or a single) biome names, IDs, or definitions.
|
||||
}
|
||||
|
||||
### Biome definition (`register_biome`)
|
||||
|
||||
{
|
||||
name = "tundra",
|
||||
node_dust = "default:snow",
|
||||
-- ^ Node dropped onto upper surface after all else is generated.
|
||||
node_top = "default:dirt_with_snow",
|
||||
depth_top = 1,
|
||||
-- ^ Node forming surface layer of biome and thickness of this layer.
|
||||
node_filler = "default:permafrost",
|
||||
depth_filler = 3,
|
||||
-- ^ Node forming lower layer of biome and thickness of this layer.
|
||||
node_stone = "default:bluestone",
|
||||
-- ^ Node that replaces all stone nodes between roughly y_min and y_max.
|
||||
node_water_top = "default:ice",
|
||||
depth_water_top = 10,
|
||||
-- ^ Node forming a surface layer in seawater with the defined thickness.
|
||||
node_water = "",
|
||||
-- ^ Node that replaces all seawater nodes not in the defined surface layer.
|
||||
node_river_water = "default:ice",
|
||||
-- ^ Node that replaces river water in mapgens that use default:river_water.
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
-- ^ Lower and upper limits for biome.
|
||||
-- ^ Because biome is not recalculated for every node in a node column
|
||||
-- ^ some biome materials can exceed their limits, especially stone.
|
||||
-- ^ For each node column in a mapchunk, biome is only recalculated at column
|
||||
-- ^ top and at each of these surfaces:
|
||||
-- ^ Ground below air, water below air, ground below water.
|
||||
-- ^ The selected biome then stays in effect for all nodes below until
|
||||
-- ^ column base or the next biome recalculation.
|
||||
heat_point = 0,
|
||||
humidity_point = 50,
|
||||
-- ^ Characteristic average temperature and humidity for the biome.
|
||||
-- ^ These values create 'biome points' on a voronoi diagram that has heat
|
||||
-- ^ and humidity as axes. The resulting voronoi cells determine which
|
||||
-- ^ heat/humidity points belong to which biome, and therefore determine
|
||||
-- ^ the area and location of each biome in the world.
|
||||
-- ^ The biome points need to be carefully and evenly spaced on the voronoi
|
||||
-- ^ diagram to result in roughly equal size biomes.
|
||||
-- ^ Heat and humidity have average values of 50, vary mostly between
|
||||
-- ^ 0 and 100 but also often exceed these values.
|
||||
-- ^ Heat is not in degrees celcius, both values are abstract.
|
||||
}
|
||||
|
||||
### Decoration definition (`register_decoration`)
|
||||
|
||||
{
|
||||
|
@ -3593,11 +3757,12 @@ Definition tables
|
|||
-- ^ Minimum and maximum `y` positions these decorations can be generated at.
|
||||
-- ^ This parameter refers to the `y` position of the decoration base, so
|
||||
-- the actual maximum height would be `height_max + size.Y`.
|
||||
flags = "liquid_surface",
|
||||
flags = "liquid_surface, force_placement",
|
||||
-- ^ Flags for all decoration types.
|
||||
-- ^ "liquid_surface": Instead of placement on the highest solid surface
|
||||
-- ^ in a mapchunk column, placement is on the highest liquid surface.
|
||||
-- ^ Placement is disabled if solid nodes are found above the liquid surface.
|
||||
-- ^ "force_placement": Nodes other than "air" and "ignore" are replaced by the decoration.
|
||||
|
||||
----- Simple-type parameters
|
||||
decoration = "default:grass",
|
||||
|
@ -3641,7 +3806,7 @@ Definition tables
|
|||
},
|
||||
-- ^ See 'Schematic specifier' for details.
|
||||
replacements = {["oldname"] = "convert_to", ...},
|
||||
flags = "place_center_x, place_center_y, place_center_z, force_placement",
|
||||
flags = "place_center_x, place_center_y, place_center_z",
|
||||
-- ^ Flags for schematic decorations. See 'Schematic attributes'.
|
||||
rotation = "90" -- rotate schematic 90 degrees on placement
|
||||
-- ^ Rotation can be "0", "90", "180", "270", or "random".
|
||||
|
@ -3752,3 +3917,37 @@ Definition tables
|
|||
playername = "singleplayer"
|
||||
-- ^ Playername is optional, if specified spawns particle only on the player's client
|
||||
}
|
||||
|
||||
### `HTTPRequest` definition (`http_fetch`, `http_fetch_async`)
|
||||
|
||||
{
|
||||
url = "http://example.org",
|
||||
timeout = 10,
|
||||
-- ^ Timeout for connection in seconds. Default is 3 seconds.
|
||||
post_data = "Raw POST request data string" OR { field1 = "data1", field2 = "data2" },
|
||||
-- ^ Optional, if specified a POST request with post_data is performed.
|
||||
-- ^ Accepts both a string and a table. If a table is specified, encodes table
|
||||
-- ^ as x-www-form-urlencoded key-value pairs.
|
||||
-- ^ If post_data ist not specified, a GET request is performed instead.
|
||||
user_agent = "ExampleUserAgent",
|
||||
-- ^ Optional, if specified replaces the default minetest user agent with given string
|
||||
extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" },
|
||||
-- ^ Optional, if specified adds additional headers to the HTTP request. You must make sure
|
||||
-- ^ that the header strings follow HTTP specification ("Key: Value").
|
||||
multipart = boolean
|
||||
-- ^ Optional, if true performs a multipart HTTP request. Default is false.
|
||||
}
|
||||
|
||||
### `HTTPRequestResult` definition (`http_fetch` callback, `http_fetch_async_get`)
|
||||
|
||||
{
|
||||
completed = true,
|
||||
-- ^ If true, the request has finished (either succeeded, failed or timed out)
|
||||
succeeded = true,
|
||||
-- ^ If true, the request was succesful
|
||||
timeout = false,
|
||||
-- ^ If true, the request timed out
|
||||
code = 200,
|
||||
-- ^ HTTP status code
|
||||
data = "response"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/** @mainpage The Minetest engine internal documentation
|
||||
|
||||
Welcome to the Minetest engine Doxygen documentation site!\n
|
||||
This page documents the internal structure of the Minetest engine's C++ code.\n
|
||||
Use the tree view at the left to navigate.
|
||||
|
||||
*/
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
Minetest Lua Mainmenu API Reference 0.4.13
|
||||
Minetest Lua Mainmenu API Reference 0.4.14
|
||||
========================================
|
||||
|
||||
Introduction
|
||||
|
|
|
@ -316,7 +316,7 @@ if map format version >= 23:
|
|||
u8[key_len] key
|
||||
u32 val_len
|
||||
u8[val_len] value
|
||||
serialized inventory
|
||||
serialized inventory
|
||||
|
||||
- Node timers
|
||||
if map format version == 23:
|
||||
|
|
|
@ -36,7 +36,7 @@ minetest.register_ore({
|
|||
clust_size = 7,
|
||||
y_min = -15,
|
||||
y_max = 0,
|
||||
noise_threshhold = 0,
|
||||
noise_threshold = 0,
|
||||
noise_params = {
|
||||
offset=0.35,
|
||||
scale=0.2,
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
# Key for toggling the camrea update. Only used for development
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
# type: key
|
||||
# keymap_toggle_update_camera =
|
||||
# keymap_toggle_update_camera =
|
||||
|
||||
# Key for toggling the display of debug info.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
|
@ -214,12 +214,12 @@
|
|||
# type: key
|
||||
# keymap_camera_mode = KEY_F7
|
||||
|
||||
# Key for increasing the viewing range. Modifies the minimum viewing range.
|
||||
# Key for increasing the viewing range.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
# type: key
|
||||
# keymap_increase_viewing_range_min = +
|
||||
|
||||
# Key for decreasing the viewing range. Modifies the minimum viewing range.
|
||||
# Key for decreasing the viewing range.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
# type: key
|
||||
# keymap_decrease_viewing_range_min = -
|
||||
|
@ -235,17 +235,28 @@
|
|||
# Leave this blank to start a local server.
|
||||
# Note that the address field in the main menu overrides this setting.
|
||||
# type: string
|
||||
# address =
|
||||
# address =
|
||||
|
||||
# Port to connect to (UDP).
|
||||
# Note that the port field in the main menu overrides this setting.
|
||||
# type: int min: 1 max: 65535
|
||||
# remote_port = 30000
|
||||
|
||||
# Whether to support older servers before protocol version 25.
|
||||
# Enable if you want to connect to 0.4.12 servers and before.
|
||||
# Servers starting with 0.4.13 will work, 0.4.12-dev servers may work.
|
||||
# Disabling this option will protect your password better.
|
||||
# type: bool
|
||||
# send_pre_v25_init = true
|
||||
|
||||
# Save the map received by the client on disk.
|
||||
# type: bool
|
||||
# enable_local_map_saving = false
|
||||
|
||||
# Show entity selection boxes
|
||||
# type: bool
|
||||
# show_entity_selectionbox = true
|
||||
|
||||
# Enable usage of remote media server (if provided by server).
|
||||
# Remote servers offer a significantly faster way to download media (e.g. textures)
|
||||
# when connecting to the server.
|
||||
|
@ -266,16 +277,14 @@
|
|||
|
||||
#### Basic
|
||||
|
||||
# Enable VBO
|
||||
# type: bool
|
||||
# enable_vbo = true
|
||||
|
||||
# Whether to fog out the end of the visible area.
|
||||
# type: bool
|
||||
# enable_fog = true
|
||||
|
||||
# Enable a bit lower water surface, so it doesn't "fill" the node completely.
|
||||
# Note that this is not quite optimized and that smooth lighting on the
|
||||
# water surface doesn't work with this.
|
||||
# type: bool
|
||||
# new_style_water = false
|
||||
|
||||
# Leaves style:
|
||||
# - Fancy: all faces visible
|
||||
# - Simple: only outer faces, if defined special_tiles are used
|
||||
|
@ -300,6 +309,10 @@
|
|||
# type: bool
|
||||
# enable_3d_clouds = true
|
||||
|
||||
# Method used to highlight selected object.
|
||||
# type: enum values: box, halo
|
||||
# node_highlighting = box
|
||||
|
||||
#### Filtering
|
||||
|
||||
# Use mip mapping to scale textures. May slightly increase performance.
|
||||
|
@ -335,12 +348,6 @@
|
|||
# type: int
|
||||
# texture_min_size = 64
|
||||
|
||||
# Pre-generate all item visuals used in the inventory.
|
||||
# This increases startup time, but runs smoother in-game.
|
||||
# The generated textures can easily exceed your VRAM, causing artifacts in the inventory.
|
||||
# type: bool
|
||||
# preload_item_visuals = false
|
||||
|
||||
# Experimental option, might cause visible spaces between blocks
|
||||
# when set to higher number than 0.
|
||||
# type: enum values: 0, 1, 2, 4, 8, 16
|
||||
|
@ -353,6 +360,12 @@
|
|||
# type: bool
|
||||
# enable_shaders = true
|
||||
|
||||
##### Tone Mapping
|
||||
|
||||
# Enables filmic tone mapping
|
||||
# type: bool
|
||||
# tone_mapping = false
|
||||
|
||||
##### Bumpmapping
|
||||
|
||||
# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack
|
||||
|
@ -431,11 +444,6 @@
|
|||
|
||||
#### Advanced
|
||||
|
||||
# Minimum wanted FPS.
|
||||
# The amount of rendered stuff is dynamically set according to this. and viewing range min and max.
|
||||
# type: int
|
||||
# wanted_fps = 30
|
||||
|
||||
# If FPS would go higher than this, limit it by sleeping
|
||||
# to not waste CPU power for no benefit.
|
||||
# type: int
|
||||
|
@ -445,21 +453,16 @@
|
|||
# type: int
|
||||
# pause_fps_max = 20
|
||||
|
||||
# The allowed adjustment range for the automatic rendering range adjustment.
|
||||
# Set this to be equal to viewing range minimum to disable the auto-adjustment algorithm.
|
||||
# View distance in nodes.
|
||||
# Min = 20
|
||||
# type: int
|
||||
# viewing_range_nodes_max = 160
|
||||
# viewing_range = 100
|
||||
|
||||
# The allowed adjustment range for the automatic rendering range adjustment.
|
||||
# Set this to be equal to viewing range minimum to disable the auto-adjustment algorithm.
|
||||
# type: int
|
||||
# viewing_range_nodes_min = 35
|
||||
|
||||
# Vertical initial window size.
|
||||
# Width component of the initial window size.
|
||||
# type: int
|
||||
# screenW = 800
|
||||
|
||||
# Horizontal initial window size.
|
||||
# Height component of the initial window size.
|
||||
# type: int
|
||||
# screenH = 600
|
||||
|
||||
|
@ -486,7 +489,7 @@
|
|||
|
||||
# Path to texture directory. All textures are first searched from here.
|
||||
# type: path
|
||||
# texture_path =
|
||||
# texture_path =
|
||||
|
||||
# The rendering back-end for Irrlicht.
|
||||
# type: enum values: null, software, burningsvideo, direct3d8, direct3d9, opengl
|
||||
|
@ -518,7 +521,8 @@
|
|||
# - interlaced: odd/even line based polarisation screen support.
|
||||
# - topbottom: split screen top/bottom.
|
||||
# - sidebyside: split screen side by side.
|
||||
# type: enum values: none, anaglyph, interlaced, topbottom, sidebyside
|
||||
# - pageflip: quadbuffer based 3d.
|
||||
# type: enum values: none, anaglyph, interlaced, topbottom, sidebyside, pageflip
|
||||
# 3d_mode = none
|
||||
|
||||
# In-game chat console background color (R,G,B).
|
||||
|
@ -554,10 +558,6 @@
|
|||
# type: float
|
||||
# hud_hotbar_max_width = 1.0
|
||||
|
||||
# Enable selection highlighting for nodes (disables selectionbox).
|
||||
# type: bool
|
||||
# enable_node_highlighting = false
|
||||
|
||||
# Enables caching of facedir rotated meshes.
|
||||
# type: bool
|
||||
# enable_mesh_cache = false
|
||||
|
@ -587,6 +587,10 @@
|
|||
# type: float min: 0.25 max: 4
|
||||
# ambient_occlusion_gamma = 2.2
|
||||
|
||||
# Enables animation of inventory items.
|
||||
# type: bool
|
||||
# inventory_items_animations = false
|
||||
|
||||
### Menus
|
||||
|
||||
# Use a cloud animation for the main menu background.
|
||||
|
@ -658,7 +662,17 @@
|
|||
|
||||
# Path to save screenshots at.
|
||||
# type: path
|
||||
# screenshot_path =
|
||||
# screenshot_path =
|
||||
|
||||
# Format of screenshots.
|
||||
# type: enum values: png, jpg, bmp, pcx, ppm, tga
|
||||
# screenshot_format = png
|
||||
|
||||
# Screenshot quality. Only used for JPEG format.
|
||||
# 1 means worst quality; 100 means best quality.
|
||||
# Use 0 for default quality.
|
||||
# type: int min: 0 max: 100
|
||||
# screenshot_quality = 0
|
||||
|
||||
### Advanced
|
||||
|
||||
|
@ -727,7 +741,7 @@
|
|||
|
||||
# The network interface that the server listens on.
|
||||
# type: string
|
||||
# bind_address =
|
||||
# bind_address =
|
||||
|
||||
# Enable to disallow old clients from connecting.
|
||||
# Older clients are compatible in the sense that they will not crash when connecting
|
||||
|
@ -740,7 +754,7 @@
|
|||
# (obviously, remote_media should end with a slash).
|
||||
# Files that are not present will be fetched the usual way.
|
||||
# type: string
|
||||
# remote_media =
|
||||
# remote_media =
|
||||
|
||||
# Enable/disable running an IPv6 server. An IPv6 server may be restricted
|
||||
# to IPv6 clients, depending on system configuration.
|
||||
|
@ -778,7 +792,7 @@
|
|||
|
||||
# Message of the day displayed to players connecting.
|
||||
# type: string
|
||||
# motd =
|
||||
# motd =
|
||||
|
||||
# Maximum number of players that can connect simultaneously.
|
||||
# type: int
|
||||
|
@ -787,7 +801,7 @@
|
|||
# World directory (everything in the world is stored here).
|
||||
# Not needed if starting from the main menu.
|
||||
# type: path
|
||||
# map-dir =
|
||||
# map-dir =
|
||||
|
||||
# Time in seconds for item entity (dropped items) to live.
|
||||
# Setting it to -1 disables the feature.
|
||||
|
@ -801,17 +815,21 @@
|
|||
# A chosen map seed for a new map, leave empty for random.
|
||||
# Will be overridden when creating a new world in the main menu.
|
||||
# type: string
|
||||
# fixed_map_seed =
|
||||
# fixed_map_seed =
|
||||
|
||||
# New users need to input this password.
|
||||
# type: string
|
||||
# default_password =
|
||||
# default_password =
|
||||
|
||||
# The privileges that new users automatically get.
|
||||
# See /privs in game for a full list on your server and mod configuration.
|
||||
# type: string
|
||||
# default_privs = interact, shout
|
||||
|
||||
# Privileges that players with basic_privs can grant
|
||||
# type: string
|
||||
# basic_privs = interact, shout
|
||||
|
||||
# Whether players are shown to clients without any range limit.
|
||||
# Deprecated, use the setting player_transfer_distance instead.
|
||||
# type: bool
|
||||
|
@ -827,14 +845,7 @@
|
|||
|
||||
# If this is set, players will always (re)spawn at the given position.
|
||||
# type: string
|
||||
# static_spawnpoint =
|
||||
|
||||
# Maximum distance above water level for player spawn.
|
||||
# Larger values result in spawn points closer to (x = 0, z = 0).
|
||||
# Smaller values may result in a suitable spawn point not being found,
|
||||
# resulting in a spawn at (0, 0, 0) possibly buried underground.
|
||||
# type: int
|
||||
# vertical_spawn_range = 16
|
||||
# static_spawnpoint =
|
||||
|
||||
# If enabled, new players cannot join with an empty password.
|
||||
# type: bool
|
||||
|
@ -977,6 +988,18 @@
|
|||
# type: float
|
||||
# dedicated_server_step = 0.1
|
||||
|
||||
# Time in between active block management cycles
|
||||
# type: float
|
||||
# active_block_mgmt_interval = 2.0
|
||||
|
||||
# Length of time between ABM execution cycles
|
||||
# type: float
|
||||
# abm_interval = 1.0
|
||||
|
||||
# Length of time between NodeTimer execution cycles
|
||||
# type: float
|
||||
# nodetimer_interval = 1.0
|
||||
|
||||
# If enabled, invalid world data won't cause the server to shut down.
|
||||
# Only enable this if you know what you are doing.
|
||||
# type: bool
|
||||
|
@ -1000,7 +1023,7 @@
|
|||
|
||||
# Name of map generator to be used when creating a new world.
|
||||
# Creating a world in the main menu will override this.
|
||||
# type: enum values: v5, v6, v7, fractal, singlenode
|
||||
# type: enum values: v5, v6, v7, flat, valleys, fractal, singlenode
|
||||
# mg_name = v6
|
||||
|
||||
# Water surface level of the world.
|
||||
|
@ -1021,11 +1044,12 @@
|
|||
# map_generation_limit = 31000
|
||||
|
||||
# Global map generation attributes.
|
||||
# In Mapgen v6 the 'decorations' flag controls all decorations except trees
|
||||
# and junglegrass, in all other mapgens this flag controls all decorations.
|
||||
# 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.
|
||||
# 'trees' and 'flat' flags only have effect in mgv6.
|
||||
# type: flags possible values: trees, caves, dungeons, light, flat, notrees, nocaves, nodungeons, nolight, noflat
|
||||
# mg_flags = trees,caves,dungeons,light
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
# type: flags possible values: caves, dungeons, light, decorations, nocaves, nodungeons, nolight, nodecorations
|
||||
# mg_flags = caves,dungeons,light,decorations
|
||||
|
||||
### Advanced
|
||||
|
||||
|
@ -1072,6 +1096,10 @@
|
|||
|
||||
#### Mapgen v5
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
# type: float
|
||||
# mgv5_cave_width = 0.125
|
||||
|
||||
# type: noise_params
|
||||
# mgv5_np_filler_depth = 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0
|
||||
|
||||
|
@ -1090,13 +1118,13 @@
|
|||
#### Mapgen v6
|
||||
|
||||
# Map generation attributes specific to Mapgen v6.
|
||||
# When snowbiomes are enabled jungles are enabled and the jungles flag is ignored.
|
||||
# When snowbiomes are enabled jungles are automatically enabled, 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.
|
||||
# type: flags possible values: jungles, biomeblend, mudflow, snowbiomes, nojungles, nobiomeblend, nomudflow, nosnowbiomes
|
||||
# mgv6_spflags = jungles,biomeblend,mudflow,snowbiomes
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
# type: flags possible values: jungles, biomeblend, mudflow, snowbiomes, flat, trees, nojungles, nobiomeblend, nomudflow, nosnowbiomes, noflat, notrees
|
||||
# mgv6_spflags = jungles,biomeblend,mudflow,snowbiomes,trees
|
||||
|
||||
# Controls size of deserts and beaches in Mapgen V6.
|
||||
# Controls size of deserts and beaches in Mapgen v6.
|
||||
# When snowbiomes are enabled 'mgv6_freq_desert' is ignored.
|
||||
# type: float
|
||||
# mgv6_freq_desert = 0.45
|
||||
|
@ -1140,12 +1168,16 @@
|
|||
#### Mapgen v7
|
||||
|
||||
# Map generation attributes specific to Mapgen v7.
|
||||
# 'ridges' are the rivers.
|
||||
# The 'ridges' flag controls the rivers.
|
||||
# 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.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
# type: flags possible values: mountains, ridges, nomountains, noridges
|
||||
# mgv7_spflags = mountains,ridges
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
# type: float
|
||||
# mgv7_cave_width = 0.3
|
||||
|
||||
# type: noise_params
|
||||
# mgv7_np_terrain_base = 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0
|
||||
|
||||
|
@ -1156,7 +1188,7 @@
|
|||
# mgv7_np_terrain_persist = 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0
|
||||
|
||||
# type: noise_params
|
||||
# mgv7_np_height_select = -12, 24, (500, 500, 500), 4213, 6, 0.7, 2.0
|
||||
# mgv7_np_height_select = -8, 16, (500, 500, 500), 4213, 6, 0.7, 2.0
|
||||
|
||||
# type: noise_params
|
||||
# mgv7_np_filler_depth = 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
|
@ -1179,59 +1211,132 @@
|
|||
# type: noise_params
|
||||
# mgv7_np_cave2 = 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0
|
||||
|
||||
#### Mapgen flat
|
||||
|
||||
# Map generation attributes specific to Mapgen flat.
|
||||
# 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.
|
||||
# type: flags possible values: lakes, hills, , nolakes, nohills
|
||||
# mgflat_spflags =
|
||||
|
||||
# Y of flat ground.
|
||||
# type: int
|
||||
# mgflat_ground_level = 8
|
||||
|
||||
# Y of upper limit of large pseudorandom caves.
|
||||
# type: int
|
||||
# mgflat_large_cave_depth = -33
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
# type: float
|
||||
# mgflat_cave_width = 0.3
|
||||
|
||||
# Terrain noise threshold for lakes.
|
||||
# Controls proportion of world area covered by lakes.
|
||||
# Adjust towards 0.0 for a larger proportion.
|
||||
# type: float
|
||||
# mgflat_lake_threshold = -0.45
|
||||
|
||||
# Controls steepness/depth of lake depressions.
|
||||
# type: float
|
||||
# mgflat_lake_steepness = 48.0
|
||||
|
||||
# Terrain noise threshold for hills.
|
||||
# Controls proportion of world area covered by hills.
|
||||
# Adjust towards 0.0 for a larger proportion.
|
||||
# type: float
|
||||
# mgflat_hill_threshold = 0.45
|
||||
|
||||
# Controls steepness/height of hills.
|
||||
# type: float
|
||||
# mgflat_hill_steepness = 64.0
|
||||
|
||||
# Determines terrain shape.
|
||||
# The 3 numbers in brackets control the scale of the
|
||||
# terrain, the 3 numbers should be identical.
|
||||
# type: noise_params
|
||||
# mgflat_np_terrain = 0, 1, (600, 600, 600), 7244, 5, 0.6, 2.0
|
||||
|
||||
# type: noise_params
|
||||
# mgflat_np_filler_depth = 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
|
||||
# type: noise_params
|
||||
# mgflat_np_cave1 = 0, 12, (128, 128, 128), 52534, 4, 0.5, 2.0
|
||||
|
||||
# type: noise_params
|
||||
# mgflat_np_cave2 = 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0
|
||||
|
||||
#### Mapgen fractal
|
||||
|
||||
# Map generation attributes specific to Mapgen fractal.
|
||||
# 'julia' selects a julia set to be generated instead of a mandelbrot set.
|
||||
# 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.
|
||||
# type: flags possible values: julia, nojulia
|
||||
# mgfractal_spflags = nojulia
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
# type: float
|
||||
# mgfractal_cave_width = 0.3
|
||||
|
||||
# Mandelbrot set: Iterations of the recursive function.
|
||||
# Controls scale of finest detail.
|
||||
# Choice of 18 fractals from 9 formulas.
|
||||
# 1 = 4D "Roundy" mandelbrot set.
|
||||
# 2 = 4D "Roundy" julia set.
|
||||
# 3 = 4D "Squarry" mandelbrot set.
|
||||
# 4 = 4D "Squarry" julia set.
|
||||
# 5 = 4D "Mandy Cousin" mandelbrot set.
|
||||
# 6 = 4D "Mandy Cousin" julia set.
|
||||
# 7 = 4D "Variation" mandelbrot set.
|
||||
# 8 = 4D "Variation" julia set.
|
||||
# 9 = 3D "Mandelbrot/Mandelbar" mandelbrot set.
|
||||
# 10 = 3D "Mandelbrot/Mandelbar" julia set.
|
||||
# 11 = 3D "Christmas Tree" mandelbrot set.
|
||||
# 12 = 3D "Christmas Tree" julia set.
|
||||
# 13 = 3D "Mandelbulb" mandelbrot set.
|
||||
# 14 = 3D "Mandelbulb" julia set.
|
||||
# 15 = 3D "Cosine Mandelbulb" mandelbrot set.
|
||||
# 16 = 3D "Cosine Mandelbulb" julia set.
|
||||
# 17 = 4D "Mandelbulb" mandelbrot set.
|
||||
# 18 = 4D "Mandelbulb" julia set.
|
||||
# type: int min: 1 max: 18
|
||||
# mgfractal_fractal = 1
|
||||
|
||||
# Iterations of the recursive function.
|
||||
# Controls the amount of fine detail.
|
||||
# type: int
|
||||
# mgfractal_m_iterations = 9
|
||||
# mgfractal_iterations = 11
|
||||
|
||||
# Mandelbrot set: Approximate (X,Y,Z) scales in nodes.
|
||||
# Approximate (X,Y,Z) scale of fractal in nodes.
|
||||
# type: v3f
|
||||
# mgfractal_m_scale = (1024.0, 256.0, 1024.0)
|
||||
# mgfractal_scale = (4096.0, 1024.0, 4096.0)
|
||||
|
||||
# Mandelbrot set: (X,Y,Z) offsets from world centre.
|
||||
# Range roughly -2 to 2, multiply by m_scale for offsets in nodes.
|
||||
# (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.
|
||||
# type: v3f
|
||||
# mgfractal_m_offset = (1.75, 0.0, 0.0)
|
||||
# mgfractal_offset = (1.79, 0.0, 0.0)
|
||||
|
||||
# Mandelbrot set: W co-ordinate of the generated 3D slice of the 4D shape.
|
||||
# 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.
|
||||
# type: float
|
||||
# mgfractal_m_slice_w = 0.0
|
||||
# mgfractal_slice_w = 0.0
|
||||
|
||||
# Julia set: Iterations of the recursive function.
|
||||
# Controls scale of finest detail.
|
||||
# type: int
|
||||
# mgfractal_j_iterations = 9
|
||||
|
||||
# Julia set: Approximate (X,Y,Z) scales in nodes.
|
||||
# type: v3f
|
||||
# mgfractal_j_scale = (2048.0, 512.0, 2048.0)
|
||||
|
||||
# Julia set: (X,Y,Z) offsets from world centre.
|
||||
# Range roughly -2 to 2, multiply by j_scale for offsets in nodes.
|
||||
# type: v3f
|
||||
# mgfractal_j_offset = (0.0, 1.0, 0.0)
|
||||
|
||||
# Julia set: W co-ordinate of the generated 3D slice of the 4D shape.
|
||||
# Range roughly -2 to 2.
|
||||
# type: float
|
||||
# mgfractal_j_slice_w = 0.0
|
||||
|
||||
# Julia set: The following 4 values determine the 4D shape.
|
||||
# Julia set only: X component of hypercomplex constant determining julia shape.
|
||||
# Range roughly -2 to 2.
|
||||
# type: float
|
||||
# mgfractal_julia_x = 0.33
|
||||
|
||||
# Julia set only: Y component of hypercomplex constant determining julia shape.
|
||||
# Range roughly -2 to 2.
|
||||
# type: float
|
||||
# mgfractal_julia_y = 0.33
|
||||
|
||||
# Julia set only: Z component of hypercomplex constant determining julia shape.
|
||||
# Range roughly -2 to 2.
|
||||
# type: float
|
||||
# mgfractal_julia_z = 0.33
|
||||
|
||||
# Julia set only: W component of hypercomplex constant determining julia shape.
|
||||
# Has no effect on 3D fractals.
|
||||
# Range roughly -2 to 2.
|
||||
# type: float
|
||||
# mgfractal_julia_w = 0.33
|
||||
|
||||
# type: noise_params
|
||||
|
@ -1246,6 +1351,95 @@
|
|||
# type: noise_params
|
||||
# mgfractal_np_cave2 = 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0
|
||||
|
||||
#### Mapgen Valleys
|
||||
|
||||
##### General
|
||||
|
||||
# Map generation attributes specific to Mapgen Valleys.
|
||||
# 'altitude_chill' makes higher elevations colder, which may cause biome issues.
|
||||
# 'humid_rivers' modifies the humidity around rivers and in areas where water would tend to pool,
|
||||
# it may interfere with delicately adjusted biomes.
|
||||
# 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.
|
||||
# type: flags possible values: altitude_chill, noaltitude_chill, humid_rivers, nohumid_rivers
|
||||
# mg_valleys_spflags = altitude_chill,humid_rivers
|
||||
|
||||
# The altitude at which temperature drops by 20C
|
||||
# type: int
|
||||
# mgvalleys_altitude_chill = 90
|
||||
|
||||
# Depth below which you'll find large caves.
|
||||
# type: int
|
||||
# mgvalleys_large_cave_depth = -33
|
||||
|
||||
# Creates unpredictable lava features in caves.
|
||||
# These can make mining difficult. Zero disables them. (0-10)
|
||||
# type: int
|
||||
# mgvalleys_lava_features = 0
|
||||
|
||||
# Depth below which you'll find massive caves.
|
||||
# type: int
|
||||
# mgvalleys_massive_cave_depth = -256
|
||||
|
||||
# How deep to make rivers
|
||||
# type: int
|
||||
# mgvalleys_river_depth = 4
|
||||
|
||||
# How wide to make rivers
|
||||
# type: int
|
||||
# mgvalleys_river_size = 5
|
||||
|
||||
# Creates unpredictable water features in caves.
|
||||
# These can make mining difficult. Zero disables them. (0-10)
|
||||
# type: int
|
||||
# mgvalleys_water_features = 0
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
# type: float
|
||||
# mgvalleys_cave_width = 0.3
|
||||
|
||||
##### Noises
|
||||
|
||||
# Caves and tunnels form at the intersection of the two noises
|
||||
# type: noise_params
|
||||
# mgvalleys_np_cave1 = 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0
|
||||
|
||||
# Caves and tunnels form at the intersection of the two noises
|
||||
# type: noise_params
|
||||
# mgvalleys_np_cave2 = 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0
|
||||
|
||||
# The depth of dirt or other filler
|
||||
# type: noise_params
|
||||
# mgvalleys_np_filler_depth = 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0
|
||||
|
||||
# Massive caves form here.
|
||||
# type: noise_params
|
||||
# mgvalleys_np_massive_caves = 0, 1, (768, 256, 768), 59033, 6, 0.63, 2.0
|
||||
|
||||
# River noise -- rivers occur close to zero
|
||||
# type: noise_params
|
||||
# mgvalleys_np_rivers = 0, 1, (256, 256, 256), -6050, 5, 0.6, 2.0
|
||||
|
||||
# Base terrain height
|
||||
# type: noise_params
|
||||
# mgvalleys_np_terrain_height = -10, 50, (1024, 1024, 1024), 5202, 6, 0.4, 2.0
|
||||
|
||||
# Raises terrain to make valleys around the rivers
|
||||
# type: noise_params
|
||||
# mgvalleys_np_valley_depth = 5, 4, (512, 512, 512), -1914, 1, 1.0, 2.0
|
||||
|
||||
# Slope and fill work together to modify the heights
|
||||
# type: noise_params
|
||||
# mgvalleys_np_inter_valley_fill = 0, 1, (256, 512, 256), 1993, 6, 0.8, 2.0
|
||||
|
||||
# Amplifies the valleys
|
||||
# type: noise_params
|
||||
# mgvalleys_np_valley_profile = 0.6, 0.5, (512, 512, 512), 777, 1, 1.0, 2.0
|
||||
|
||||
# Slope and fill work together to modify the heights
|
||||
# type: noise_params
|
||||
# mgvalleys_np_inter_valley_slope = 0.5, 0.5, (128, 128, 128), 746, 1, 1.0, 2.0
|
||||
|
||||
## Security
|
||||
|
||||
# Prevent mods from doing insecure things like running shell commands.
|
||||
|
@ -1255,7 +1449,12 @@
|
|||
# Comma-separated list of trusted mods that are allowed to access insecure
|
||||
# functions even when mod security is on (via request_insecure_environment()).
|
||||
# type: string
|
||||
# secure.trusted_mods =
|
||||
# secure.trusted_mods =
|
||||
|
||||
# Comma-seperated list of mods that are allowed to access HTTP APIs, which
|
||||
# allow them to upload and download data to/from the internet.
|
||||
# type: string
|
||||
# secure.http_mods =
|
||||
|
||||
#
|
||||
# Client and Server
|
||||
|
@ -1265,12 +1464,12 @@
|
|||
# When running a server, clients connecting with this name are admins.
|
||||
# When starting from the main menu, this is overridden.
|
||||
# type: string
|
||||
# name =
|
||||
# name =
|
||||
|
||||
# Set the language. Leave empty to use the system language.
|
||||
# A restart is required after changing this.
|
||||
# type: enum values: , be, cs, da, de, eo, es, et, fr, hu, id, it, ja, jbo, ko, ky, lt, nb, nl, pl, pt, pt_BR, ro, ru, tr, uk, zh_CN, zh_TW
|
||||
# language =
|
||||
# language =
|
||||
|
||||
# Level of logging to be written to debug.txt:
|
||||
# - <nothing> (no logging)
|
||||
|
@ -1312,7 +1511,7 @@
|
|||
|
||||
# Replaces the default main menu with a custom one.
|
||||
# type: string
|
||||
# main_menu_script =
|
||||
# main_menu_script =
|
||||
|
||||
# type: int
|
||||
# main_menu_game_mgr = 0
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
</ul>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot type="default" width="1440" height="851">http://minetest.net/_media/screen2.png</screenshot>
|
||||
<screenshot width="1440" height="851">http://minetest.net/_media/screenshot_4032289578.png</screenshot>
|
||||
<screenshot type="default" width="1920" height="1080">http://www.minetest.net/media/gallery/1.jpg</screenshot>
|
||||
<screenshot width="1920" height="1080">http://www.minetest.net/media/gallery/3.jpg</screenshot>
|
||||
<screenshot width="1920" height="1080">http://www.minetest.net/media/gallery/5.jpg</screenshot>
|
||||
</screenshots>
|
||||
<url type="homepage">http://minetest.net</url>
|
||||
<updatecontact>sfan5@live.de</updatecontact>
|
||||
|
|