First commit

master
Joel Leclerc 2012-04-29 13:24:10 -06:00
commit f6c1abcc43
707 changed files with 252252 additions and 0 deletions

47
.gitignore vendored Normal file
View File

@ -0,0 +1,47 @@
## Generic ignorable patterns and files
*~
.*.swp
*bak*
tags
*.vim
## Non-static Minetest directories
/build*
/bin/
/games/*
!/games/minetest/
!/games/minimal/
/cache/
/textures/
/sounds/
/mods/*
!/mods/minetest/
/mods/minetest/*
!/mods/minetest/mods_here.txt
/worlds/
/world/
## Configuration/log files
minetest.conf
debug.txt
## Build files
CMakeFiles/*
src/CMakeFiles/*
src/Makefile
src/cmake_config.h
src/cmake_install.cmake
src/jthread/CMakeFiles/*
src/jthread/Makefile
src/jthread/cmake_config.h
src/jthread/cmake_install.cmake
src/jthread/libjthread.a
src/lua/build/
src/lua/CMakeFiles/
CMakeCache.txt
CPackConfig.cmake
CPackSourceConfig.cmake
Makefile
cmake_install.cmake
locale/

171
CMakeLists.txt Normal file
View File

@ -0,0 +1,171 @@
cmake_minimum_required(VERSION 2.6)
if(${CMAKE_VERSION} STREQUAL "2.8.2")
# bug http://vtk.org/Bug/view.php?id=11020
message( WARNING "CMake/CPack version 2.8.2 will not create working .deb packages!")
endif(${CMAKE_VERSION} STREQUAL "2.8.2")
# This can be read from ${PROJECT_NAME} after project() is called
project(minetest)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
set(VERSION_MAJOR 0)
set(VERSION_MINOR 4)
set(VERSION_PATCH dev-20120408)
if(VERSION_EXTRA)
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
endif()
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
MESSAGE(STATUS "*** Will build version ${VERSION_STRING} ***")
# Configuration options
if(WIN32)
set(RUN_IN_PLACE 1 CACHE BOOL "Run directly in source directory structure")
else()
set(RUN_IN_PLACE 0 CACHE BOOL "Run directly in source directory structure")
endif()
set(BUILD_CLIENT 1 CACHE BOOL "Build client")
if(WIN32)
set(BUILD_SERVER 0 CACHE BOOL "Build server")
else()
set(BUILD_SERVER 1 CACHE BOOL "Build server")
endif()
set(WARN_ALL 1 CACHE BOOL "Enable -Wall for Release build")
if(NOT CMAKE_BUILD_TYPE)
# Default to release
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE)
endif()
# Included stuff
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
include(${CMAKE_SOURCE_DIR}/cmake/Modules/misc.cmake)
# This is done here so that relative search paths are more reasnable
find_package(Irrlicht)
find_package(CURL)
#
# Installation
#
if(WIN32)
set(SHAREDIR ".")
set(BINDIR "bin")
set(DOCDIR "doc")
set(EXAMPLE_CONF_DIR ".")
set(LOCALEDIR "locale")
elseif(APPLE)
# Random placeholders; this isn't usually used and may not work
# See https://github.com/toabi/minetest-mac/
set(SHAREDIR "share/${PROJECT_NAME}")
set(BINDIR "bin")
set(DOCDIR "share/doc/${PROJECT_NAME}")
set(EXAMPLE_CONF_DIR ${DOCDIR})
set(LOCALEDIR "locale")
elseif(UNIX) # Linux, BSD etc
if(RUN_IN_PLACE)
set(SHAREDIR ".")
set(BINDIR "bin")
set(DOCDIR "doc")
set(EXAMPLE_CONF_DIR ".")
set(MANDIR "unix/man")
set(XDG_APPS_DIR "unix/applications")
set(ICONDIR "unix/icons")
set(LOCALEDIR "locale")
else()
set(SHAREDIR "share/${PROJECT_NAME}")
set(BINDIR "bin")
set(DOCDIR "share/doc/${PROJECT_NAME}")
set(MANDIR "share/man")
set(EXAMPLE_CONF_DIR ${DOCDIR})
set(XDG_APPS_DIR "share/applications")
set(ICONDIR "share/icons")
set(LOCALEDIR "share/locale")
endif()
endif()
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}")
#install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games")
set(MINETEST_GAME_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest")
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")
endif()
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)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/mods/minetest/mods_here.txt" DESTINATION "${SHAREDIR}/mods/minetest")
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/textures/all/textures_here.txt" DESTINATION "${SHAREDIR}/textures/all")
endif()
install(FILES "README.md" DESTINATION "${DOCDIR}")
install(FILES "doc/lua_api.txt" DESTINATION "${DOCDIR}")
install(FILES "doc/mapformat.txt" DESTINATION "${DOCDIR}")
install(FILES "minetest.conf.example" DESTINATION "${EXAMPLE_CONF_DIR}")
if(UNIX)
install(FILES "doc/minetest.6" "doc/minetestserver.6" DESTINATION "${MANDIR}/man6")
install(FILES "misc/minetest.desktop" DESTINATION "${XDG_APPS_DIR}")
install(FILES "misc/minetest-icon.svg" DESTINATION "${ICONDIR}/hicolor/scalable/apps")
endif()
#
# Subdirectories
# Be sure to add all relevant definitions above this
#
add_subdirectory(src)
# CPack
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "An InfiniMiner/Minecraft inspired game")
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
set(CPACK_PACKAGE_VENDOR "celeron55")
set(CPACK_PACKAGE_CONTACT "Perttu Ahola <celeron55@gmail.com>")
if(WIN32)
# For some reason these aren't copied otherwise
# NOTE: For some reason now it seems to work without these
#if(BUILD_CLIENT)
# install(FILES bin/minetest.exe DESTINATION bin)
#endif()
#if(BUILD_SERVER)
# install(FILES bin/minetestserver.exe DESTINATION bin)
#endif()
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32")
set(CPACK_GENERATOR ZIP)
# This might be needed for some installer
#set(CPACK_PACKAGE_EXECUTABLES bin/minetest.exe "Minetest" bin/minetestserver.exe "Minetest Server")
elseif(APPLE)
# TODO
# see http://cmake.org/Wiki/CMake:CPackPackageGenerators#Bundle_.28OSX_only.29
#
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-osx")
set(CPACK_PACKAGE_ICON "")
set(CPACK_BUNDLE_NAME ${PROJECT_NAME})
set(CPACK_BUNDLE_ICON "")
set(CPACK_BUNDLE_PLIST "")
set(CPACK_BUNDLE_STARTUP_COMMAND "Contents/MacOS/${PROJECT_NAME}")
set(CPACK_GENERATOR "Bundle")
else()
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-linux")
set(CPACK_GENERATOR TGZ)
set(CPACK_SOURCE_GENERATOR TGZ)
endif()
include(CPack)

338
README.md Normal file
View File

@ -0,0 +1,338 @@
Minetest++
==========
A game built off of the best free and open source Minecraft clone, Minetest-C55.
Copyright (c) 2010-2012 Perttu Ahola <celeron55@gmail.com>
and ther contributors (see source file comments and the version control log)
This contains 2 different game modes, Minetest and Minimal.
Game mode Minimal is just a test and will be taken out soon. Game mode Minetest has all the cool features.
Further documentation
----------------------
- Website: http://www.minetest.net
- Wiki: http://wiki.minetest.com
- Forum: http://www.minetest.net/forum
This game is in alpha!
--------------------------
- Don't expect it to work as well as a finished game will.
- Please tell me about any bugs you come across. Just look in your debug.txt file. (/minetest/bin/debug.txt)
- But other then that, have fun and expect new features :)
Default Controls
-----------------
- WASD: Move
- Space: Jump
- E:
- While walking: Run (need the fast privelage)
- While flying: Go down
- Shift: Sneak
- Q: Drop item
- R: Open inventory
- Mouse: Turn/look
- C: Toggle fly (need fly privelage)
- X: toggle fast (need fast Privelage)
- Settable in the configuration file, see the section below.
Compiling:
-----------------------
### GNU/Linux ###
#### Install dependencies. ####
Here's an example for Debian/Ubuntu:
`sudo apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev`
#### Download source: ####
##### Method 1: Download tarball #####
wget https://github.com/jordan4ibanez/minetest/tarball/master -O master.tar.gz
tar xf master.tar.gz
cd jordan4ibanez-minetest-*
##### Method 2: Clone from git #####
git clone git://github.com/jordan4ibanez/minetest.git minetestpp
cd minetestpp
#### Build ####
##### Method 1: Build a version that runs directly from the source directory #####
cmake . -DRUN_IN_PLACE=1
make -j2
##### Method 2: Build a version that can be installed system-wide #####
mkdir build && cd build
cmake ..
make
sudo make install
- Use cmake . -LH to see all CMake options and their current state
- If you want to install it system-wide (or are making a distribution package), you will want to use -DRUN_IN_PLACE=0
- You can build a bare server or a bare client by specifying -DBUILD_CLIENT=0 or -DBUILD_SERVER=0
- You can select between Release and Debug build by -DCMAKE_BUILD_TYPE=<Debug or Release>
- Debug build is slower, but gives much more useful output in a debugger
### Windows :###
- This section is outdated. In addition to what is described here:
- In addition to minetest, you need to download minetest_game.
- If you wish to have sound support, you need libogg, libvorbis and libopenal
- You need:
* CMake:
http://www.cmake.org/cmake/resources/software.html
* MinGW or Visual Studio
http://www.mingw.org/
http://msdn.microsoft.com/en-us/vstudio/default
* Irrlicht SDK 1.7:
http://irrlicht.sourceforge.net/downloads.html
* Zlib headers (zlib125.zip)
http://www.winimage.com/zLibDll/index.html
* Zlib library (zlibwapi.lib and zlibwapi.dll from zlib125dll.zip):
http://www.winimage.com/zLibDll/index.html
* Optional: gettext bibrary and tools:
http://gnuwin32.sourceforge.net/downlinks/gettext.php
- This is used for other UI languages. Feel free to leave it out.
* And, of course, Minetest-c55:
http://c55.me/minetest/download
- Steps:
- Select a directory called DIR hereafter in which you will operate.
- Make sure you have CMake and a compiler installed.
- Download all the other stuff to DIR and extract them into there.
("extract here", not "extract to packagename/")
NOTE: zlib125dll.zip needs to be extracted into zlib125dll
- All those packages contain a nice base directory in them, which
should end up being the direct subdirectories of DIR.
- You will end up with a directory structure like this:
+ DIR
- zlib-1.2.5.tar.gz
- zlib125dll.zip
- irrlicht-1.7.1.zip
- 110214175330.zip (or whatever, this is the minetest source)
+ zlib-1.2.5
- zlib.h
+ win32
...
+ zlib125dll
- readme.txt
+ dll32
...
+ irrlicht-1.7.1
+ lib
+ include
...
+ gettext (optional)
+bin
+include
+lib
+ minetest
+ src
+ doc
- CMakeLists.txt
- Start up the CMake GUI
- Select "Browse Source..." and select DIR/minetest
- Now, if using MSVC:
- Select "Browse Build..." and select DIR/minetest-build
- Else if using MinGW:
- Select "Browse Build..." and select DIR/minetest
- Select "Configure"
- Select your compiler
- It will warn about missing stuff, ignore that at this point. (later don't)
- Make sure the configuration is as follows (note that the versions may differ for you):</li><pre><code>-----------------
BUILD_CLIENT [X]
BUILD_SERVER [ ]
CMAKE_BUILD_TYPE Release
CMAKE_INSTALL_PREFIX DIR/minetest-install
IRRLICHT_SOURCE_DIR DIR/irrlicht-1.7.1
RUN_IN_PLACE [X]
WARN_ALL [ ]
ZLIB_DLL DIR/zlib125dll/dll32/zlibwapi.dll
ZLIB_INCLUDE_DIR DIR/zlib-1.2.5
ZLIB_LIBRARIES DIR/zlib125dll/dll32/zlibwapi.lib
GETTEXT_BIN_DIR DIR/gettext/bin
GETTEXT_INCLUDE_DIR DIR/gettext/include
GETTEXT_LIBRARIES DIR/gettext/lib/intl.lib
GETTEXT_MSGFMT DIR/gettext/bin/msgfmt
-----------------</code></pre>
- Hit "Configure"
- Hit "Configure" once again 8)
- If something is still coloured red, you have a problem.
- Hit "Generate"
If using MSVC:
- Open the generated minetest.sln
- The project defaults to the "Debug" configuration. Make very sure to
select "Release", unless you want to debug some stuff (it's slower
and might not even work at all)
- Build the ALL_BUILD project
- Build the INSTALL project
- You should now have a working game with the executable in
DIR/minetest-install/bin/minetest.exe
- Additionally you may create a zip package by building the PACKAGE
project.
If using MinGW:
- Using the command line, browse to the build directory and run 'make'
(or mingw32-make or whatever it happens to be)
- You may need to copy some of the downloaded DLLs into bin/, see what
running the produced executable tells you it doesn't have.
- You should now have a working game with the executable in
DIR/minetest/bin/minetest.exe
#### This can be automated with a batch script like this ###
set sourcedir=%CD%
set installpath="C:\tmp\minetest_install"
set irrlichtpath="C:\tmp\irrlicht-1.7.2"
set builddir=%sourcedir%\bvc10
mkdir %builddir%
pushd %builddir%
cmake %sourcedir% -G "Visual Studio 10" -DIRRLICHT_SOURCE_DIR=%irrlichtpath% -DRUN_IN_PLACE=1 -DCMAKE_INSTALL_PREFIX=%installpath%
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" INSTALL.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" PACKAGE.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
popd
echo Finished.
exit /b 0
:fail
popd
echo Failed.
exit /b 1
License of Minetest-c55 textures and sounds
-------------------------------------------
This applies to textures and sounds contained in the main Minetest
distribution.
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/
License of Minetest-c55 source code
-----------------------------------
Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU 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.
Irrlicht
---------------
This program uses the Irrlicht Engine. http://irrlicht.sourceforge.net/
The Irrlicht Engine License
Copyright © 2002-2005 Nikolaus Gebhardt
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
JThread
---------------
This program uses the JThread library. License for JThread follows:
Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
Lua
---------------
Lua is licensed under the terms of the MIT license reproduced below.
This means that Lua is free software and can be used for both academic
and commercial purposes at absolutely no cost.
For details and rationale, see http://www.lua.org/license.html .
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Fonts
---------------
DejaVu Sans Mono:
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
Bitstream Vera Fonts Copyright:
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
a trademark of Bitstream, Inc.
Arev Fonts Copyright:
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
Press Start 2P Font by:
codeman38 http://www.zone38.net/font/

253
README.txt Normal file
View File

@ -0,0 +1,253 @@
Minetest++
A game built off of the best free and open source Minecraft clone, Minetest-C55.
Copyright (c) 2010-2012 Perttu Ahola celeron55@gmail.com and ther contributors (see source file comments and the version control log)
This contains 2 different game modes, Minetest and Minimal. Game mode Minimal is just a test and will be taken out soon. Game mode Minetest has all the cool features.
Further documentation
Website: http://www.minetest.net
Wiki: http://wiki.minetest.com
Forum: http://www.minetest.net/forum
This game is in alpha!
Don't expect it to work as well as a finished game will.
Please tell me about any bugs you come across. Just look in your debug.txt file. (/minetest/bin/debug.txt)
But other then that, have fun and expect new features :)
Default Controls
WASD: Move
Space: Jump
E:
While walking: Run (need the fast privelage)
While flying: Go down
Shift: Sneak
Q: Drop item
R: Open inventory
Mouse: Turn/look
C: Toggle fly (need fly privelage)
X: toggle fast (need fast Privelage)
Settable in the configuration file, see the section below.
Compiling:
GNU/Linux
Install dependencies.
Here's an example for Debian/Ubuntu: sudo apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl3
Download source:
Method 1: Download tarball
wget https://github.com/jordan4ibanez/minetest/tarball/master -O master.tar.gz
tar xf master.tar.gz
cd jordan4ibanez-minetest-*
Method 2: Clone from git
git clone git://github.com/jordan4ibanez/minetest.git minetestpp
cd minetestpp
Build
Method 1: Build a version that runs directly from the source directory
cmake . -DRUN_IN_PLACE=1
make -j2
Method 2: Build a version that can be installed system-wide
mkdir build && cd build
cmake ..
make
sudo make install
Use cmake . -LH to see all CMake options and their current state
If you want to install it system-wide (or are making a distribution package), you will want to use -DRUN_IN_PLACE=0
You can build a bare server or a bare client by specifying -DBUILD_CLIENT=0 or -DBUILD_SERVER=0
You can select between Release and Debug build by -DCMAKE_BUILD_TYPE=
Debug build is slower, but gives much more useful output in a debugger
Windows :
This section is outdated. In addition to what is described here:
In addition to minetest, you need to download minetest_game.
If you wish to have sound support, you need libogg, libvorbis and libopenal
You need:
CMake: http://www.cmake.org/cmake/resources/software.html
MinGW or Visual Studio http://www.mingw.org/ http://msdn.microsoft.com/en-us/vstudio/default
Irrlicht SDK 1.7: http://irrlicht.sourceforge.net/downloads.html
Zlib headers (zlib125.zip) http://www.winimage.com/zLibDll/index.html
Zlib library (zlibwapi.lib and zlibwapi.dll from zlib125dll.zip): http://www.winimage.com/zLibDll/index.html
Optional: gettext bibrary and tools: http://gnuwin32.sourceforge.net/downlinks/gettext.php
This is used for other UI languages. Feel free to leave it out.
And, of course, Minetest-c55: http://c55.me/minetest/download
Steps:
Select a directory called DIR hereafter in which you will operate.
Make sure you have CMake and a compiler installed.
Download all the other stuff to DIR and extract them into there. ("extract here", not "extract to packagename/") NOTE: zlib125dll.zip needs to be extracted into zlib125dll
All those packages contain a nice base directory in them, which should end up being the direct subdirectories of DIR.
You will end up with a directory structure like this:
DIR
zlib-1.2.5.tar.gz
zlib125dll.zip
irrlicht-1.7.1.zip
110214175330.zip (or whatever, this is the minetest source)
zlib-1.2.5
zlib.h
win32 ...
zlib125dll
readme.txt
dll32 ...
irrlicht-1.7.1
lib
include ...
gettext (optional) +bin +include +lib
minetest
src
doc
CMakeLists.txt
Start up the CMake GUI
Select "Browse Source..." and select DIR/minetest
Now, if using MSVC:
Select "Browse Build..." and select DIR/minetest-build
Else if using MinGW:
Select "Browse Build..." and select DIR/minetest
Select "Configure"
Select your compiler
It will warn about missing stuff, ignore that at this point. (later don't)
Make sure the configuration is as follows (note that the versions may differ for you):
-----------------
BUILD_CLIENT [X]
BUILD_SERVER [ ]
CMAKE_BUILD_TYPE Release
CMAKE_INSTALL_PREFIX DIR/minetest-install
IRRLICHT_SOURCE_DIR DIR/irrlicht-1.7.1
RUN_IN_PLACE [X]
WARN_ALL [ ]
ZLIB_DLL DIR/zlib125dll/dll32/zlibwapi.dll
ZLIB_INCLUDE_DIR DIR/zlib-1.2.5
ZLIB_LIBRARIES DIR/zlib125dll/dll32/zlibwapi.lib
GETTEXT_BIN_DIR DIR/gettext/bin
GETTEXT_INCLUDE_DIR DIR/gettext/include
GETTEXT_LIBRARIES DIR/gettext/lib/intl.lib
GETTEXT_MSGFMT DIR/gettext/bin/msgfmt
-----------------
Hit "Configure"
Hit "Configure" once again 8)
If something is still coloured red, you have a problem.
Hit "Generate" If using MSVC:
Open the generated minetest.sln
The project defaults to the "Debug" configuration. Make very sure to select "Release", unless you want to debug some stuff (it's slower and might not even work at all)
Build the ALL_BUILD project
Build the INSTALL project
You should now have a working game with the executable in DIR/minetest-install/bin/minetest.exe
Additionally you may create a zip package by building the PACKAGE project. If using MinGW:
Using the command line, browse to the build directory and run 'make' (or mingw32-make or whatever it happens to be)
You may need to copy some of the downloaded DLLs into bin/, see what running the produced executable tells you it doesn't have.
You should now have a working game with the executable in DIR/minetest/bin/minetest.exe
This can be automated with a batch script like this
set sourcedir=%CD%
set installpath="C:\tmp\minetest_install"
set irrlichtpath="C:\tmp\irrlicht-1.7.2"
set builddir=%sourcedir%\bvc10
mkdir %builddir%
pushd %builddir%
cmake %sourcedir% -G "Visual Studio 10" -DIRRLICHT_SOURCE_DIR=%irrlichtpath% -DRUN_IN_PLACE=1 -DCMAKE_INSTALL_PREFIX=%installpath%
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" INSTALL.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" PACKAGE.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
popd
echo Finished.
exit /b 0
:fail
popd
echo Failed.
exit /b 1
License of Minetest-c55 textures and sounds
This applies to textures and sounds contained in the main Minetest distribution.
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/
License of Minetest-c55 source code
Minetest-c55 Copyright (C) 2010-2011 celeron55, Perttu Ahola celeron55@gmail.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU 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.
Irrlicht
This program uses the Irrlicht Engine. http://irrlicht.sourceforge.net/
The Irrlicht Engine License
Copyright © 2002-2005 Nikolaus Gebhardt
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
This notice may not be removed or altered from any source distribution.
JThread
This program uses the JThread library. License for JThread follows:
Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Lua
Lua is licensed under the terms of the MIT license reproduced below. This means that Lua is free software and can be used for both academic and commercial purposes at absolutely no cost.
For details and rationale, see http://www.lua.org/license.html .
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Fonts
DejaVu Sans Mono:
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
Bitstream Vera Fonts Copyright:
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.
Arev Fonts Copyright:
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
Press Start 2P Font by:
codeman38 http://www.zone38.net/font/

188
builtin/auth.lua Normal file
View File

@ -0,0 +1,188 @@
-- Minetest: builtin/auth.lua
--
-- Authentication handler
--
function minetest.string_to_privs(str, delim)
assert(type(str) == "string")
delim = delim or ','
privs = {}
for _, priv in pairs(string.split(str, delim)) do
privs[priv:trim()] = true
end
return privs
end
function minetest.privs_to_string(privs, delim)
assert(type(privs) == "table")
delim = delim or ','
list = {}
for priv, bool in pairs(privs) do
if bool then
table.insert(list, priv)
end
end
return table.concat(list, delim)
end
assert(minetest.string_to_privs("a,b").b == true)
assert(minetest.privs_to_string({a=true,b=true}) == "a,b")
minetest.auth_file_path = minetest.get_worldpath().."/auth.txt"
minetest.auth_table = {}
local function read_auth_file()
local newtable = {}
local file, errmsg = io.open(minetest.auth_file_path, 'rb')
if not file then
minetest.log("info", minetest.auth_file_path.." could not be opened for reading ("..errmsg.."); assuming new world")
return
end
for line in file:lines() do
if line ~= "" then
local name, password, privilegestring = string.match(line, "([^:]*):([^:]*):([^:]*)")
if not name or not password or not privilegestring then
error("Invalid line in auth.txt: "..dump(line))
end
local privileges = minetest.string_to_privs(privilegestring)
newtable[name] = {password=password, privileges=privileges}
end
end
io.close(file)
minetest.auth_table = newtable
minetest.notify_authentication_modified()
end
local function save_auth_file()
local newtable = {}
-- Check table for validness before attempting to save
for name, stuff in pairs(minetest.auth_table) do
assert(type(name) == "string")
assert(name ~= "")
assert(type(stuff) == "table")
assert(type(stuff.password) == "string")
assert(type(stuff.privileges) == "table")
end
local file, errmsg = io.open(minetest.auth_file_path, 'w+b')
if not file then
error(minetest.auth_file_path.." could not be opened for writing: "..errmsg)
end
for name, stuff in pairs(minetest.auth_table) do
local privstring = minetest.privs_to_string(stuff.privileges)
file:write(name..":"..stuff.password..":"..privstring..'\n')
end
io.close(file)
end
read_auth_file()
minetest.builtin_auth_handler = {
get_auth = function(name)
assert(type(name) == "string")
-- Figure out what password to use for a new player (singleplayer
-- always has an empty password, otherwise use default, which is
-- usually empty too)
local new_password_hash = ""
-- If not in authentication table, return nil
if not minetest.auth_table[name] then
return nil
end
-- Figure out what privileges the player should have.
-- Take a copy of the privilege table
local privileges = {}
for priv, _ in pairs(minetest.auth_table[name].privileges) do
privileges[priv] = true
end
-- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
if minetest.is_singleplayer() then
for priv, def in pairs(minetest.registered_privileges) do
if def.give_to_singleplayer then
privileges[priv] = true
end
end
-- For the admin, give everything
elseif name == minetest.setting_get("name") then
for priv, def in pairs(minetest.registered_privileges) do
privileges[priv] = true
end
end
-- All done
return {
password = minetest.auth_table[name].password,
privileges = privileges,
}
end,
create_auth = function(name, password)
assert(type(name) == "string")
assert(type(password) == "string")
minetest.log('info', "Built-in authentication handler adding player '"..name.."'")
minetest.auth_table[name] = {
password = password,
privileges = minetest.string_to_privs(minetest.setting_get("default_privs")),
}
save_auth_file()
end,
set_password = function(name, password)
assert(type(name) == "string")
assert(type(password) == "string")
if not minetest.auth_table[name] then
minetest.builtin_auth_handler.create_auth(name, password)
else
minetest.log('info', "Built-in authentication handler setting password of player '"..name.."'")
minetest.auth_table[name].password = password
save_auth_file()
end
return true
end,
set_privileges = function(name, privileges)
assert(type(name) == "string")
assert(type(privileges) == "table")
if not minetest.auth_table[name] then
minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password")))
end
minetest.auth_table[name].privileges = privileges
minetest.notify_authentication_modified(name)
save_auth_file()
end,
reload = function()
read_auth_file()
return true
end,
}
function minetest.register_authentication_handler(handler)
if minetest.registered_auth_handler then
error("Add-on authentication handler already registered by "..minetest.registered_auth_handler_modname)
end
minetest.registered_auth_handler = handler
minetest.registered_auth_handler_modname = minetest.get_current_modname()
end
function minetest.get_auth_handler()
if minetest.registered_auth_handler then
return minetest.registered_auth_handler
end
return minetest.builtin_auth_handler
end
function minetest.set_player_password(name, password)
if minetest.get_auth_handler().set_password then
minetest.get_auth_handler().set_password(name, password)
end
end
function minetest.set_player_privs(name, privs)
if minetest.get_auth_handler().set_privileges then
minetest.get_auth_handler().set_privileges(name, privs)
end
end
function minetest.auth_reload()
if minetest.get_auth_handler().reload then
return minetest.get_auth_handler().reload()
end
return false
end

23
builtin/builtin.lua Normal file
View File

@ -0,0 +1,23 @@
--
-- This file contains built-in stuff in Minetest implemented in Lua.
--
-- It is always loaded and executed after registration of the C API,
-- before loading and running any mods.
--
-- Initialize some very basic things
print = minetest.debug
math.randomseed(os.time())
-- Load other files
dofile(minetest.get_modpath("__builtin").."/misc_helpers.lua")
dofile(minetest.get_modpath("__builtin").."/item.lua")
dofile(minetest.get_modpath("__builtin").."/misc_register.lua")
dofile(minetest.get_modpath("__builtin").."/item_entity.lua")
dofile(minetest.get_modpath("__builtin").."/deprecated.lua")
dofile(minetest.get_modpath("__builtin").."/misc.lua")
dofile(minetest.get_modpath("__builtin").."/privileges.lua")
dofile(minetest.get_modpath("__builtin").."/auth.lua")
dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")

352
builtin/chatcommands.lua Normal file
View File

@ -0,0 +1,352 @@
-- Minetest: builtin/chatcommands.lua
--
-- Chat command handler
--
minetest.chatcommands = {}
function minetest.register_chatcommand(cmd, def)
def = def or {}
def.params = def.params or ""
def.description = def.description or ""
def.privs = def.privs or {}
minetest.chatcommands[cmd] = def
end
minetest.register_on_chat_message(function(name, message)
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
if not param then
param = ""
end
local cmd_def = minetest.chatcommands[cmd]
if cmd_def then
if not cmd_def.func then
-- This is a C++ command
return false
else
local has_privs, missing_privs = minetest.check_player_privs(name, cmd_def.privs)
if has_privs then
cmd_def.func(name, param)
else
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
end
return true -- handled chat message
end
end
return false
end)
--
-- Chat commands
--
-- Register C++ commands without functions
minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)"})
minetest.register_chatcommand("status", {description = "print server status line"})
minetest.register_chatcommand("shutdown", {params = "", description = "shutdown server", privs = {server=true}})
minetest.register_chatcommand("clearobjects", {params = "", description = "clear all objects in world", privs = {server=true}})
minetest.register_chatcommand("time", {params = "<0...24000>", description = "set time of day", privs = {settime=true}})
minetest.register_chatcommand("ban", {params = "<name>", description = "ban IP of player", privs = {ban=true}})
minetest.register_chatcommand("unban", {params = "<name/ip>", description = "remove IP ban", privs = {ban=true}})
-- Register other commands
minetest.register_chatcommand("help", {
privs = {},
params = "(nothing)/all/privs/<cmd>",
description = "Get help for commands or list privileges",
func = function(name, param)
local format_help_line = function(cmd, def)
local msg = "/"..cmd
if def.params and def.params ~= "" then msg = msg .. " " .. def.params end
if def.description and def.description ~= "" then msg = msg .. ": " .. def.description end
return msg
end
if param == "" then
local msg = ""
cmds = {}
for cmd, def in pairs(minetest.chatcommands) do
if minetest.check_player_privs(name, def.privs) then
table.insert(cmds, cmd)
end
end
minetest.chat_send_player(name, "Available commands: "..table.concat(cmds, " "))
minetest.chat_send_player(name, "Use '/help <cmd>' to get more information, or '/help all' to list everything.")
elseif param == "all" then
minetest.chat_send_player(name, "Available commands:")
for cmd, def in pairs(minetest.chatcommands) do
if minetest.check_player_privs(name, def.privs) then
minetest.chat_send_player(name, format_help_line(cmd, def))
end
end
elseif param == "privs" then
minetest.chat_send_player(name, "Available privileges:")
for priv, def in pairs(minetest.registered_privileges) do
minetest.chat_send_player(name, priv..": "..def.description)
end
else
local cmd = param
def = minetest.chatcommands[cmd]
if not def then
minetest.chat_send_player(name, "Command not available: "..cmd)
else
minetest.chat_send_player(name, format_help_line(cmd, def))
end
end
end,
})
minetest.register_chatcommand("privs", {
params = "<name>",
description = "print out privileges of player",
func = function(name, param)
if param == "" then
param = name
else
if not minetest.check_player_privs(name, {privs=true}) then
minetest.chat_send_player(name, "Privileges of "..param.." are hidden from you.")
end
end
minetest.chat_send_player(name, "Privileges of "..param..": "..minetest.privs_to_string(minetest.get_player_privs(param), ' '))
end,
})
minetest.register_chatcommand("grant", {
params = "<name> <privilege>|all",
description = "Give privilege to player",
privs = {},
func = function(name, param)
if not minetest.check_player_privs(name, {privs=true}) and
not minetest.check_player_privs(name, {basic_privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
if not grantname or not grantprivstr then
minetest.chat_send_player(name, "Invalid parameters (see /help grant)")
return
end
local grantprivs = minetest.string_to_privs(grantprivstr)
if grantprivstr == "all" then
grantprivs = minetest.registered_privileges
end
local privs = minetest.get_player_privs(grantname)
local privs_known = true
for priv, _ in pairs(grantprivs) do
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
if not minetest.registered_privileges[priv] then
minetest.chat_send_player(name, "Unknown privilege: "..priv)
privs_known = false
end
privs[priv] = true
end
if not privs_known then
return
end
minetest.set_player_privs(grantname, privs)
minetest.chat_send_player(name, "Privileges of "..grantname..": "..minetest.privs_to_string(minetest.get_player_privs(grantname), ' '))
if grantname ~= name then
minetest.chat_send_player(grantname, name.." granted you privileges: "..minetest.privs_to_string(grantprivs, ' '))
end
end,
})
minetest.register_chatcommand("revoke", {
params = "<name> <privilege>|all",
description = "Remove privilege from player",
privs = {},
func = function(name, param)
if not minetest.check_player_privs(name, {privs=true}) and
not minetest.check_player_privs(name, {basic_privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)")
if not revokename or not revokeprivstr then
minetest.chat_send_player(name, "Invalid parameters (see /help revoke)")
return
end
local revokeprivs = minetest.string_to_privs(revokeprivstr)
local privs = minetest.get_player_privs(revokename)
for priv, _ in pairs(revokeprivs) do
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
end
if revokeprivstr == "all" then
privs = {}
else
for priv, _ in pairs(revokeprivs) do
privs[priv] = nil
end
end
minetest.set_player_privs(revokename, privs)
minetest.chat_send_player(name, "Privileges of "..revokename..": "..minetest.privs_to_string(minetest.get_player_privs(revokename), ' '))
if revokename ~= name then
minetest.chat_send_player(revokename, name.." revoked privileges from you: "..minetest.privs_to_string(revokeprivs, ' '))
end
end,
})
minetest.register_chatcommand("setpassword", {
params = "<name> <password>",
description = "set given password",
privs = {password=true},
func = function(name, param)
if param == "" then
minetest.chat_send_player(name, "Password field required")
return
end
minetest.set_player_password(name, param)
minetest.chat_send_player(name, "Password set")
end,
})
minetest.register_chatcommand("clearpassword", {
params = "<name>",
description = "set empty password",
privs = {password=true},
func = function(name, param)
minetest.set_player_password(name, '')
minetest.chat_send_player(name, "Password cleared")
end,
})
minetest.register_chatcommand("auth_reload", {
params = "",
description = "reload authentication data",
privs = {server=true},
func = function(name, param)
local done = minetest.auth_reload()
if done then
minetest.chat_send_player(name, "Done.")
else
minetest.chat_send_player(name, "Failed.")
end
end,
})
minetest.register_chatcommand("teleport", {
params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
description = "teleport to given position",
privs = {teleport=true},
func = function(name, param)
-- Returns (pos, true) if found, otherwise (pos, false)
local function find_free_position_near(pos)
local tries = {
{x=1,y=0,z=0},
{x=-1,y=0,z=0},
{x=0,y=0,z=1},
{x=0,y=0,z=-1},
}
for _, d in ipairs(tries) do
local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z}
local n = minetest.env:get_node(p)
if not minetest.registered_nodes[n.name].walkable then
return p, true
end
end
return pos, false
end
local teleportee = nil
local p = {}
p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
teleportee = minetest.env:get_player_by_name(name)
if teleportee and p.x and p.y and p.z then
minetest.chat_send_player(name, "Teleporting to ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
local teleportee = nil
local p = nil
local target_name = nil
target_name = string.match(param, "^([^ ]+)$")
teleportee = minetest.env:get_player_by_name(name)
if target_name then
local target = minetest.env:get_player_by_name(target_name)
if target then
p = target:getpos()
end
end
if teleportee and p then
p = find_free_position_near(p)
minetest.chat_send_player(name, "Teleporting to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
if minetest.check_player_privs(name, {bring=true}) then
local teleportee = nil
local p = {}
local teleportee_name = nil
teleportee_name, p.x, p.y, p.z = string.match(param, "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
if teleportee_name then
teleportee = minetest.env:get_player_by_name(teleportee_name)
end
if teleportee and p.x and p.y and p.z then
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
local teleportee = nil
local p = nil
local teleportee_name = nil
local target_name = nil
teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$")
if teleportee_name then
teleportee = minetest.env:get_player_by_name(teleportee_name)
end
if target_name then
local target = minetest.env:get_player_by_name(target_name)
if target then
p = target:getpos()
end
end
if teleportee and p then
p = find_free_position_near(p)
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
end
minetest.chat_send_player(name, "Invalid parameters (\""..param.."\") or player not found (see /help teleport)")
return
end,
})
minetest.register_chatcommand("set", {
params = "[-n] <name> <value> | <name>",
description = "set or read server configuration setting",
privs = {server=true},
func = function(name, param)
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
if arg and arg == "-n" and setname and setvalue then
minetest.setting_set(setname, setvalue)
minetest.chat_send_player(name, setname.." = "..setvalue)
return
end
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
if setname and setvalue then
if not minetest.setting_get(setname) then
minetest.chat_send_player(name, "Failed. Use '/set -n <name> <value>' to create a new setting.")
return
end
minetest.setting_set(setname, setvalue)
minetest.chat_send_player(name, setname.." = "..setvalue)
return
end
local setname = string.match(param, "([^ ]+)")
if setname then
local setvalue = minetest.setting_get(setname)
if not setvalue then
setvalue = "<not set>"
end
minetest.chat_send_player(name, setname.." = "..setvalue)
return
end
minetest.chat_send_player(name, "Invalid parameters (see /help set)")
end,
})

19
builtin/deprecated.lua Normal file
View File

@ -0,0 +1,19 @@
-- Minetest: builtin/deprecated.lua
--
-- Default material types
--
function digprop_err()
minetest.log("info", debug.traceback())
minetest.log("info", "WARNING: The minetest.digprop_* functions are obsolete and need to be replaced by item groups.")
end
minetest.digprop_constanttime = digprop_err
minetest.digprop_stonelike = digprop_err
minetest.digprop_dirtlike = digprop_err
minetest.digprop_gravellike = digprop_err
minetest.digprop_woodlike = digprop_err
minetest.digprop_leaveslike = digprop_err
minetest.digprop_glasslike = digprop_err

397
builtin/item.lua Normal file
View File

@ -0,0 +1,397 @@
-- Minetest: builtin/item.lua
--
-- Item definition helpers
--
function minetest.inventorycube(img1, img2, img3)
img2 = img2 or img1
img3 = img3 or img1
return "[inventorycube"
.. "{" .. img1:gsub("%^", "&")
.. "{" .. img2:gsub("%^", "&")
.. "{" .. img3:gsub("%^", "&")
end
function minetest.get_pointed_thing_position(pointed_thing, above)
if pointed_thing.type == "node" then
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
elseif pointed_thing.type == "object" then
obj = pointed_thing.ref
if obj ~= nil then
return obj:getpos()
else
return nil
end
else
return nil
end
end
function minetest.dir_to_facedir(dir)
if math.abs(dir.x) > math.abs(dir.z) then
if dir.x < 0 then
return 3
else
return 1
end
else
if dir.z < 0 then
return 2
else
return 0
end
end
end
function minetest.dir_to_wallmounted(dir)
if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
if dir.y < 0 then
return 1
else
return 0
end
elseif math.abs(dir.x) > math.abs(dir.z) then
if dir.x < 0 then
return 3
else
return 2
end
else
if dir.z < 0 then
return 5
else
return 4
end
end
end
function minetest.get_node_drops(nodename, toolname)
local drop = ItemStack({name=nodename}):get_definition().drop
if drop == nil then
-- default drop
return {ItemStack({name=nodename})}
elseif type(drop) == "string" then
-- itemstring drop
return {ItemStack(drop)}
elseif drop.items == nil then
-- drop = {} to disable default drop
return {}
end
-- Extended drop table
local got_items = {}
local got_count = 0
local _, item, tool
for _, item in ipairs(drop.items) do
local good_rarity = true
local good_tool = true
if item.rarity ~= nil then
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
end
if item.tools ~= nil then
good_tool = false
for _, tool in ipairs(item.tools) do
if tool:sub(1, 1) == '~' then
good_tool = toolname:find(tool:sub(2)) ~= nil
else
good_tool = toolname == tool
end
if good_tool then
break
end
end
end
if good_rarity and good_tool then
got_count = got_count + 1
for _, add_item in ipairs(item.items) do
got_items[#got_items+1] = add_item
end
if drop.max_items ~= nil and got_count == drop.max_items then
break
end
end
end
return got_items
end
function minetest.item_place_node(itemstack, placer, pointed_thing)
local item = itemstack:peek_item()
local def = itemstack:get_definition()
if def.type == "node" and pointed_thing.type == "node" then
local pos = pointed_thing.above
local oldnode = minetest.env:get_node(pos)
local olddef = ItemStack({name=oldnode.name}):get_definition()
if not olddef.buildable_to then
minetest.log("info", placer:get_player_name() .. " tried to place"
.. " node in invalid position " .. minetest.pos_to_string(pos)
.. ", replacing " .. oldnode.name)
return
end
minetest.log("action", placer:get_player_name() .. " places node "
.. def.name .. " at " .. minetest.pos_to_string(pos))
local newnode = {name = def.name, param1 = 0, param2 = 0}
-- Calculate direction for wall mounted stuff like torches and signs
if def.paramtype2 == 'wallmounted' then
local under = pointed_thing.under
local above = pointed_thing.above
local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
newnode.param2 = minetest.dir_to_wallmounted(dir)
-- Calculate the direction for furnaces and chests and stuff
elseif def.paramtype2 == 'facedir' then
local playerpos = placer:getpos()
local dir = {x = pos.x - playerpos.x, y = pos.y - playerpos.y, z = pos.z - playerpos.z}
newnode.param2 = minetest.dir_to_facedir(dir)
minetest.log("action", "facedir: " .. newnode.param2)
end
-- Add node and update
minetest.env:add_node(pos, newnode)
-- Set metadata owner
if def.metadata_name ~= "" then
minetest.env:get_meta(pos):set_owner(placer:get_player_name())
end
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_placenodes) do
callback(pos, newnode, placer)
end
itemstack:take_item()
end
return itemstack
end
function minetest.item_place_object(itemstack, placer, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
if pos ~= nil then
local item = itemstack:take_item()
minetest.env:add_item(pos, item)
end
return itemstack
end
function minetest.item_place(itemstack, placer, pointed_thing)
if itemstack:get_definition().type == "node" then
return minetest.item_place_node(itemstack, placer, pointed_thing)
else
return minetest.item_place_object(itemstack, placer, pointed_thing)
end
end
function minetest.item_drop(itemstack, dropper, pos)
if dropper and dropper:get_player_name() ~= nil then
local v = dropper:get_look_dir()
local p = {x=pos.x+v.x, y=pos.y+1.5+v.y, z=pos.z+v.z}
local obj = minetest.env:add_item(p, itemstack)
v.x = v.x*2
v.y = v.y*2 + 2
v.z = v.z*2
obj:setvelocity(v)
else
minetest.env:add_item(pos, itemstack)
end
return ""
end
function minetest.item_eat(hp_change, hunger_change, replace_with_item)
return function(itemstack, user, pointed_thing) -- closure
if itemstack:take_item() ~= nil then
user:set_hp(user:get_hp() + hp_change)
user:set_hunger(user:get_hunger() + hunger_change)
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
end
return itemstack
end
end
function minetest.node_punch(pos, node, puncher)
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_punchnodes) do
callback(pos, node, puncher)
end
end
function minetest.node_dig(pos, node, digger)
minetest.debug("node_dig")
local def = ItemStack({name=node.name}):get_definition()
if not def.diggable then
minetest.debug("not diggable")
minetest.log("info", digger:get_player_name() .. " tried to dig "
.. node.name .. " which is not diggable "
.. minetest.pos_to_string(pos))
return
end
local meta = minetest.env:get_meta(pos)
if meta ~= nil and not meta:get_allow_removal() then
minetest.debug("dig prevented by metadata")
minetest.log("info", digger:get_player_name() .. " tried to dig "
.. node.name .. ", but removal is disabled by metadata "
.. minetest.pos_to_string(pos))
return
end
minetest.log('action', digger:get_player_name() .. " digs "
.. node.name .. " at " .. minetest.pos_to_string(pos))
if not minetest.setting_getbool("creative_mode") then
local wielded = digger:get_wielded_item()
local drops = minetest.get_node_drops(node.name, wielded:get_name())
-- Wear out tool
tp = wielded:get_tool_capabilities()
dp = minetest.get_dig_params(def.groups, tp)
wielded:add_wear(dp.wear)
digger:set_wielded_item(wielded)
-- Add dropped items
local _, dropped_item
for _, dropped_item in ipairs(drops) do
minetest.item_drop(dropped_item, nil, pos)
end
end
-- Remove node and update
minetest.env:remove_node(pos)
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_dignodes) do
callback(pos, node, digger)
end
end
-- This is used to allow mods to redefine minetest.item_place and so on
local function redef_wrapper(table, name)
return function(...)
return table[name](...)
end
end
--
-- Item definition defaults
--
minetest.nodedef_default = {
-- Item properties
type="node",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
usable = false,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
on_use = nil,
on_punch = redef_wrapper(minetest, 'node_punch'), -- minetest.node_punch
on_dig = redef_wrapper(minetest, 'node_dig'), -- minetest.node_dig
-- Node properties
drawtype = "normal",
visual_scale = 1.0,
tile_images = {""},
special_materials = {
{image="", backface_culling=true},
{image="", backface_culling=true},
},
alpha = 255,
post_effect_color = {a=0, r=0, g=0, b=0},
paramtype = "none",
paramtype2 = "none",
is_ground_content = false,
sunlight_propagates = false,
walkable = true,
pointable = true,
diggable = true,
climbable = false,
buildable_to = false,
metadata_name = "",
liquidtype = "none",
liquid_alternative_flowing = "",
liquid_alternative_source = "",
liquid_viscosity = 0,
light_source = 0,
damage_per_second = 0,
selection_box = {type="regular"},
legacy_facedir_simple = false,
legacy_wallmounted = false,
}
minetest.craftitemdef_default = {
type="craft",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
on_use = nil,
}
minetest.tooldef_default = {
type="tool",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 1,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
on_use = nil,
}
minetest.noneitemdef_default = { -- This is used for the hand and unknown items
type="none",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = nil,
on_drop = nil,
on_use = nil,
}

148
builtin/item_entity.lua Normal file
View File

@ -0,0 +1,148 @@
-- Minetest: builtin/item_entity.lua
function minetest.spawn_item(pos, item)
-- Take item in any format
local stack = ItemStack(item)
local obj = minetest.env:add_entity(pos, "__builtin:item")
obj:get_luaentity():set_item(stack:to_string())
return obj
end
minetest.register_entity("__builtin:item", {
initial_properties = {
hp_max = 1,
physical = true,
collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17},
visual = "sprite",
visual_size = {x=0.5, y=0.5},
textures = {""},
spritediv = {x=1, y=1},
initial_sprite_basepos = {x=0, y=0},
is_visible = false,
pointable = false,
},
itemstring = '',
physical_state = true,
dontbugme = true,
outercircle = 2.0,
innercircle = 0.5,
gravity = true,
whocaresaboutnodes = false,
lastplayer = false,
set_item = function(self, itemstring)
self.itemstring = itemstring
local stack = ItemStack(itemstring)
local itemtable = stack:to_table()
local itemname = nil
if itemtable then
itemname = stack:to_table().name
end
local item_texture = nil
local item_type = ""
if minetest.registered_items[itemname] then
item_texture = minetest.registered_items[itemname].inventory_image
item_type = minetest.registered_items[itemname].type
end
prop = {
is_visible = true,
visual = "sprite",
textures = {"unknown_item.png"}
}
prop.visual = "wielditem"
prop.textures = {itemname}
prop.visual_size = {x=0.20, y=0.20}
prop.automatic_rotate = math.pi * 0.25
self.object:set_properties(prop)
end,
get_staticdata = function(self)
return self.itemstring
end,
on_activate = function(self, staticdata)
self.itemstring = staticdata
self.object:set_armor_groups({immortal=1})
self.object:setvelocity({x=math.random(-1.5,1.5), y=0, z=math.random(-1.5,1.5)})
self.object:setacceleration({x=0, y=-10, z=0})
self:set_item(self.itemstring)
end,
on_step = function(self, dtime)
local p = self.object:getpos()
p.y = p.y - 0.3
local nn = minetest.env:get_node(p).name
if minetest.registered_nodes[nn].walkable and self.whocaresaboutnodes == false then
if self.physical_state then
self.object:setvelocity({x=0, y=0, z=0})
self.object:setacceleration({x=0, y=0, z=0})
self.physical_state = false
self.object:set_properties({
physical = false
})
self.dontbugme = false
end
else
if not self.physical_state and self.gravity == true then
self.object:setvelocity({x=0, y=0, z=0})
self.object:setacceleration({x=0, y=-10, z=0})
self.physical_state = true
self.object:set_properties({
physical = true
})
self.dontbugme = true
end
end
local pos = p
local objs = minetest.env:get_objects_inside_radius(pos, self.innercircle)
local objs2 = minetest.env:get_objects_inside_radius(pos, self.outercircle)
for k, obj in pairs(objs) do
local objpos=obj:getpos()
if objpos.y >= pos.y-1.5 and objpos.y <= pos.y+.5 then
if obj:get_player_name() ~= nil then
if self.itemstring ~= '' then
obj:get_inventory():add_item("main", self.itemstring)
soundfile = "pop"
minetest.sound_play(soundfile, {gain=0.2})
end
self.object:remove()
end
end
end
local playerfound = false
for k, obj in pairs(objs2) do
local objpos=obj:getpos()
if obj:get_player_name() ~= nil and objpos.y >= pos.y-1.25 and objpos.y <= pos.y+.25 then
playerfound = true
if self.dontbugme == false then
self.lastplayer = true
local fx = objpos.x - pos.x
local fy = objpos.y - pos.y
local fz = objpos.z - pos.z
self.gravity = false
self.physical_state = false
self.object:set_properties({
physical = false
})
self.object:setvelocity({x=fx * 5, y=fy * 5, z=fz * 5})
self.dontbugme = true
self.whocaresaboutnodes = true
end
end
end
if playerfound == false then
if self.lastplayer == true then
self.lastplayer = false
self.object:setvelocity({x=0, y=0, z=0})
self.object:setacceleration({x=0, y=-10, z=0})
end
self.gravity = true
self.physical_state = true
self.object:set_properties({
physical = true
})
self.whocaresaboutnodes = false
end
end,
})

101
builtin/misc.lua Normal file
View File

@ -0,0 +1,101 @@
-- Minetest: builtin/misc.lua
--
-- Misc. API functions
--
minetest.timers_to_add = {}
minetest.timers = {}
minetest.register_globalstep(function(dtime)
for _, timer in ipairs(minetest.timers_to_add) do
table.insert(minetest.timers, timer)
end
minetest.timers_to_add = {}
for index, timer in ipairs(minetest.timers) do
timer.time = timer.time - dtime
if timer.time <= 0 then
timer.func(timer.param)
table.remove(minetest.timers,index)
end
end
end)
function minetest.after(time, func, param)
table.insert(minetest.timers_to_add, {time=time, func=func, param=param})
end
function minetest.check_player_privs(name, privs)
local player_privs = minetest.get_player_privs(name)
local missing_privileges = {}
for priv, val in pairs(privs) do
if val then
if not player_privs[priv] then
table.insert(missing_privileges, priv)
end
end
end
if #missing_privileges > 0 then
return false, missing_privileges
end
return true, ""
end
function minetest.get_connected_players()
-- This could be optimized a bit, but leave that for later
local list = {}
for _, obj in pairs(minetest.env:get_objects_inside_radius({x=0,y=0,z=0}, 1000000)) do
if obj:get_player_name() then
table.insert(list, obj)
end
end
return list
end
function minetest.hash_node_position(pos)
return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
end
function minetest.get_item_group(name, group)
if not minetest.registered_items[name] or not
minetest.registered_items[name].groups[group] then
return 0
end
return minetest.registered_items[name].groups[group]
end
function minetest.get_node_group(name, group)
return minetest.get_item_group(name, group)
end
function minetest.string_to_pos(value)
local p = {}
p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
if p.x and p.y and p.z then
p.x = tonumber(p.x)
p.y = tonumber(p.y)
p.z = tonumber(p.z)
return p
end
local p = {}
p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$")
if p.x and p.y and p.z then
p.x = tonumber(p.x)
p.y = tonumber(p.y)
p.z = tonumber(p.z)
return p
end
return nil
end
assert(minetest.string_to_pos("10.0, 5, -2").x == 10)
assert(minetest.string_to_pos("( 10.0, 5, -2)").z == -2)
assert(minetest.string_to_pos("asd, 5, -2)") == nil)
function minetest.setting_get_pos(name)
local value = minetest.setting_get(name)
if not value then
return nil
end
return minetest.string_to_pos(value)
end

94
builtin/misc_helpers.lua Normal file
View File

@ -0,0 +1,94 @@
-- Minetest: builtin/misc_helpers.lua
function basic_dump2(o)
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
elseif type(o) == "boolean" then
return tostring(o)
elseif type(o) == "function" then
return "<function>"
elseif type(o) == "userdata" then
return "<userdata>"
elseif type(o) == "nil" then
return "nil"
else
error("cannot dump a " .. type(o))
return nil
end
end
function dump2(o, name, dumped)
name = name or "_"
dumped = dumped or {}
io.write(name, " = ")
if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
or type(o) == "function" or type(o) == "nil"
or type(o) == "userdata" then
io.write(basic_dump2(o), "\n")
elseif type(o) == "table" then
if dumped[o] then
io.write(dumped[o], "\n")
else
dumped[o] = name
io.write("{}\n") -- new table
for k,v in pairs(o) do
local fieldname = string.format("%s[%s]", name, basic_dump2(k))
dump2(v, fieldname, dumped)
end
end
else
error("cannot dump a " .. type(o))
return nil
end
end
function dump(o, dumped)
dumped = dumped or {}
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
elseif type(o) == "table" then
if dumped[o] then
return "<circular reference>"
end
dumped[o] = true
local t = {}
for k,v in pairs(o) do
t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
end
return "{" .. table.concat(t, ", ") .. "}"
elseif type(o) == "boolean" then
return tostring(o)
elseif type(o) == "function" then
return "<function>"
elseif type(o) == "userdata" then
return "<userdata>"
elseif type(o) == "nil" then
return "nil"
else
error("cannot dump a " .. type(o))
return nil
end
end
function string:split(sep)
local sep, fields = sep or ",", {}
local pattern = string.format("([^%s]+)", sep)
self:gsub(pattern, function(c) fields[#fields+1] = c end)
return fields
end
function string:trim()
return (self:gsub("^%s*(.-)%s*$", "%1"))
end
assert(string.trim("\n \t\tfoo bar\t ") == "foo bar")
function minetest.pos_to_string(pos)
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
end

315
builtin/misc_register.lua Normal file
View File

@ -0,0 +1,315 @@
-- Minetest: builtin/misc_register.lua
--
-- Make raw registration functions inaccessible to anyone except this file
--
local register_item_raw = minetest.register_item_raw
minetest.register_item_raw = nil
local register_alias_raw = minetest.register_alias_raw
minetest.register_item_raw = nil
--
-- Item / entity / ABM registration functions
--
minetest.registered_abms = {}
minetest.registered_entities = {}
minetest.registered_items = {}
minetest.registered_nodes = {}
minetest.registered_craftitems = {}
minetest.registered_tools = {}
minetest.registered_aliases = {}
minetest.registered_crafts = {}
-- For tables that are indexed by item name:
-- If table[X] does not exist, default to table[minetest.registered_aliases[X]]
local function set_alias_metatable(table)
setmetatable(table, {
__index = function(name)
return rawget(table, minetest.registered_aliases[name])
end
})
end
set_alias_metatable(minetest.registered_items)
set_alias_metatable(minetest.registered_nodes)
set_alias_metatable(minetest.registered_craftitems)
set_alias_metatable(minetest.registered_tools)
-- These item names may not be used because they would interfere
-- with legacy itemstrings
local forbidden_item_names = {
MaterialItem = true,
MaterialItem2 = true,
MaterialItem3 = true,
NodeItem = true,
node = true,
CraftItem = true,
craft = true,
MBOItem = true,
ToolItem = true,
tool = true,
}
local function check_modname_prefix(name)
if name:sub(1,1) == ":" then
-- Escape the modname prefix enforcement mechanism
return name:sub(2)
else
-- Modname prefix enforcement
local expected_prefix = minetest.get_current_modname() .. ":"
if name:sub(1, #expected_prefix) ~= expected_prefix then
error("Name " .. name .. " does not follow naming conventions: " ..
"\"modname:\" or \":\" prefix required")
end
local subname = name:sub(#expected_prefix+1)
if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
error("Name " .. name .. " does not follow naming conventions: " ..
"contains unallowed characters")
end
return name
end
end
function minetest.register_abm(spec)
-- Add to minetest.registered_abms
minetest.registered_abms[#minetest.registered_abms+1] = spec
end
function minetest.register_entity(name, prototype)
-- Check name
if name == nil then
error("Unable to register entity: Name is nil")
end
name = check_modname_prefix(tostring(name))
prototype.name = name
prototype.__index = prototype -- so that it can be used as a metatable
-- Add to minetest.registered_entities
minetest.registered_entities[name] = prototype
end
function minetest.register_item(name, itemdef)
-- Check name
if name == nil then
error("Unable to register item: Name is nil")
end
name = check_modname_prefix(tostring(name))
if forbidden_item_names[name] then
error("Unable to register item: Name is forbidden: " .. name)
end
itemdef.name = name
-- Apply defaults and add to registered_* table
if itemdef.type == "node" then
setmetatable(itemdef, {__index = minetest.nodedef_default})
minetest.registered_nodes[itemdef.name] = itemdef
elseif itemdef.type == "craft" then
setmetatable(itemdef, {__index = minetest.craftitemdef_default})
minetest.registered_craftitems[itemdef.name] = itemdef
elseif itemdef.type == "tool" then
setmetatable(itemdef, {__index = minetest.tooldef_default})
minetest.registered_tools[itemdef.name] = itemdef
elseif itemdef.type == "none" then
setmetatable(itemdef, {__index = minetest.noneitemdef_default})
else
error("Unable to register item: Type is invalid: " .. dump(itemdef))
end
-- Flowing liquid uses param2
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
itemdef.paramtype2 = "flowingliquid"
end
-- BEGIN Legacy stuff
if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then
minetest.register_craft({
type="cooking",
output=itemdef.cookresult_itemstring,
recipe=itemdef.name,
cooktime=itemdef.furnace_cooktime
})
end
if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then
minetest.register_craft({
type="fuel",
recipe=itemdef.name,
burntime=itemdef.furnace_burntime
})
end
-- END Legacy stuff
-- Disable all further modifications
getmetatable(itemdef).__newindex = {}
--minetest.log("Registering item: " .. itemdef.name)
minetest.registered_items[itemdef.name] = itemdef
minetest.registered_aliases[itemdef.name] = nil
register_item_raw(itemdef)
end
function minetest.register_node(name, nodedef)
nodedef.type = "node"
minetest.register_item(name, nodedef)
end
function minetest.register_craftitem(name, craftitemdef)
craftitemdef.type = "craft"
-- BEGIN Legacy stuff
if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then
craftitemdef.inventory_image = craftitemdef.image
end
-- END Legacy stuff
minetest.register_item(name, craftitemdef)
end
function minetest.register_tool(name, tooldef)
tooldef.type = "tool"
tooldef.stack_max = 1
-- BEGIN Legacy stuff
if tooldef.inventory_image == nil and tooldef.image ~= nil then
tooldef.inventory_image = tooldef.image
end
if tooldef.tool_capabilities == nil and
(tooldef.full_punch_interval ~= nil or
tooldef.basetime ~= nil or
tooldef.dt_weight ~= nil or
tooldef.dt_crackiness ~= nil or
tooldef.dt_crumbliness ~= nil or
tooldef.dt_cuttability ~= nil or
tooldef.basedurability ~= nil or
tooldef.dd_weight ~= nil or
tooldef.dd_crackiness ~= nil or
tooldef.dd_crumbliness ~= nil or
tooldef.dd_cuttability ~= nil) then
tooldef.tool_capabilities = {
full_punch_interval = tooldef.full_punch_interval,
basetime = tooldef.basetime,
dt_weight = tooldef.dt_weight,
dt_crackiness = tooldef.dt_crackiness,
dt_crumbliness = tooldef.dt_crumbliness,
dt_cuttability = tooldef.dt_cuttability,
basedurability = tooldef.basedurability,
dd_weight = tooldef.dd_weight,
dd_crackiness = tooldef.dd_crackiness,
dd_crumbliness = tooldef.dd_crumbliness,
dd_cuttability = tooldef.dd_cuttability,
}
end
-- END Legacy stuff
minetest.register_item(name, tooldef)
end
function minetest.register_alias(name, convert_to)
if forbidden_item_names[name] then
error("Unable to register alias: Name is forbidden: " .. name)
end
if minetest.registered_items[name] ~= nil then
minetest.log("WARNING: Not registering alias, item with same name" ..
" is already defined: " .. name .. " -> " .. convert_to)
else
--minetest.log("Registering alias: " .. name .. " -> " .. convert_to)
minetest.registered_aliases[name] = convert_to
register_alias_raw(name, convert_to)
end
end
-- Alias the forbidden item names to "" so they can't be
-- created via itemstrings (e.g. /give)
local name
for name in pairs(forbidden_item_names) do
minetest.registered_aliases[name] = ""
register_alias_raw(name, "")
end
-- Deprecated:
-- Aliases for minetest.register_alias (how ironic...)
--minetest.alias_node = minetest.register_alias
--minetest.alias_tool = minetest.register_alias
--minetest.alias_craftitem = minetest.register_alias
--
-- Built-in node definitions. Also defined in C.
--
minetest.register_item(":unknown", {
type = "none",
description = "Unknown Item",
inventory_image = "unknown_item.png",
on_place = minetest.item_place,
on_drop = minetest.item_drop,
})
minetest.register_node(":air", {
description = "Air (you hacker you!)",
inventory_image = "unknown_block.png",
wield_image = "unknown_block.png",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
air_equivalent = true,
})
minetest.register_node(":ignore", {
description = "Ignore (you hacker you!)",
inventory_image = "unknown_block.png",
wield_image = "unknown_block.png",
drawtype = "airlike",
paramtype = "none",
sunlight_propagates = false,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true, -- A way to remove accidentally placed ignores
air_equivalent = true,
})
-- The hand (bare definition)
minetest.register_item(":", {
type = "none",
})
--
-- Creative inventory
--
minetest.creative_inventory = {}
minetest.add_to_creative_inventory = function(itemstring)
table.insert(minetest.creative_inventory, itemstring)
end
--
-- Callback registration
--
local function make_registration()
local t = {}
local registerfunc = function(func) table.insert(t, func) end
return t, registerfunc
end
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registration()
minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
minetest.registered_on_joinplayers, minetest.register_on_joinplayer = make_registration()
minetest.registered_on_leaveplayers, minetest.register_on_leaveplayer = make_registration()

48
builtin/privileges.lua Normal file
View File

@ -0,0 +1,48 @@
-- Minetest: builtin/privileges.lua
--
-- Privileges
--
minetest.registered_privileges = {}
function minetest.register_privilege(name, param)
local function fill_defaults(def)
if def.give_to_singleplayer == nil then
def.give_to_singleplayer = true
end
if def.description == nil then
def.description = "(no description)"
end
end
local def = {}
if type(param) == "table" then
def = param
else
def = {description = param}
end
fill_defaults(def)
minetest.registered_privileges[name] = def
end
minetest.register_privilege("interact", "Can interact with things and modify the world")
minetest.register_privilege("teleport", "Can use /teleport command")
minetest.register_privilege("bring", "Can teleport other players")
minetest.register_privilege("settime", "Can use /time")
minetest.register_privilege("privs", "Can modify privileges")
minetest.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
minetest.register_privilege("server", "Can do server maintenance stuff")
minetest.register_privilege("shout", "Can speak in chat")
minetest.register_privilege("ban", "Can ban and unban players")
minetest.register_privilege("give", "Can use /give and /giveme")
minetest.register_privilege("password", "Can use /setpassword and /clearpassword")
minetest.register_privilege("fly", {
description = "Can fly using the free_move mode",
give_to_singleplayer = false,
})
minetest.register_privilege("fast", {
description = "Can walk fast using the fast_move mode",
give_to_singleplayer = false,
})

33
builtin/static_spawn.lua Normal file
View File

@ -0,0 +1,33 @@
-- Minetest: builtin/static_spawn.lua
local function warn_invalid_static_spawnpoint()
if minetest.setting_get("static_spawnpoint") and
not minetest.setting_get_pos("static_spawnpoint") then
minetest.log('error', "The static_spawnpoint setting is invalid: \""..
minetest.setting_get("static_spawnpoint").."\"")
end
end
warn_invalid_static_spawnpoint()
local function put_player_in_spawn(obj)
warn_invalid_static_spawnpoint()
local static_spawnpoint = minetest.setting_get_pos("static_spawnpoint")
if not static_spawnpoint then
return false
end
minetest.log('action', "Moving "..obj:get_player_name()..
" to static spawnpoint at "..
minetest.pos_to_string(static_spawnpoint))
obj:setpos(static_spawnpoint)
return true
end
minetest.register_on_newplayer(function(obj)
put_player_in_spawn(obj)
end)
minetest.register_on_respawnplayer(function(obj)
return put_player_in_spawn(obj)
end)

View File

@ -0,0 +1,32 @@
# - Find CURL
# Find the native CURL includes and libraries
#
# CURL_INCLUDE_DIR - where to find vorbis.h, etc.
# CURL_LIBRARIES - List of libraries when using vorbis(file).
# CURL_FOUND - True if vorbis found.
if(NOT GP2XWIZ)
if(CURL_INCLUDE_DIR)
# Already in cache, be silent
set(CURL_FIND_QUIETLY TRUE)
endif(CURL_INCLUDE_DIR)
find_library(CURL_LIBRARY NAMES curl)
# Handle the QUIETLY and REQUIRED arguments and set VORBIS_FOUND
# to TRUE if all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CURL DEFAULT_MSG CURL_INCLUDE_DIR CURL_LIBRARY)
else(NOT GP2XWIZ)
find_package_handle_standard_args(VORBIS DEFAULT_MSG
CURL_INCLUDE_DIR CURL_LIBRARY)
endif(NOT GP2XWIZ)
if(CURL_FOUND)
if(NOT GP2XWIZ)
set(CURL_LIBRARY ${CURL_LIBRARY})
else(NOT GP2XWIZ)
set(CURL_LIBRARY ${CURL_LIBRARY})
endif(NOT GP2XWIZ)
else(CURL_FOUND)
set(CURL_LIBRARY)
endif(CURL_FOUND)

View File

@ -0,0 +1,72 @@
# Package finder for gettext libs and include files
SET(CUSTOM_GETTEXT_PATH "${PROJECT_SOURCE_DIR}/../../gettext"
CACHE FILEPATH "path to custom gettext")
# by default
SET(GETTEXT_FOUND FALSE)
FIND_PATH(GETTEXT_INCLUDE_DIR
NAMES libintl.h
PATHS "${CUSTOM_GETTEXT_PATH}/include"
DOC "gettext include directory")
FIND_PROGRAM(GETTEXT_MSGFMT
NAMES msgfmt
PATHS "${CUSTOM_GETTEXT_PATH}/bin"
DOC "path to msgfmt")
# modern Linux, as well as Mac, seem to not need require special linking
# they do not because gettext is part of glibc
# TODO check the requirements on other BSDs and older Linux
IF (WIN32)
IF(MSVC)
SET(GETTEXT_LIB_NAMES
libintl.lib intl.lib libintl3.lib intl3.lib)
ELSE()
SET(GETTEXT_LIB_NAMES
libintl.dll.a intl.dll.a libintl3.dll.a intl3.dll.a)
ENDIF()
FIND_LIBRARY(GETTEXT_LIBRARY
NAMES ${GETTEXT_LIB_NAMES}
PATHS "${CUSTOM_GETTEXT_PATH}/lib"
DOC "gettext *intl*.lib")
FIND_FILE(GETTEXT_DLL
NAMES libintl.dll intl.dll libintl3.dll intl3.dll
PATHS "${CUSTOM_GETTEXT_PATH}/bin" "${CUSTOM_GETTEXT_PATH}/lib"
DOC "gettext *intl*.dll")
FIND_FILE(GETTEXT_ICONV_DLL
NAMES libiconv2.dll
PATHS "${CUSTOM_GETTEXT_PATH}/bin" "${CUSTOM_GETTEXT_PATH}/lib"
DOC "gettext *iconv*.lib")
ENDIF(WIN32)
IF(GETTEXT_INCLUDE_DIR AND GETTEXT_MSGFMT)
IF (WIN32)
# in the Win32 case check also for the extra linking requirements
IF(GETTEXT_LIBRARY AND GETTEXT_DLL AND GETTEXT_ICONV_DLL)
SET(GETTEXT_FOUND TRUE)
ENDIF()
ELSE(WIN32)
# *BSD variants require special linkage as they don't use glibc
IF(${CMAKE_SYSTEM_NAME} MATCHES "BSD")
SET(GETTEXT_LIBRARY "intl")
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "BSD")
SET(GETTEXT_FOUND TRUE)
ENDIF(WIN32)
ENDIF()
IF(GETTEXT_FOUND)
SET(GETTEXT_PO_PATH ${CMAKE_SOURCE_DIR}/po)
SET(GETTEXT_MO_BUILD_PATH ${CMAKE_BINARY_DIR}/locale/<locale>/LC_MESSAGES)
SET(GETTEXT_MO_DEST_PATH ${LOCALEDIR}/<locale>/LC_MESSAGES)
FILE(GLOB GETTEXT_AVAILABLE_LOCALES RELATIVE ${GETTEXT_PO_PATH} "${GETTEXT_PO_PATH}/*")
LIST(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES minetest.pot)
MACRO(SET_MO_PATHS _buildvar _destvar _locale)
STRING(REPLACE "<locale>" ${_locale} ${_buildvar} ${GETTEXT_MO_BUILD_PATH})
STRING(REPLACE "<locale>" ${_locale} ${_destvar} ${GETTEXT_MO_DEST_PATH})
ENDMACRO(SET_MO_PATHS)
ELSE()
SET(GETTEXT_INCLUDE_DIR "")
SET(GETTEXT_LIBRARY "")
ENDIF()

View File

@ -0,0 +1,94 @@
#FindIrrlicht.cmake
set(IRRLICHT_SOURCE_DIR "" CACHE PATH "Path to irrlicht source directory (optional)")
if( UNIX )
# Unix
else( UNIX )
# Windows
endif( UNIX )
# Find include directory
if(NOT IRRLICHT_SOURCE_DIR STREQUAL "")
set(IRRLICHT_SOURCE_DIR_INCLUDE
"${IRRLICHT_SOURCE_DIR}/include"
)
set(IRRLICHT_LIBRARY_NAMES libIrrlicht.a Irrlicht Irrlicht.lib)
if(WIN32)
if(MSVC)
set(IRRLICHT_SOURCE_DIR_LIBS "${IRRLICHT_SOURCE_DIR}/lib/Win32-visualstudio")
set(IRRLICHT_LIBRARY_NAMES Irrlicht.lib)
else()
set(IRRLICHT_SOURCE_DIR_LIBS "${IRRLICHT_SOURCE_DIR}/lib/Win32-gcc")
set(IRRLICHT_LIBRARY_NAMES libIrrlicht.a libIrrlicht.dll.a)
endif()
else()
set(IRRLICHT_SOURCE_DIR_LIBS "${IRRLICHT_SOURCE_DIR}/lib/Linux")
set(IRRLICHT_LIBRARY_NAMES libIrrlicht.a)
endif()
FIND_PATH(IRRLICHT_INCLUDE_DIR NAMES irrlicht.h
PATHS
${IRRLICHT_SOURCE_DIR_INCLUDE}
NO_DEFAULT_PATH
)
FIND_LIBRARY(IRRLICHT_LIBRARY NAMES ${IRRLICHT_LIBRARY_NAMES}
PATHS
${IRRLICHT_SOURCE_DIR_LIBS}
NO_DEFAULT_PATH
)
else()
FIND_PATH(IRRLICHT_INCLUDE_DIR NAMES irrlicht.h
PATHS
/usr/local/include/irrlicht
/usr/include/irrlicht
)
FIND_LIBRARY(IRRLICHT_LIBRARY NAMES libIrrlicht.a Irrlicht
PATHS
/usr/local/lib
/usr/lib
)
endif()
MESSAGE(STATUS "IRRLICHT_SOURCE_DIR = ${IRRLICHT_SOURCE_DIR}")
MESSAGE(STATUS "IRRLICHT_INCLUDE_DIR = ${IRRLICHT_INCLUDE_DIR}")
MESSAGE(STATUS "IRRLICHT_LIBRARY = ${IRRLICHT_LIBRARY}")
# On windows, find the dll for installation
if(WIN32)
if(MSVC)
FIND_FILE(IRRLICHT_DLL NAMES Irrlicht.dll
PATHS
"${IRRLICHT_SOURCE_DIR}/bin/Win32-VisualStudio"
DOC "Path of the Irrlicht dll (for installation)"
)
else()
FIND_FILE(IRRLICHT_DLL NAMES Irrlicht.dll
PATHS
"${IRRLICHT_SOURCE_DIR}/bin/Win32-gcc"
DOC "Path of the Irrlicht dll (for installation)"
)
endif()
MESSAGE(STATUS "IRRLICHT_DLL = ${IRRLICHT_DLL}")
endif(WIN32)
# handle the QUIETLY and REQUIRED arguments and set IRRLICHT_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(IRRLICHT DEFAULT_MSG IRRLICHT_LIBRARY IRRLICHT_INCLUDE_DIR)
IF(IRRLICHT_FOUND)
SET(IRRLICHT_LIBRARIES ${IRRLICHT_LIBRARY})
ELSE(IRRLICHT_FOUND)
SET(IRRLICHT_LIBRARIES)
ENDIF(IRRLICHT_FOUND)
MARK_AS_ADVANCED(IRRLICHT_LIBRARY IRRLICHT_INCLUDE_DIR IRRLICHT_DLL)

View File

@ -0,0 +1,18 @@
# Look for jthread, use our own if not found
FIND_PATH(JTHREAD_INCLUDE_DIR jthread.h)
FIND_LIBRARY(JTHREAD_LIBRARY NAMES jthread)
IF(JTHREAD_LIBRARY AND JTHREAD_INCLUDE_DIR)
SET( JTHREAD_FOUND TRUE )
ENDIF(JTHREAD_LIBRARY AND JTHREAD_INCLUDE_DIR)
IF(JTHREAD_FOUND)
MESSAGE(STATUS "Found system jthread header file in ${JTHREAD_INCLUDE_DIR}")
MESSAGE(STATUS "Found system jthread library ${JTHREAD_LIBRARY}")
ELSE(JTHREAD_FOUND)
SET(JTHREAD_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/jthread)
SET(JTHREAD_LIBRARY jthread)
MESSAGE(STATUS "Using project jthread library")
ENDIF(JTHREAD_FOUND)

View File

@ -0,0 +1,18 @@
# Look for sqlite3, use our own if not found
FIND_PATH(SQLITE3_INCLUDE_DIR sqlite3.h)
FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite3)
IF(SQLITE3_LIBRARY AND SQLITE3_INCLUDE_DIR)
SET( SQLITE3_FOUND TRUE )
ENDIF(SQLITE3_LIBRARY AND SQLITE3_INCLUDE_DIR)
IF(SQLITE3_FOUND)
MESSAGE(STATUS "Found system sqlite3 header file in ${SQLITE3_INCLUDE_DIR}")
MESSAGE(STATUS "Found system sqlite3 library ${SQLITE3_LIBRARY}")
ELSE(SQLITE3_FOUND)
SET(SQLITE3_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/sqlite)
SET(SQLITE3_LIBRARY sqlite3)
MESSAGE(STATUS "Using project sqlite3 library")
ENDIF(SQLITE3_FOUND)

View File

@ -0,0 +1,46 @@
# - Find vorbis
# Find the native vorbis includes and libraries
#
# VORBIS_INCLUDE_DIR - where to find vorbis.h, etc.
# OGG_INCLUDE_DIR - where to find ogg/ogg.h, etc.
# VORBIS_LIBRARIES - List of libraries when using vorbis(file).
# VORBIS_FOUND - True if vorbis found.
if(NOT GP2XWIZ)
if(VORBIS_INCLUDE_DIR)
# Already in cache, be silent
set(VORBIS_FIND_QUIETLY TRUE)
endif(VORBIS_INCLUDE_DIR)
find_path(OGG_INCLUDE_DIR ogg/ogg.h)
find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h)
# MSVC built ogg/vorbis may be named ogg_static and vorbis_static
find_library(OGG_LIBRARY NAMES ogg ogg_static)
find_library(VORBIS_LIBRARY NAMES vorbis vorbis_static)
find_library(VORBISFILE_LIBRARY NAMES vorbisfile vorbisfile_static)
# Handle the QUIETLY and REQUIRED arguments and set VORBIS_FOUND
# to TRUE if all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(VORBIS DEFAULT_MSG
OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR
OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY)
else(NOT GP2XWIZ)
find_path(VORBIS_INCLUDE_DIR tremor/ivorbisfile.h)
find_library(VORBIS_LIBRARY NAMES vorbis_dec)
find_package_handle_standard_args(VORBIS DEFAULT_MSG
VORBIS_INCLUDE_DIR VORBIS_LIBRARY)
endif(NOT GP2XWIZ)
if(VORBIS_FOUND)
if(NOT GP2XWIZ)
set(VORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY}
${OGG_LIBRARY})
else(NOT GP2XWIZ)
set(VORBIS_LIBRARIES ${VORBIS_LIBRARY})
endif(NOT GP2XWIZ)
else(VORBIS_FOUND)
set(VORBIS_LIBRARIES)
endif(VORBIS_FOUND)
mark_as_advanced(OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR)
mark_as_advanced(OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY)

21
cmake/Modules/misc.cmake Normal file
View File

@ -0,0 +1,21 @@
#
# Random macros
#
# Not used ATM
MACRO (GETDATETIME RESULT)
IF (WIN32)
EXECUTE_PROCESS(COMMAND "cmd" /C echo %date% %time% OUTPUT_VARIABLE ${RESULT})
string(REGEX REPLACE "\n" "" ${RESULT} "${${RESULT}}")
ELSEIF(UNIX)
EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d_%H:%M:%S" OUTPUT_VARIABLE ${RESULT})
string(REGEX REPLACE "\n" "" ${RESULT} "${${RESULT}}")
ELSE (WIN32)
MESSAGE(SEND_ERROR "date not implemented")
SET(${RESULT} "Unknown")
ENDIF (WIN32)
string(REGEX REPLACE " " "_" ${RESULT} "${${RESULT}}")
ENDMACRO (GETDATETIME)

339
doc/gpl-2.0.txt Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU 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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

1044
doc/lua_api.txt Normal file

File diff suppressed because it is too large Load Diff

549
doc/mapformat.txt Normal file
View File

@ -0,0 +1,549 @@
=================================================
Minetest World Format used as of 0.4.dev-20120322
=================================================
This applies to a world format carrying the block serialization version 22
which is used at least in version 0.4.dev-20120322.
The block serialization version used is 22. It does not fully specify every
aspect of this format; if compliance with this format is to be checked, it
needs to be done by detecting if the files and data indeed follows it.
Legacy stuff
=============
Data can, in theory, be contained in the flat file directory structure
described below in Version 17, but it is not officially supported. Also you
may stumble upon all kinds of oddities in not-so-recent formats.
Files
======
Everything is contained in a directory, the name of which is freeform, but
often serves as the name of the world.
Currently the authentication and ban data is stored on a per-world basis. It
can be copied over from an old world to a newly created world.
World
|-- auth.txt ----- Authentication data
|-- env_meta.txt - Environment metadata
|-- ipban.txt ---- Banned ips/users
|-- map_meta.txt - Map metadata
|-- map.sqlite --- Map data
|-- players ------ Player directory
| |-- player1 -- Player file
| '-- Foo ------ Player file
`-- world.mt ----- World metadata
auth.txt
---------
Contains authentication data, player per line.
<name>:<password hash>:<privilege1,...>
Format of password hash is <name><password> SHA1'd, in the base64 encoding.
Example lines:
- Player "celeron55", no password, privileges "interact" and "shout":
celeron55::interact,shout
- Player "Foo", password "bar", privilege "shout":
foo:iEPX+SQWIR3p67lj/0zigSWTKHg:shout
- Player "bar", no password, no privileges:
bar::
env_meta.txt
-------------
Simple global environment variables.
Example content (added indentation):
game_time = 73471
time_of_day = 19118
EnvArgsEnd
ipban.txt
----------
Banned IP addresses and usernames.
Example content (added indentation):
123.456.78.9|foo
123.456.78.10|bar
map_meta.txt
-------------
Simple global map variables.
Example content (added indentation):
seed = 7980462765762429666
[end_of_params]
map.sqlite
-----------
Map data.
See Map File Format below.
player1, Foo
-------------
Player data.
Filename can be anything.
See Player File Format below.
world.mt
---------
World metadata.
Example content (added indentation):
gameid = mesetint
Player File Format
===================
- Should be pretty self-explanatory.
- Note: position is in nodes * 10
Example content (added indentation):
hp = 11
name = celeron55
pitch = 39.77
position = (-5231.97,15,1961.41)
version = 1
yaw = 101.37
PlayerArgsEnd
List main 32
Item default:torch 13
Item default:pick_steel 1 50112
Item experimental:tnt
Item default:cobble 99
Item default:pick_stone 1 13104
Item default:shovel_steel 1 51838
Item default:dirt 61
Item default:rail 78
Item default:coal_lump 3
Item default:cobble 99
Item default:leaves 22
Item default:gravel 52
Item default:axe_steel 1 2045
Item default:cobble 98
Item default:sand 61
Item default:water_source 94
Item default:glass 2
Item default:mossycobble
Item default:pick_steel 1 64428
Item animalmaterials:bone
Item default:sword_steel
Item default:sapling
Item default:sword_stone 1 10647
Item default:dirt 99
Empty
Empty
Empty
Empty
Empty
Empty
Empty
Empty
EndInventoryList
List craft 9
Empty
Empty
Empty
Empty
Empty
Empty
Empty
Empty
Empty
EndInventoryList
List craftpreview 1
Empty
EndInventoryList
List craftresult 1
Empty
EndInventoryList
EndInventory
Map File Format
================
Minetest maps consist of MapBlocks, chunks of 16x16x16 nodes.
In addition to the bulk node data, MapBlocks stored on disk also contain
other things.
History
--------
We need a bit of history in here. Initially Minetest stored maps in a
format called the "sectors" format. It was a directory/file structure like
this:
sectors2/XXX/ZZZ/YYYY
For example, the MapBlock at (0,1,-2) was this file:
sectors2/000/ffd/0001
Eventually Minetest outgrow this directory structure, as filesystems were
struggling under the amount of files and directories.
Large servers seriously needed a new format, and thus the base of the
current format was invented, suggested by celeron55 and implemented by
JacobF.
SQLite3 was slammed in, and blocks files were directly inserted as blobs
in a single table, indexed by integer primary keys, oddly mangled from
coordinates.
Today we know that SQLite3 allows multiple primary keys (which would allow
storing coordinates separately), but the format has been kept unchanged for
that part. So, this is where it has come.
</history>
So here goes
-------------
map.sqlite is an sqlite3 database, containg a single table, called
"blocks". It looks like this:
CREATE TABLE `blocks` (`pos` INT NOT NULL PRIMARY KEY,`data` BLOB);
The key
--------
"pos" is created from the three coordinates of a MapBlock using this
algorithm, defined here in Python:
def getBlockAsInteger(p):
return int64(p[2]*16777216 + p[1]*4096 + p[0])
def int64(u):
while u >= 2**63:
u -= 2**64
while u <= -2**63:
u += 2**64
return u
It can be converted the other way by using this code:
def getIntegerAsBlock(i):
x = unsignedToSigned(i % 4096, 2048)
i = int((i - x) / 4096)
y = unsignedToSigned(i % 4096, 2048)
i = int((i - y) / 4096)
z = unsignedToSigned(i % 4096, 2048)
return x,y,z
def unsignedToSigned(i, max_positive):
if i < max_positive:
return i
else:
return i - 2*max_positive
The blob
---------
The blob is the data that would have otherwise gone into the file.
See below for description.
MapBlock serialization format
==============================
NOTE: Byte order is MSB first (big-endian).
NOTE: Zlib data is in such a format that Python's zlib at least can
directly decompress.
u8 version
- map format version number, this one is version 22
u8 flags
- Flag bitmasks:
- 0x01: is_underground: Should be set to 0 if there will be no light
obstructions above the block. If/when sunlight of a block is updated
and there is no block above it, this value is checked for determining
whether sunlight comes from the top.
- 0x02: day_night_differs: Whether the lighting of the block is different
on day and night. Only blocks that have this bit set are updated when
day transforms to night.
- 0x04: lighting_expired: If true, lighting is invalid and should be
updated. If you can't calculate lighting in your generator properly,
you could try setting this 1 to everything and setting the uppermost
block in every sector as is_underground=0. I am quite sure it doesn't
work properly, though.
- 0x08: generated: True if the block has been generated. If false, block
is mostly filled with CONTENT_IGNORE and is likely to contain eg. parts
of trees of neighboring blocks.
u8 content_width
- Number of bytes in the content (param0) fields of nodes
- Always 1
u8 params_width
- Number of bytes used for parameters per node
- Always 2
zlib-compressed node data:
- content:
u8[4096]: param0 fields
u8[4096]: param1 fields
u8[4096]: param2 fields
- The location of a node in each of those arrays is (z*16*16 + y*16 + x).
zlib-compressed node metadata list
- content:
u16 version (=1)
u16 count of metadata
foreach count:
u16 position (p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X)
u16 type_id
u16 content_size
u8[content_size] (content of metadata)
u16 mapblockobject_count
- Always 0
- Should be removed in version 23 (TODO)
u8 static object version:
- Always 0
u16 static_object_count
foreach static_object_count:
u8 type (object type-id)
s32 pos_x_nodes * 10000
s32 pos_y_nodes * 10000
s32 pos_z_nodes * 10000
u16 data_size
u8[data_size] data
u32 timestamp
- Timestamp when last saved, as seconds from starting the game.
- 0xffffffff = invalid/unknown timestamp, nothing should be done with the time
difference when loaded
u8 name-id-mapping version
- Always 0
u16 num_name_id_mappings
foreach num_name_id_mappings
u16 id
u16 name_len
u8[name_len] name
EOF.
Format of nodes
----------------
A node is composed of the u8 fields param0, param1 and param2.
The content id of a node is determined as so:
- If param0 < 0x80,
content_id = param0
- Otherwise
content_id = (param0<<4) + (param2>>4)
The purpose of param1 and param2 depend on the definition of the node.
The name-id-mapping
--------------------
The mapping maps node content ids to node names.
Node metadata format
---------------------
1: Generic metadata
serialized inventory
u32 len
u8[len] text
u16 len
u8[len] owner
u16 len
u8[len] infotext
u16 len
u8[len] inventory drawspec
u8 allow_text_input (bool)
u8 removal_disabled (bool)
u8 enforce_owner (bool)
u32 num_vars
foreach num_vars
u16 len
u8[len] name
u32 len
u8[len] value
14: Sign metadata
u16 text_len
u8[text_len] text
15: Chest metadata
serialized inventory
16: Furnace metadata
TBD
17: Locked Chest metadata
u16 len
u8[len] owner
serialized inventory
Static objects
---------------
Static objects are persistent freely moving objects in the world.
Object types:
1: Test object
2: Item
3: Rat (deprecated)
4: Oerkki (deprecated)
5: Firefly (deprecated)
6: MobV2 (deprecated)
7: LuaEntity
1: Item:
u8 version
version 0:
u16 len
u8[len] itemstring
7: LuaEntity:
u8 version
version 1:
u16 len
u8[len] entity name
u32 len
u8[len] static data
s16 hp
s32 velocity.x * 10000
s32 velocity.y * 10000
s32 velocity.z * 10000
s32 yaw * 1000
Itemstring format
------------------
eg. 'default:dirt 5'
eg. 'default:pick_wood 21323'
eg. '"default:apple" 2'
eg. 'default:apple'
- The wear value in tools is 0...65535
- There are also a number of older formats that you might stumble upon:
eg. 'node "default:dirt" 5'
eg. 'NodeItem default:dirt 5'
eg. 'ToolItem WPick 21323'
Inventory serialization format
-------------------------------
- The inventory serialization format is line-based
- The newline character used is "\n"
- The end condition of a serialized inventory is always "EndInventory\n"
- All the slots in a list must always be serialized.
Example (format does not include "---"):
---
List foo 4
Item default:sapling
Item default:sword_stone 1 10647
Item default:dirt 99
Empty
EndInventoryList
List bar 9
Empty
Empty
Empty
Empty
Empty
Empty
Empty
Empty
Empty
EndInventoryList
EndInventory
---
==============================================
Minetest World Format used as of 2011-05 or so
==============================================
Map data serialization format version 17.
0.3.1 does not use this format, but a more recent one. This exists here for
historical reasons.
Directory structure:
sectors/XXXXZZZZ or sectors2/XXX/ZZZ
XXXX, ZZZZ, XXX and ZZZ being the hexadecimal X and Z coordinates.
Under these, the block files are stored, called YYYY.
There also exists files map_meta.txt and chunk_meta, that are used by the
generator. If they are not found or invalid, the generator will currently
behave quite strangely.
The MapBlock file format (sectors2/XXX/ZZZ/YYYY):
-------------------------------------------------
NOTE: Byte order is MSB first.
u8 version
- map format version number, this one is version 17
u8 flags
- Flag bitmasks:
- 0x01: is_underground: Should be set to 0 if there will be no light
obstructions above the block. If/when sunlight of a block is updated and
there is no block above it, this value is checked for determining whether
sunlight comes from the top.
- 0x02: day_night_differs: Whether the lighting of the block is different on
day and night. Only blocks that have this bit set are updated when day
transforms to night.
- 0x04: lighting_expired: If true, lighting is invalid and should be updated.
If you can't calculate lighting in your generator properly, you could try
setting this 1 to everything and setting the uppermost block in every
sector as is_underground=0. I am quite sure it doesn't work properly,
though.
zlib-compressed map data:
- content:
u8[4096]: content types
u8[4096]: param1 values
u8[4096]: param2 values
zlib-compressed node metadata
- content:
u16 version (=1)
u16 count of metadata
foreach count:
u16 position (= p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X)
u16 type_id
u16 content_size
u8[content_size] misc. stuff contained in the metadata
u16 mapblockobject_count
- always write as 0.
- if read != 0, just fail.
foreach mapblockobject_count:
- deprecated, should not be used. Length of this data can only be known by
properly parsing it. Just hope not to run into any of this.
u8 static object version:
- currently 0
u16 static_object_count
foreach static_object_count:
u8 type (object type-id)
s32 pos_x * 1000
s32 pos_y * 1000
s32 pos_z * 1000
u16 data_size
u8[data_size] data
u32 timestamp
- Timestamp when last saved, as seconds from starting the game.
- 0xffffffff = invalid/unknown timestamp, nothing will be done with the time
difference when loaded (recommended)
Node metadata format:
---------------------
Sign metadata:
u16 string_len
u8[string_len] string
Furnace metadata:
TBD
Chest metadata:
TBD
Locking Chest metadata:
u16 string_len
u8[string_len] string
TBD
// END

91
doc/minetest.6 Normal file
View File

@ -0,0 +1,91 @@
.\" Minetest man page
.TH minetest 6 "11 March 2012" "" ""
.SH NAME
minetest \- Multiplayer infinite-world block sandbox
.SH SYNOPSIS
.B minetest
[ OPTION ... ]
.SH DESCRIPTION
.B Minetest
is one of the first InfiniMiner/Minecraft(/whatever) inspired games (started October 2010), with a goal of taking the survival multiplayer gameplay to a slightly different direction.
.PP
The main design philosophy is to keep it technically simple, stable and portable. It will be kept lightweight enough to run on fairly old hardware.
.SH OPTIONS
.TP
\-\-address <value>
Address to connect to
.TP
\-\-config <value>
Load configuration from specified file
.TP
\-\-disable\-unittests
Disable unit tests
.TP
\-\-enable\-unittests
Enable unit tests
.TP
\-\-gameid <value>
Set gameid
.TP
\-\-go
Disable main menu
.TP
\-\-help
Show allowed options
.TP
\-\-logfile <value>
Set logfile path (debug.txt)
.TP
\-\-map\-dir <value>
Same as --world (deprecated)
.TP
\-\-name <value>
Set player name
.TP
\-\-password <value>
Set password
.TP
\-\-port <value>
Set network port (UDP) to use
.TP
\-\-random\-input
Enable random user input, for testing
.TP
\-\-server
Run dedicated server
.TP
\-\-speedtests
Run speed tests
.TP
\-\-info
Print more information to console
.TP
\-\-verbose
Print even more information to console
.TP
\-\-trace
Print enormous amounts of information to console
.TP
\-\-world <value>
Set world path
.SH BUGS
Please report all bugs to Perttu Ahola <celeron55@gmail.com>.
.SH AUTHOR
.PP
Perttu Ahola <celeron55@gmail.com>
and contributors.
.PP
This man page was originally written by
Juhani Numminen <juhaninumminen0@gmail.com>.
.SH WWW
http://c55.me/minetest/
.SH "SEE ALSO"
.BR minetestserver(6)

70
doc/minetestserver.6 Normal file
View File

@ -0,0 +1,70 @@
.\" Minetestserver man page
.TH minetestserver 6 "11 March 2012" "" ""
.SH NAME
minetestserver \- Minetest server
.SH SYNOPSIS
.B minetestserver
[ OPTION ... ]
.SH DESCRIPTION
.B Minetest
is one of the first InfiniMiner/Minecraft(/whatever) inspired games (started October 2010), with a goal of taking the survival multiplayer gameplay to a slightly different direction.
.PP
The main design philosophy is to keep it technically simple, stable and portable. It will be kept lightweight enough to run on fairly old hardware.
.SH OPTIONS
.TP
\-\-config <value>
Load configuration from specified file
.TP
\-\-disable\-unittests
Disable unit tests
.TP
\-\-enable\-unittests
Enable unit tests
.TP
\-\-gameid <value>
Set gameid
.TP
\-\-help
Show allowed options
.TP
\-\-logfile <value>
Set logfile path (debug.txt)
.TP
\-\-map\-dir <value>
Same as --world (deprecated)
.TP
\-\-port <value>
Set network port (UDP) to use
.TP
\-\-info
Print more information to console
.TP
\-\-verbose
Print even more information to console
.TP
\-\-trace
Print enormous amounts of information to console
.TP
\-\-world <value>
Set world path
.SH BUGS
Please report all bugs to Perttu Ahola <celeron55@gmail.com>.
.SH AUTHOR
.PP
Perttu Ahola <celeron55@gmail.com>
and contributors.
.PP
This man page was originally written by
Juhani Numminen <juhaninumminen0@gmail.com>.
.SH WWW
http://c55.me/minetest/
.SH "SEE ALSO"
.BR minetest(6)

72
doc/protocol.txt Normal file
View File

@ -0,0 +1,72 @@
Minetest-c55 protocol (incomplete, early draft):
Updated 2011-06-18
A custom protocol over UDP.
Integers are big endian.
Refer to connection.{h,cpp} for further reference.
Initialization:
- A dummy reliable packet with peer_id=PEER_ID_INEXISTENT=0 is sent to the server:
- Actually this can be sent without the reliable packet header, too, i guess,
but the sequence number in the header allows the sender to re-send the
packet without accidentally getting a double initialization.
- Packet content:
# Basic header
u32 protocol_id = PROTOCOL_ID = 0x4f457403
u16 sender_peer_id = PEER_ID_INEXISTENT = 0
u8 channel = 0
# Reliable packet header
u8 type = TYPE_RELIABLE = 3
u16 seqnum = SEQNUM_INITIAL = 65500
# Original packet header
u8 type = TYPE_ORIGINAL = 1
# And no actual payload.
- Server responds with something like this:
- Packet content:
# Basic header
u32 protocol_id = PROTOCOL_ID = 0x4f457403
u16 sender_peer_id = PEER_ID_INEXISTENT = 0
u8 channel = 0
# Reliable packet header
u8 type = TYPE_RELIABLE = 3
u16 seqnum = SEQNUM_INITIAL = 65500
# Control packet header
u8 type = TYPE_CONTROL = 0
u8 controltype = CONTROLTYPE_SET_PEER_ID = 1
u16 peer_id_new = assigned peer id to client (other than 0 or 1)
- Then the connection can be disconnected by sending:
- Packet content:
# Basic header
u32 protocol_id = PROTOCOL_ID = 0x4f457403
u16 sender_peer_id = whatever was gotten in CONTROLTYPE_SET_PEER_ID
u8 channel = 0
# Control packet header
u8 type = TYPE_CONTROL = 0
u8 controltype = CONTROLTYPE_DISCO = 3
- Here's a quick untested connect-disconnect done in PHP:
# host: ip of server (use gethostbyname(hostname) to get from a dns name)
# port: port of server
function check_if_minetestserver_up($host, $port)
{
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$timeout = array("sec" => 1, "usec" => 0);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);
$buf = "\x4f\x45\x74\x03\x00\x00\x00\x03\xff\xdc\x01";
socket_sendto($socket, $buf, strlen($buf), 0, $host, $port);
$buf = socket_read($socket, 1000);
if($buf != "")
{
# We got a reply! read the peer id from it.
$peer_id = substr($buf, 9, 2);
# Disconnect
$buf = "\x4f\x45\x74\x03".$peer_id."\x00\x00\x03";
socket_sendto($socket, $buf, strlen($buf), 0, $host, $port);
socket_close($socket);
return true;
}
return false;
}

7
games/minetest/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
## Generic ignorable patterns and files
*~
.*.swp
*bak*
tags
*.vim

50
games/minetest/README.txt Normal file
View File

@ -0,0 +1,50 @@
The main game for the Minetest game engine [minetest_game]
==========================================================
To build the wholeness of the Minetest project, insert this repository as
/games/minetest_game
in the Minetest Engine.
The Minetest Engine can be found in:
https://github.com/celeron55/minetest/
Compatibility
--------------
The minetest_game github master HEAD is generally compatible with the github
master HEAD of minetest.
Additionally, when the minetest engine is tagged to be a certain version (eg.
0.4.dev-20120326), minetest_game is tagged with the version too.
When stable releases are made, minetest_game is packaged and made available in
https://github.com/celeron55/minetest_game/downloads
and in case the repository has grown too much, it may be reset. In that sense,
this is not a "real" git repository. (Package maintainers please note!)
License of source code
----------------------
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
See README.txt in each mod directory for information about other authors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU 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.
License of media (textures and sounds)
--------------------------------------
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
See README.txt in each mod directory for information about other authors.
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/

2
games/minetest/game.conf Normal file
View File

@ -0,0 +1,2 @@
name = Minetest

View File

@ -0,0 +1,26 @@
Minetest 0.4 mod: bucket
=========================
License of source code:
-----------------------
Copyright (C) 2011-2012 Kahrl <kahrl@gmx.net>
Copyright (C) 2011-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
http://www.gnu.org/licenses/gpl-2.0.html
License of media (textures and sounds)
--------------------------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/
Authors of media files
-----------------------
Everything not listed in here:
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>

View File

@ -0,0 +1,2 @@
default

View File

@ -0,0 +1,95 @@
-- Minetest 0.4 mod: bucket
-- See README.txt for licensing and other information.
minetest.register_alias("bucket", "bucket:bucket_empty")
minetest.register_alias("bucket_water", "bucket:bucket_water")
minetest.register_alias("bucket_lava", "bucket:bucket_lava")
minetest.register_craft({
output = 'bucket:bucket_empty 1',
recipe = {
{'default:steel_ingot', '', 'default:steel_ingot'},
{'', 'default:steel_ingot', ''},
}
})
bucket = {}
bucket.liquids = {}
-- Register a new liquid
-- source = name of the source node
-- flowing = name of the flowing node
-- itemname = name of the new bucket item (or nil if liquid is not takeable)
-- inventory_image = texture of the new bucket item (ignored if itemname == nil)
-- This function can be called from any mod (that depends on bucket).
function bucket.register_liquid(source, flowing, itemname, inventory_image)
bucket.liquids[source] = {
source = source,
flowing = flowing,
itemname = itemname,
}
bucket.liquids[flowing] = bucket.liquids[source]
if itemname ~= nil then
minetest.register_craftitem(itemname, {
inventory_image = inventory_image,
stack_max = 1,
liquids_pointable = true,
on_use = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
-- Check if pointing to a liquid
n = minetest.env:get_node(pointed_thing.under)
if bucket.liquids[n.name] == nil then
-- Not a liquid
minetest.env:add_node(pointed_thing.above, {name=source})
elseif n.name ~= source then
-- It's a liquid
minetest.env:add_node(pointed_thing.under, {name=source})
end
return {name="bucket:bucket_empty"}
end
})
end
end
minetest.register_craftitem("bucket:bucket_empty", {
inventory_image = "bucket.png",
stack_max = 1,
liquids_pointable = true,
on_use = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
-- Check if pointing to a liquid source
n = minetest.env:get_node(pointed_thing.under)
liquiddef = bucket.liquids[n.name]
if liquiddef ~= nil and liquiddef.source == n.name and liquiddef.itemname ~= nil then
minetest.env:add_node(pointed_thing.under, {name="air"})
return {name=liquiddef.itemname}
end
end,
})
bucket.register_liquid(
"default:water_source",
"default:water_flowing",
"bucket:bucket_water",
"bucket_water.png"
)
bucket.register_liquid(
"default:lava_source",
"default:lava_flowing",
"bucket:bucket_lava",
"bucket_lava.png"
)
minetest.register_craft({
type = "fuel",
recipe = "default:bucket_lava",
burntime = 60,
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

View File

@ -0,0 +1,108 @@
local function handle_give_command(cmd, giver, receiver, stackstring)
if not minetest.get_player_privs(giver)["give"] then
minetest.chat_send_player(giver, "error: you don't have permission to give")
return
end
minetest.debug("DEBUG: "..cmd..' invoked, stackstring="'..stackstring..'"')
minetest.log(cmd..' invoked, stackstring="'..stackstring..'"')
local itemstack = ItemStack(stackstring)
if itemstack:is_empty() then
minetest.chat_send_player(giver, 'error: cannot give an empty item')
return
elseif not itemstack:is_known() then
minetest.chat_send_player(giver, 'error: cannot give an unknown item')
return
end
local receiverref = minetest.env:get_player_by_name(receiver)
if receiverref == nil then
minetest.chat_send_player(giver, receiver..' is not a known player')
return
end
local leftover = receiverref:get_inventory():add_item("main", itemstack)
if leftover:is_empty() then
partiality = ""
elseif leftover:get_count() == itemstack:get_count() then
partiality = "could not be "
else
partiality = "partially "
end
-- The actual item stack string may be different from what the "giver"
-- entered (e.g. big numbers are always interpreted as 2^16-1).
stackstring = itemstack:to_string()
if giver == receiver then
minetest.chat_send_player(giver, '"'..stackstring
..'" '..partiality..'added to inventory.');
else
minetest.chat_send_player(giver, '"'..stackstring
..'" '..partiality..'added to '..receiver..'\'s inventory.');
minetest.chat_send_player(receiver, '"'..stackstring
..'" '..partiality..'added to inventory.');
end
end
minetest.register_on_chat_message(function(name, message)
--print("default on_chat_message: name="..dump(name).." message="..dump(message))
local cmd = "/giveme"
if message:sub(0, #cmd) == cmd then
local stackstring = string.match(message, cmd.." (.*)")
if stackstring == nil then
minetest.chat_send_player(name, 'usage: '..cmd..' stackstring')
return true -- Handled chat message
end
handle_give_command(cmd, name, name, stackstring)
return true
end
local cmd = "/give"
if message:sub(0, #cmd) == cmd then
local receiver, stackstring = string.match(message, cmd.." ([%a%d_-]+) (.*)")
if receiver == nil or stackstring == nil then
minetest.chat_send_player(name, 'usage: '..cmd..' name stackstring')
return true -- Handled chat message
end
handle_give_command(cmd, name, receiver, stackstring)
return true
end
local cmd = "/spawnentity"
if message:sub(0, #cmd) == cmd then
if not minetest.get_player_privs(name)["give"] then
minetest.chat_send_player(name, "you don't have permission to spawn (give)")
return true -- Handled chat message
end
if not minetest.get_player_privs(name)["interact"] then
minetest.chat_send_player(name, "you don't have permission to interact")
return true -- Handled chat message
end
local entityname = string.match(message, cmd.." (.*)")
if entityname == nil then
minetest.chat_send_player(name, 'usage: '..cmd..' entityname')
return true -- Handled chat message
end
print(cmd..' invoked, entityname="'..entityname..'"')
local player = minetest.env:get_player_by_name(name)
if player == nil then
print("Unable to spawn entity, player is nil")
return true -- Handled chat message
end
local p = player:getpos()
p.y = p.y + 1
minetest.env:add_entity(p, entityname)
minetest.chat_send_player(name, '"'..entityname
..'" spawned.');
return true -- Handled chat message
end
local cmd = "/pulverize"
if message:sub(0, #cmd) == cmd then
local player = minetest.env:get_player_by_name(name)
if player == nil then
print("Unable to pulverize, player is nil")
return true -- Handled chat message
end
if player:get_wielded_item():is_empty() then
minetest.chat_send_player(name, 'Unable to pulverize, no item in hand.')
else
player:set_wielded_item(nil)
minetest.chat_send_player(name, 'An item was pulverized.')
end
return true
end
end)

View File

@ -0,0 +1,70 @@
Minetest 0.4 mod: default
==========================
License of source code:
-----------------------
Copyright (C) 2011-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
http://www.gnu.org/licenses/gpl-2.0.html
License of media (textures and sounds)
--------------------------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/
Authors of media files
-----------------------
Everything not listed in here:
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
Originating from work by kddekadenz/Dogers:
default_grass_footstep.{1,2,3}.ogg
default_dig_crumbly.{1,2}.ogg
Popping sound:
http://www.youtube.com/watch?v=vJ507XRaslc
Minecraft textures:
http://minetest.net/forum/viewtopic.php?id=997
Cisoun's WTFPL texture pack:
default_chest_front.png
default_chest_lock.png
default_chest_side.png
default_chest_top.png
default_cobble.png
default_dirt.png
default_grass.png
default_grass_side.png
default_jungletree.png
default_jungletree_top.png
default_lava.png
default_leaves.png
default_mossycobble.png
default_sand.png
default_sapling.png
default_sign_wall.png
default_stone.png
default_tool_mesepick.png
default_tool_steelpick.png
default_tool_steelshovel.png
default_tool_steelsword.png
default_tool_stonepick.png
default_tool_stoneshovel.png
default_tool_woodpick.png
default_tool_woodshovel.png
default_tree.png
default_tree_top.png
default_water.png
Originating from G4JC's Almost MC Texture Pack:
default_wood.png
default_torch.png
default_torch_on_ceiling.png
default_torch_on_floor.png

View File

@ -0,0 +1,4 @@
-- Furnace (lkjoel)
-- Ported from minetest's C++ code

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
-- minetest/default/leafdecay.lua
-- To enable leaf decay for a node, add it to the "leafdecay" group.
--
-- The rating of the group determines how far from a node in the group "tree"
-- the node can be without decaying.
--
-- If param2 of the node is ~= 0, the node will always be preserved. Thus, if
-- the player places a node of that kind, you will want to set param2=1 or so.
default.leafdecay_trunk_cache = {}
default.leafdecay_enable_cache = true
-- Spread the load of finding trunks
default.leafdecay_trunk_find_allow_accumulator = 0
minetest.register_globalstep(function(dtime)
local finds_per_second = 5000
default.leafdecay_trunk_find_allow_accumulator =
math.floor(dtime * finds_per_second)
end)
minetest.register_abm({
nodenames = {"group:leafdecay"},
neighbors = {"air", "group:liquid"},
-- A low interval and a high inverse chance spreads the load
interval = 2,
chance = 5,
action = function(p0, node, _, _)
--print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")")
local do_preserve = false
local d = minetest.registered_nodes[node.name].groups.leafdecay
if not d or d == 0 then
--print("not groups.leafdecay")
return
end
local n0 = minetest.env:get_node(p0)
if n0.param2 ~= 0 then
--print("param2 ~= 0")
return
end
local p0_hash = nil
if default.leafdecay_enable_cache then
p0_hash = minetest.hash_node_position(p0)
local trunkp = default.leafdecay_trunk_cache[p0_hash]
if trunkp then
local n = minetest.env:get_node(trunkp)
local reg = minetest.registered_nodes[n.name]
-- Assume ignore is a trunk, to make the thing work at the border of the active area
if n.name == "ignore" or (reg.groups.tree and reg.groups.tree ~= 0) then
--print("cached trunk still exists")
return
end
--print("cached trunk is invalid")
-- Cache is invalid
table.remove(default.leafdecay_trunk_cache, p0_hash)
end
end
if default.leafdecay_trunk_find_allow_accumulator <= 0 then
return
end
default.leafdecay_trunk_find_allow_accumulator =
default.leafdecay_trunk_find_allow_accumulator - 1
-- Assume ignore is a trunk, to make the thing work at the border of the active area
local p1 = minetest.env:find_node_near(p0, d, {"ignore", "group:tree"})
if p1 then
do_preserve = true
if default.leafdecay_enable_cache then
--print("caching trunk")
-- Cache the trunk
default.leafdecay_trunk_cache[p0_hash] = p1
end
end
if not do_preserve then
-- Drop stuff other than the node itself
itemstacks = minetest.get_node_drops(n0.name)
for _, itemname in ipairs(itemstacks) do
if itemname ~= n0.name then
local p_drop = {
x = p0.x - 0.5 + math.random(),
y = p0.y - 0.5 + math.random(),
z = p0.z - 0.5 + math.random(),
}
minetest.env:add_item(p_drop, itemname)
end
end
-- Remove node
minetest.env:remove_node(p0)
end
end
})

View File

@ -0,0 +1,230 @@
-- minetest/default/mapgen.lua
--
-- Aliases for map generator outputs
--
minetest.register_alias("mapgen_air", "air")
minetest.register_alias("mapgen_stone", "default:stone")
minetest.register_alias("mapgen_tree", "default:tree")
minetest.register_alias("mapgen_jungletree", "default:jungletree")
minetest.register_alias("mapgen_leaves", "default:leaves")
minetest.register_alias("mapgen_apple", "default:apple")
minetest.register_alias("mapgen_water_source", "default:water_source")
minetest.register_alias("mapgen_dirt", "default:dirt")
minetest.register_alias("mapgen_sand", "default:sand")
minetest.register_alias("mapgen_gravel", "default:gravel")
minetest.register_alias("mapgen_clay", "default:clay")
minetest.register_alias("mapgen_lava_source", "default:lava_source")
minetest.register_alias("mapgen_cobble", "default:cobble")
minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
minetest.register_alias("mapgen_mese", "default:mese")
minetest.register_alias("mapgen_desert_sand", "default:desert_sand")
minetest.register_alias("mapgen_desert_stone", "default:desert_stone")
-- Nether stuff
minetest.register_alias("mapgen_netherrack", "nether:netherrack")
minetest.register_alias("mapgen_nether_tree", "nether:nether_tree")
minetest.register_alias("mapgen_nether_leaves", "nether:nether_leaves")
minetest.register_alias("mapgen_nether_apple", "nether:nether_apple")
minetest.register_alias("mapgen_nether_torch", "nether:nether_torch")
minetest.register_alias("mapgen_nether_glowstone", "nether:nether_glowstone")
--
-- Ore generation
--
local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume, ore_per_chunk, height_min, height_max)
if maxp.y < height_min or minp.y > height_max then
return
end
local y_min = math.max(minp.y, height_min)
local y_max = math.min(maxp.y, height_max)
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
local pr = PseudoRandom(seed)
local num_chunks = math.floor(chunks_per_volume * volume)
local chunk_size = 3
if ore_per_chunk <= 4 then
chunk_size = 2
end
local inverse_chance = math.floor(chunk_size*chunk_size*chunk_size / ore_per_chunk)
--print("generate_ore num_chunks: "..dump(num_chunks))
for i=1,num_chunks do
local y0 = pr:next(y_min, y_max-chunk_size+1)
if y0 >= height_min and y0 <= height_max then
local x0 = pr:next(minp.x, maxp.x-chunk_size+1)
local z0 = pr:next(minp.z, maxp.z-chunk_size+1)
local p0 = {x=x0, y=y0, z=z0}
for x1=0,chunk_size-1 do
for y1=0,chunk_size-1 do
for z1=0,chunk_size-1 do
if pr:next(1,inverse_chance) == 1 then
local x2 = x0+x1
local y2 = y0+y1
local z2 = z0+z1
local p2 = {x=x2, y=y2, z=z2}
if minetest.env:get_node(p2).name == wherein then
minetest.env:set_node(p2, {name=name})
end
end
end
end
end
end
end
--print("generate_ore done")
end
function default.make_papyrus(pos, size)
for y=0,size-1 do
local p = {x=pos.x, y=pos.y+y, z=pos.z}
minetest.env:set_node(p, {name="default:papyrus"})
end
end
function default.make_cactus(pos, size)
for y=0,size-1 do
local p = {x=pos.x, y=pos.y+y, z=pos.z}
minetest.env:set_node(p, {name="default:cactus"})
end
end
minetest.register_on_generated(function(minp, maxp, seed)
generate_ore("default:stone_with_coal", "default:stone", minp, maxp, seed, 1/8/8/8, 5, -31000, 64)
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+1, 1/16/16/16, 5, -5, 7)
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+2, 1/12/12/12, 5, -16, -5)
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+3, 1/9/9/9, 5, -31000, -17)
generate_ore("gun_powder:gun_stone", "default:stone", minp, maxp, seed+4, 1/9/9/9, 5, -31000, 64)
if maxp.y >= 2 and minp.y <= 0 then
-- Generate clay
-- Assume X and Z lengths are equal
local divlen = 4
local divs = (maxp.x-minp.x)/divlen+1;
for divx=0+1,divs-1-1 do
for divz=0+1,divs-1-1 do
local cx = minp.x + math.floor((divx+0.5)*divlen)
local cz = minp.z + math.floor((divz+0.5)*divlen)
if minetest.env:get_node({x=cx,y=1,z=cz}).name == "default:water_source" and
minetest.env:get_node({x=cx,y=0,z=cz}).name == "default:sand" then
local is_shallow = true
local num_water_around = 0
if minetest.env:get_node({x=cx-divlen*2,y=1,z=cz+0}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if minetest.env:get_node({x=cx+divlen*2,y=1,z=cz+0}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if minetest.env:get_node({x=cx+0,y=1,z=cz-divlen*2}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if minetest.env:get_node({x=cx+0,y=1,z=cz+divlen*2}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if num_water_around >= 2 then
is_shallow = false
end
if is_shallow then
for x1=-divlen,divlen do
for z1=-divlen,divlen do
if minetest.env:get_node({x=cx+x1,y=0,z=cz+z1}).name == "default:sand" then
minetest.env:set_node({x=cx+x1,y=0,z=cz+z1}, {name="default:clay"})
end
end
end
end
end
end
end
-- Generate papyrus
local perlin1 = minetest.env:get_perlin(354, 3, 0.7, 100)
-- Assume X and Z lengths are equal
local divlen = 8
local divs = (maxp.x-minp.x)/divlen+1;
for divx=0,divs-1 do
for divz=0,divs-1 do
local x0 = minp.x + math.floor((divx+0)*divlen)
local z0 = minp.z + math.floor((divz+0)*divlen)
local x1 = minp.x + math.floor((divx+1)*divlen)
local z1 = minp.z + math.floor((divz+1)*divlen)
-- Determine papyrus amount from perlin noise
local papyrus_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 45 - 20)
-- Find random positions for papyrus based on this random
local pr = PseudoRandom(seed+1)
for i=0,papyrus_amount do
local x = pr:next(x0, x1)
local z = pr:next(z0, z1)
if minetest.env:get_node({x=x,y=1,z=z}).name == "default:dirt_with_grass" and
minetest.env:find_node_near({x=x,y=1,z=z}, 1, "default:water_source") then
default.make_papyrus({x=x,y=2,z=z}, pr:next(2, 4))
end
end
end
end
-- Generate cactuses
local perlin1 = minetest.env:get_perlin(230, 3, 0.6, 100)
-- Assume X and Z lengths are equal
local divlen = 16
local divs = (maxp.x-minp.x)/divlen+1;
for divx=0,divs-1 do
for divz=0,divs-1 do
local x0 = minp.x + math.floor((divx+0)*divlen)
local z0 = minp.z + math.floor((divz+0)*divlen)
local x1 = minp.x + math.floor((divx+1)*divlen)
local z1 = minp.z + math.floor((divz+1)*divlen)
-- Determine cactus amount from perlin noise
local cactus_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 6 - 3)
-- Find random positions for cactus based on this random
local pr = PseudoRandom(seed+1)
for i=0,cactus_amount do
local x = pr:next(x0, x1)
local z = pr:next(z0, z1)
-- Find ground level (0...15)
local ground_y = nil
for y=30,0,-1 do
if minetest.env:get_node({x=x,y=y,z=z}).name ~= "air" then
ground_y = y
break
end
end
-- If desert sand, make cactus
if ground_y and minetest.env:get_node({x=x,y=ground_y,z=z}).name == "default:desert_sand" then
default.make_cactus({x=x,y=ground_y+1,z=z}, pr:next(3, 4))
end
end
end
end
-- Generate dry shrubs
local perlin1 = minetest.env:get_perlin(329, 3, 0.6, 100)
-- Assume X and Z lengths are equal
local divlen = 16
local divs = (maxp.x-minp.x)/divlen+1;
for divx=0,divs-1 do
for divz=0,divs-1 do
local x0 = minp.x + math.floor((divx+0)*divlen)
local z0 = minp.z + math.floor((divz+0)*divlen)
local x1 = minp.x + math.floor((divx+1)*divlen)
local z1 = minp.z + math.floor((divz+1)*divlen)
-- Determine cactus amount from perlin noise
local cactus_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 5 + 0)
-- Find random positions for cactus based on this random
local pr = PseudoRandom(seed+1)
for i=0,cactus_amount do
local x = pr:next(x0, x1)
local z = pr:next(z0, z1)
-- Find ground level (0...15)
local ground_y = nil
for y=30,0,-1 do
if minetest.env:get_node({x=x,y=y,z=z}).name ~= "air" then
ground_y = y
break
end
end
-- If desert sand, make cactus
if ground_y and minetest.env:get_node({x=x,y=ground_y,z=z}).name == "default:desert_sand" then
minetest.env:set_node({x=x,y=ground_y+1,z=z}, {name="default:dry_shrub"})
end
end
end
end
end
end)

View File

@ -0,0 +1,5 @@
[Dolphin]
AdditionalInfoV2=Details_Size,Details_Date,CustomizedDetails
Timestamp=2012,4,29,3,45,0
Version=2
ViewMode=1

View File

@ -0,0 +1,4 @@
Wood:
http://www.youtube.com/watch?v=u6UNjvQIurQ&feature=related
Grass and Dirt:
http://www.freesound.org/people/Snoman/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
[Dolphin]
AdditionalInfoV2=Details_Size,Details_Date,CustomizedDetails
Timestamp=2012,4,21,22,22,53
Version=2

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

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