Compare commits

...

5 Commits

Author SHA1 Message Date
SmallJoker e2f8f4da83
Formspecs: Close on metadata removal (#8348)
Formspecs will now close as soon the formspec string in the node metadata turns invalid.
2019-06-10 13:01:07 +02:00
SmallJoker e40be619f2
Add disable_jump to liquids and ladders (#7688)
Remove second nodedef check by improving the colliding node detection
Also remove the 2nd check in old_move, correct standing node a bit
2019-06-10 13:00:35 +02:00
adrido bd6f1cca9d Add compatibility to vcpkg buildsystem (#8317) 2019-06-10 02:56:55 +01:00
Thomas Rudin 9a07792f4d Save forceloaded blocks file periodically (#8535)
saves the forceloaded blocks periodically.
checks every 10 seconds if the forceloaded blocks got changed in-game
and persists them on-disk if that's the case
2019-06-10 01:07:33 +01:00
SmallJoker a687efa6df
Damage: Play no damage sound when immortal (#8350)
Add isImmortal server-side for proper enable_damage handling
Rework log messages
2019-06-09 11:25:41 +02:00
19 changed files with 388 additions and 376 deletions

206
README.md
View File

@ -284,165 +284,77 @@ Library specific options:
VORBIS_LIBRARY - Only if building with sound; path to libvorbis.a/libvorbis.so/libvorbis.dll.a VORBIS_LIBRARY - Only if building with sound; path to libvorbis.a/libvorbis.so/libvorbis.dll.a
XXF86VM_LIBRARY - Only on Linux; path to libXXf86vm.a/libXXf86vm.so XXF86VM_LIBRARY - Only on Linux; path to libXXf86vm.a/libXXf86vm.so
ZLIB_DLL - Only on Windows; path to zlib1.dll ZLIB_DLL - Only on Windows; path to zlib1.dll
ZLIBWAPI_DLL - Only on Windows; path to zlibwapi.dll
ZLIB_INCLUDE_DIR - Directory that contains zlib.h ZLIB_INCLUDE_DIR - Directory that contains zlib.h
ZLIB_LIBRARY - Path to libz.a/libz.so/zlibwapi.lib ZLIB_LIBRARY - Path to libz.a/libz.so/zlib.lib
### Compiling on Windows ### Compiling on Windows
* This section is outdated. In addition to what is described here: ### Requirements
* In addition to minetest, you need to download [minetest_game](https://github.com/minetest/minetest_game).
* If you wish to have sound support, you need libogg, libvorbis and libopenal
* You need: * Visual Studio 2015 or newer https://visualstudio.microsoft.com
* CMake: * CMake https://cmake.org/download/
http://www.cmake.org/cmake/resources/software.html * vcpkg https://github.com/Microsoft/vcpkg
* A compiler * git https://git-scm.com/downloads
* MinGW: http://www.mingw.org/
* or Visual Studio: 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
* SQLite3 headers and library
https://www.sqlite.org/download.html
* Optional: gettext library 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:
http://minetest.net/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
* NOTE: You need to extract sqlite3.h & sqlite3ext.h from the SQLite 3
source and sqlite3.dll & sqlite3.def from the SQLite 3 precompiled
binaries into "sqlite3" directory, and generate sqlite3.lib using
command "LIB /DEF:sqlite3.def /OUT:sqlite3.lib"
* 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, -=file):
-----------------
+ DIR
* zlib-1.2.5.tar.gz
* zlib125dll.zip
* irrlicht-1.8.3.zip
* sqlite-amalgamation-3130000.zip (SQLite3 headers)
* sqlite-dll-win32-x86-3130000.zip (SQLite3 library for 32bit system)
* 110214175330.zip (or whatever, this is the minetest source)
+ zlib-1.2.5
* zlib.h
+ win32
...
+ zlib125dll
* readme.txt
+ dll32
...
+ irrlicht-1.8.3
+ lib
+ include
...
+ sqlite3
sqlite3.h
sqlite3ext.h
sqlite3.lib
sqlite3.dll
+ 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] ### Compiling and Installing the dependencies
BUILD_SERVER [ ]
CMAKE_BUILD_TYPE Release
CMAKE_INSTALL_PREFIX DIR/minetest-install
IRRLICHT_SOURCE_DIR DIR/irrlicht-1.8.3
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
* If CMake complains it couldn't find SQLITE3, choose "Advanced" box on the It is highly recommended to use vcpkg as package manager.
right top corner, then specify the location of SQLITE3_INCLUDE_DIR and
SQLITE3_LIBRARY manually.
* If you want to build 64-bit minetest, you will need to build 64-bit version
of irrlicht engine manually, as only 32-bit pre-built library is provided.
* 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
### Bat script to build Windows releases of Minetest #### a) Using vcpkg to install dependencies
This is how we build Windows releases. After you successfully built vcpkg you can easily install the required libaries.
```powershell
vcpkg install irrlicht zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit --triplet x64-windows
```
`curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
set sourcedir=%CD% `openal-soft`, `libvorbis` and `libogg` are optional, but required to use sound.
set installpath="C:\tmp\minetest_install"
set irrlichtpath="C:\tmp\irrlicht-1.7.2"
set builddir=%sourcedir%\bvc10 `freetype` is optional, it allows true-type font rendering.
mkdir %builddir%
pushd %builddir%
cmake %sourcedir% -G "Visual Studio 10" -DIRRLICHT_SOURCE_DIR=%irrlichtpath% -DRUN_IN_PLACE=TRUE -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 `luajit` is optional and replaces the integrated lua interpreter with a faster just in time interpreter
popd
echo Failed. There are other libaries that are optional, but are not tested if they can build and linked correctly.
exit /b 1
`--triplet` specify the target triplet e.g. x64-windows x86-windows
#### b) Compile the dependencies on your own
This is outdated and not recommended. Follow the instructions on https://dev.minetest.net/Build_Win32_Minetest_including_all_required_libraries#VS2012_Build
### Compile Minetest
#### a) Using the vcpkg toolchain and CMakeGUI
1. Start up the CMake GUI
2. Select "Browse Source..." and select DIR/minetest
3. Select "Browse Build..." and select DIR/minetest-build
4. Select "Configure"
5. Choose the right visual Studio version and target platform. It has to match the version of the installed dependencies
6. Choose "Specify toolchain file for cross-compiling"
7. Click "Next"
8. Select the vcpkg toolchain file e.g. `D:/vcpkg/scripts/buildsystems/vcpkg.cmake`
9. Click Finish
10. Wait until cmake have generated the cash file
11. If there are any errors, solve them and hit "Configure"
12. Click "Generate"
13. Click "Open Project"
14. Compile Minetest inside Visual studio.
#### b) Using the vcpkg toolchain and the commandline
Run the following script in Powershell:
```powershell
cmake . -G"Visual Studio 15 2017 Win64" -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GETTEXT=0 -DENABLE_CURSES=0
cmake --build . --config Release
```
Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct.
#### c) Using your own compiled libaries
**This is outdated and not recommended**
Follow the instructions on https://dev.minetest.net/Build_Win32_Minetest_including_all_required_libraries#VS2012_Build
### Windows Installer using WIX Toolset ### Windows Installer using WIX Toolset

View File

@ -8,6 +8,9 @@ local blocks_forceloaded
local blocks_temploaded = {} local blocks_temploaded = {}
local total_forceloaded = 0 local total_forceloaded = 0
-- true, if the forceloaded blocks got changed (flag for persistence on-disk)
local forceload_blocks_changed = false
local BLOCKSIZE = core.MAP_BLOCKSIZE local BLOCKSIZE = core.MAP_BLOCKSIZE
local function get_blockpos(pos) local function get_blockpos(pos)
return { return {
@ -31,6 +34,9 @@ local function get_relevant_tables(transient)
end end
function core.forceload_block(pos, transient) function core.forceload_block(pos, transient)
-- set changed flag
forceload_blocks_changed = true
local blockpos = get_blockpos(pos) local blockpos = get_blockpos(pos)
local hash = core.hash_node_position(blockpos) local hash = core.hash_node_position(blockpos)
local relevant_table, other_table = get_relevant_tables(transient) local relevant_table, other_table = get_relevant_tables(transient)
@ -51,6 +57,9 @@ function core.forceload_block(pos, transient)
end end
function core.forceload_free_block(pos, transient) function core.forceload_free_block(pos, transient)
-- set changed flag
forceload_blocks_changed = true
local blockpos = get_blockpos(pos) local blockpos = get_blockpos(pos)
local hash = core.hash_node_position(blockpos) local hash = core.hash_node_position(blockpos)
local relevant_table, other_table = get_relevant_tables(transient) local relevant_table, other_table = get_relevant_tables(transient)
@ -95,6 +104,28 @@ core.after(5, function()
end end
end) end)
core.register_on_shutdown(function() -- persists the currently forceloaded blocks to disk
local function persist_forceloaded_blocks()
write_file(wpath.."/force_loaded.txt", blocks_forceloaded) write_file(wpath.."/force_loaded.txt", blocks_forceloaded)
end) end
-- periodical forceload persistence
local function periodically_persist_forceloaded_blocks()
-- only persist if the blocks actually changed
if forceload_blocks_changed then
persist_forceloaded_blocks()
-- reset changed flag
forceload_blocks_changed = false
end
-- recheck after some time
core.after(10, periodically_persist_forceloaded_blocks)
end
-- persist periodically
core.after(5, periodically_persist_forceloaded_blocks)
-- persist on shutdown
core.register_on_shutdown(persist_forceloaded_blocks)

View File

@ -1,19 +1,16 @@
mark_as_advanced(CURL_LIBRARY CURL_INCLUDE_DIR) mark_as_advanced(CURL_LIBRARY CURL_INCLUDE_DIR)
find_library(CURL_LIBRARY NAMES curl) find_library(CURL_LIBRARY NAMES curl libcurl)
find_path(CURL_INCLUDE_DIR NAMES curl/curl.h) find_path(CURL_INCLUDE_DIR NAMES curl/curl.h)
set(CURL_REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR)
if(WIN32) if(WIN32)
find_file(CURL_DLL NAMES libcurl-4.dll # If VCPKG_APPLOCAL_DEPS is ON, dll's are automatically handled by VCPKG
PATHS if(NOT VCPKG_APPLOCAL_DEPS)
"C:/Windows/System32" find_file(CURL_DLL NAMES libcurl-4.dll libcurl.dll
DOC "Path to the cURL DLL (for installation)") DOC "Path to the cURL DLL (for installation)")
mark_as_advanced(CURL_DLL) mark_as_advanced(CURL_DLL)
set(CURL_REQUIRED_VARS ${CURL_REQUIRED_VARS} CURL_DLL) endif()
endif() endif()
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CURL DEFAULT_MSG ${CURL_REQUIRED_VARS}) find_package_handle_standard_args(CURL DEFAULT_MSG CURL_LIBRARY CURL_INCLUDE_DIR)

View File

@ -43,6 +43,7 @@ else()
/usr/local/include/irrlicht /usr/local/include/irrlicht
/usr/include/irrlicht /usr/include/irrlicht
/system/develop/headers/irrlicht #Haiku /system/develop/headers/irrlicht #Haiku
PATH_SUFFIXES "include/irrlicht"
) )
find_library(IRRLICHT_LIBRARY NAMES libIrrlicht.so libIrrlicht.a Irrlicht find_library(IRRLICHT_LIBRARY NAMES libIrrlicht.so libIrrlicht.a Irrlicht
@ -56,16 +57,19 @@ endif()
# On Windows, find the DLL for installation # On Windows, find the DLL for installation
if(WIN32) if(WIN32)
if(MSVC) # If VCPKG_APPLOCAL_DEPS is ON, dll's are automatically handled by VCPKG
set(IRRLICHT_COMPILER "VisualStudio") if(NOT VCPKG_APPLOCAL_DEPS)
else() if(MSVC)
set(IRRLICHT_COMPILER "gcc") set(IRRLICHT_COMPILER "VisualStudio")
else()
set(IRRLICHT_COMPILER "gcc")
endif()
find_file(IRRLICHT_DLL NAMES Irrlicht.dll
PATHS
"${IRRLICHT_SOURCE_DIR}/bin/Win32-${IRRLICHT_COMPILER}"
DOC "Path of the Irrlicht dll (for installation)"
)
endif() endif()
find_file(IRRLICHT_DLL NAMES Irrlicht.dll
PATHS
"${IRRLICHT_SOURCE_DIR}/bin/Win32-${IRRLICHT_COMPILER}"
DOC "Path of the Irrlicht dll (for installation)"
)
endif(WIN32) endif(WIN32)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)

View File

@ -19,19 +19,31 @@ FIND_PATH(LUA_INCLUDE_DIR luajit.h
/opt /opt
) )
FIND_LIBRARY(LUA_LIBRARY # Test if running on vcpkg toolchain
NAMES luajit-5.1 if(DEFINED VCPKG_TARGET_TRIPLET AND DEFINED VCPKG_APPLOCAL_DEPS)
HINTS # On vcpkg luajit is 'lua51' and normal lua is 'lua'
$ENV{LUA_DIR} FIND_LIBRARY(LUA_LIBRARY
PATH_SUFFIXES lib64 lib NAMES lua51
PATHS HINTS
~/Library/Frameworks $ENV{LUA_DIR}
/Library/Frameworks PATH_SUFFIXES lib
/sw )
/opt/local else()
/opt/csw FIND_LIBRARY(LUA_LIBRARY
/opt NAMES luajit-5.1
) HINTS
$ENV{LUA_DIR}
PATH_SUFFIXES lib64 lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
endif()
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/luajit.h") IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/luajit.h")
FILE(STRINGS "${LUA_INCLUDE_DIR}/luajit.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"LuaJIT .+\"") FILE(STRINGS "${LUA_INCLUDE_DIR}/luajit.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"LuaJIT .+\"")

View File

@ -176,7 +176,7 @@ option(ENABLE_LEVELDB "Enable LevelDB backend" TRUE)
set(USE_LEVELDB FALSE) set(USE_LEVELDB FALSE)
if(ENABLE_LEVELDB) if(ENABLE_LEVELDB)
find_library(LEVELDB_LIBRARY leveldb) find_library(LEVELDB_LIBRARY NAMES leveldb libleveldb)
find_path(LEVELDB_INCLUDE_DIR db.h PATH_SUFFIXES leveldb) find_path(LEVELDB_INCLUDE_DIR db.h PATH_SUFFIXES leveldb)
if(LEVELDB_LIBRARY AND LEVELDB_INCLUDE_DIR) if(LEVELDB_LIBRARY AND LEVELDB_INCLUDE_DIR)
set(USE_LEVELDB TRUE) set(USE_LEVELDB TRUE)
@ -251,32 +251,23 @@ if(WIN32)
set(PLATFORM_LIBS ws2_32.lib version.lib shlwapi.lib ${PLATFORM_LIBS}) set(PLATFORM_LIBS ws2_32.lib version.lib shlwapi.lib ${PLATFORM_LIBS})
# Zlib stuff # Zlib stuff
set(ZLIB_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/../../zlib/zlib-1.2.5" find_path(ZLIB_INCLUDE_DIR "zlib.h" DOC "Zlib include directory")
CACHE PATH "Zlib include directory") find_library(ZLIB_LIBRARIES "zlib" DOC "Path to zlib library")
set(ZLIB_LIBRARIES "${PROJECT_SOURCE_DIR}/../../zlib125dll/dll32/zlibwapi.lib"
CACHE FILEPATH "Path to zlib library (usually zlibwapi.lib)") # Dll's are automatically copied to the output directory by vcpkg when VCPKG_APPLOCAL_DEPS=ON
set(ZLIB_DLL "${PROJECT_SOURCE_DIR}/../../zlib125dll/dll32/zlibwapi.dll" if(NOT VCPKG_APPLOCAL_DEPS)
CACHE FILEPATH "Path to zlib DLL (for installation)") find_file(ZLIB_DLL NAMES "zlib.dll" "zlib1.dll" DOC "Path to zlib.dll for installation (optional)")
set(ZLIBWAPI_DLL "" CACHE FILEPATH "Path to zlibwapi DLL") if(ENABLE_SOUND)
set(IRRLICHT_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../../irrlicht-1.7.2" set(OPENAL_DLL "" CACHE FILEPATH "Path to OpenAL32.dll for installation (optional)")
CACHE PATH "irrlicht dir") set(OGG_DLL "" CACHE FILEPATH "Path to libogg.dll for installation (optional)")
if(USE_FREETYPE) set(VORBIS_DLL "" CACHE FILEPATH "Path to libvorbis.dll for installation (optional)")
set(FREETYPE_INCLUDE_DIR_ft2build "${PROJECT_SOURCE_DIR}/../../freetype2/include/" set(VORBISFILE_DLL "" CACHE FILEPATH "Path to libvorbisfile.dll for installation (optional)")
CACHE PATH "freetype include dir") endif()
set(FREETYPE_INCLUDE_DIR_freetype2 "${PROJECT_SOURCE_DIR}/../../freetype2/include/freetype" if(USE_LUAJIT)
CACHE PATH "freetype include dir") set(LUA_DLL "" CACHE FILEPATH "Path to lua51.dll for installation (optional)")
set(FREETYPE_LIBRARY "${PROJECT_SOURCE_DIR}/../../freetype2/objs/win32/vc2005/freetype247.lib" endif()
CACHE FILEPATH "Path to freetype247.lib")
endif()
if(ENABLE_SOUND)
set(OPENAL_DLL "" CACHE FILEPATH "Path to OpenAL32.dll for installation (optional)")
set(OGG_DLL "" CACHE FILEPATH "Path to libogg.dll for installation (optional)")
set(VORBIS_DLL "" CACHE FILEPATH "Path to libvorbis.dll for installation (optional)")
set(VORBISFILE_DLL "" CACHE FILEPATH "Path to libvorbisfile.dll for installation (optional)")
endif()
if(USE_LUAJIT)
set(LUA_DLL "" CACHE FILEPATH "Path to lua51.dll for installation (optional)")
endif() endif()
else() else()
# Unix probably # Unix probably
if(BUILD_CLIENT) if(BUILD_CLIENT)
@ -703,12 +694,6 @@ else()
set(OTHER_FLAGS "${OTHER_FLAGS} -Wsign-compare") set(OTHER_FLAGS "${OTHER_FLAGS} -Wsign-compare")
endif() endif()
if(WIN32 AND NOT ZLIBWAPI_DLL AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(OTHER_FLAGS "${OTHER_FLAGS} -DWIN32_NO_ZLIB_WINAPI")
message(WARNING "Defaulting to cdecl for zlib on win32 because ZLIBWAPI_DLL"
" isn't set, ensure that ZLIBWAPI_DLL is set if you want stdcall.")
endif()
if(MINGW) if(MINGW)
set(OTHER_FLAGS "${OTHER_FLAGS} -mthreads -fexceptions") set(OTHER_FLAGS "${OTHER_FLAGS} -mthreads -fexceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_LEAN_AND_MEAN") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32_LEAN_AND_MEAN")
@ -736,40 +721,58 @@ endif()
# Installation # Installation
if(WIN32) if(WIN32)
if(USE_SOUND) if(VCPKG_APPLOCAL_DEPS)
if(OPENAL_DLL) # Collect the dll's from the output path
install(FILES ${OPENAL_DLL} DESTINATION ${BINDIR}) install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Release/
DESTINATION ${BINDIR}
CONFIGURATIONS Release
FILES_MATCHING PATTERN "*.dll")
install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Debug/
DESTINATION ${BINDIR}
CONFIGURATIONS Debug
FILES_MATCHING PATTERN "*.dll")
install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/RelWithDebInfo/
DESTINATION ${BINDIR}
CONFIGURATIONS RelWithDebInfo
FILES_MATCHING PATTERN "*.dll")
install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/MinSizeRel/
DESTINATION ${BINDIR}
CONFIGURATIONS RelWithDebInfo
FILES_MATCHING PATTERN "*.dll")
else()
# Use the old-style way to install dll's
if(USE_SOUND)
if(OPENAL_DLL)
install(FILES ${OPENAL_DLL} DESTINATION ${BINDIR})
endif()
if(OGG_DLL)
install(FILES ${OGG_DLL} DESTINATION ${BINDIR})
endif()
if(VORBIS_DLL)
install(FILES ${VORBIS_DLL} DESTINATION ${BINDIR})
endif()
if(VORBISFILE_DLL)
install(FILES ${VORBISFILE_DLL} DESTINATION ${BINDIR})
endif()
endif() endif()
if(OGG_DLL) if(CURL_DLL)
install(FILES ${OGG_DLL} DESTINATION ${BINDIR}) install(FILES ${CURL_DLL} DESTINATION ${BINDIR})
endif() endif()
if(VORBIS_DLL) if(ZLIB_DLL)
install(FILES ${VORBIS_DLL} DESTINATION ${BINDIR}) install(FILES ${ZLIB_DLL} DESTINATION ${BINDIR})
endif() endif()
if(VORBISFILE_DLL) if(FREETYPE_DLL)
install(FILES ${VORBISFILE_DLL} DESTINATION ${BINDIR}) install(FILES ${FREETYPE_DLL} DESTINATION ${BINDIR})
endif()
if(SQLITE3_DLL)
install(FILES ${SQLITE3_DLL} DESTINATION ${BINDIR})
endif()
if(LEVELDB_DLL)
install(FILES ${LEVELDB_DLL} DESTINATION ${BINDIR})
endif()
if(LUA_DLL)
install(FILES ${LUA_DLL} DESTINATION ${BINDIR})
endif() endif()
endif()
if(CURL_DLL)
install(FILES ${CURL_DLL} DESTINATION ${BINDIR})
endif()
if(ZLIB_DLL)
install(FILES ${ZLIB_DLL} DESTINATION ${BINDIR})
endif()
if(ZLIBWAPI_DLL)
install(FILES ${ZLIBWAPI_DLL} DESTINATION ${BINDIR})
endif()
if(FREETYPE_DLL)
install(FILES ${FREETYPE_DLL} DESTINATION ${BINDIR})
endif()
if(SQLITE3_DLL)
install(FILES ${SQLITE3_DLL} DESTINATION ${BINDIR})
endif()
if(LEVELDB_DLL)
install(FILES ${LEVELDB_DLL} DESTINATION ${BINDIR})
endif()
if(LUA_DLL)
install(FILES ${LUA_DLL} DESTINATION ${BINDIR})
endif() endif()
endif() endif()
@ -806,15 +809,17 @@ if(BUILD_CLIENT)
endif() endif()
if(WIN32) if(WIN32)
if(DEFINED IRRLICHT_DLL) if(NOT VCPKG_APPLOCAL_DEPS)
install(FILES ${IRRLICHT_DLL} DESTINATION ${BINDIR}) if(DEFINED IRRLICHT_DLL)
endif() install(FILES ${IRRLICHT_DLL} DESTINATION ${BINDIR})
if(USE_GETTEXT)
if(DEFINED GETTEXT_DLL)
install(FILES ${GETTEXT_DLL} DESTINATION ${BINDIR})
endif() endif()
if(DEFINED GETTEXT_ICONV_DLL) if(USE_GETTEXT)
install(FILES ${GETTEXT_ICONV_DLL} DESTINATION ${BINDIR}) if(DEFINED GETTEXT_DLL)
install(FILES ${GETTEXT_DLL} DESTINATION ${BINDIR})
endif()
if(DEFINED GETTEXT_ICONV_DLL)
install(FILES ${GETTEXT_ICONV_DLL} DESTINATION ${BINDIR})
endif()
endif() endif()
endif() endif()
endif() endif()

View File

@ -827,10 +827,6 @@ private:
ChatBackend *chat_backend = nullptr; ChatBackend *chat_backend = nullptr;
GUIFormSpecMenu *current_formspec = nullptr;
//default: "". If other than "", empty show_formspec packets will only close the formspec when the formname matches
std::string cur_formname;
EventManager *eventmgr = nullptr; EventManager *eventmgr = nullptr;
QuicktuneShortcutter *quicktune = nullptr; QuicktuneShortcutter *quicktune = nullptr;
bool registration_confirmation_shown = false; bool registration_confirmation_shown = false;
@ -1143,8 +1139,9 @@ void Game::shutdown()
driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS); driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS);
} }
#endif #endif
if (current_formspec) auto formspec = m_game_ui->getFormspecGUI();
current_formspec->quitMenu(); if (formspec)
formspec->quitMenu();
showOverlayMessage(N_("Shutting down..."), 0, 0, false); showOverlayMessage(N_("Shutting down..."), 0, 0, false);
@ -1163,10 +1160,7 @@ void Game::shutdown()
g_menumgr.deletingMenu(g_menumgr.m_stack.front()); g_menumgr.deletingMenu(g_menumgr.m_stack.front());
} }
if (current_formspec) { m_game_ui->deleteFormspec();
current_formspec->drop();
current_formspec = NULL;
}
chat_backend->addMessage(L"", L"# Disconnected."); chat_backend->addMessage(L"", L"# Disconnected.");
chat_backend->addMessage(L"", L""); chat_backend->addMessage(L"", L"");
@ -1853,8 +1847,9 @@ void Game::processUserInput(f32 dtime)
input->step(dtime); input->step(dtime);
#ifdef __ANDROID__ #ifdef __ANDROID__
if (current_formspec != NULL) auto formspec = m_game_ui->getFormspecGUI();
current_formspec->getAndroidUIInput(); if (formspec)
formspec->getAndroidUIInput();
else else
handleAndroidChatInput(); handleAndroidChatInput();
#endif #endif
@ -2050,10 +2045,11 @@ void Game::openInventory()
if (!client->moddingEnabled() if (!client->moddingEnabled()
|| !client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) { || !client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) {
TextDest *txt_dst = new TextDestPlayerInventory(client); TextDest *txt_dst = new TextDestPlayerInventory(client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src, auto *&formspec = m_game_ui->updateFormspec("");
GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
txt_dst, client->getFormspecPrepend()); txt_dst, client->getFormspecPrepend());
cur_formname = "";
current_formspec->setFormSpec(fs_src->getForm(), inventoryloc); formspec->setFormSpec(fs_src->getForm(), inventoryloc);
} }
} }
@ -2581,9 +2577,10 @@ void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *
void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam) void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam)
{ {
if (event->show_formspec.formspec->empty()) { if (event->show_formspec.formspec->empty()) {
if (current_formspec && (event->show_formspec.formname->empty() auto formspec = m_game_ui->getFormspecGUI();
|| *(event->show_formspec.formname) == cur_formname)) { if (formspec && (event->show_formspec.formname->empty()
current_formspec->quitMenu(); || *(event->show_formspec.formname) == m_game_ui->getFormspecName())) {
formspec->quitMenu();
} }
} else { } else {
FormspecFormSource *fs_src = FormspecFormSource *fs_src =
@ -2591,9 +2588,9 @@ void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation
TextDestPlayerInventory *txt_dst = TextDestPlayerInventory *txt_dst =
new TextDestPlayerInventory(client, *(event->show_formspec.formname)); new TextDestPlayerInventory(client, *(event->show_formspec.formname));
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, auto *&formspec = m_game_ui->updateFormspec(*(event->show_formspec.formname));
GUIFormSpecMenu::create(formspec, client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend()); fs_src, txt_dst, client->getFormspecPrepend());
cur_formname = *(event->show_formspec.formname);
} }
delete event->show_formspec.formspec; delete event->show_formspec.formspec;
@ -2605,7 +2602,7 @@ void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrienta
FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec); FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec);
LocalFormspecHandler *txt_dst = LocalFormspecHandler *txt_dst =
new LocalFormspecHandler(*event->show_formspec.formname, client); new LocalFormspecHandler(*event->show_formspec.formname, client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, GUIFormSpecMenu::create(m_game_ui->getFormspecGUI(), client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend()); fs_src, txt_dst, client->getFormspecPrepend());
delete event->show_formspec.formspec; delete event->show_formspec.formspec;
@ -3272,11 +3269,11 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
&client->getEnv().getClientMap(), nodepos); &client->getEnv().getClientMap(), nodepos);
TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client); TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src, auto *&formspec = m_game_ui->updateFormspec("");
GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
txt_dst, client->getFormspecPrepend()); txt_dst, client->getFormspecPrepend());
cur_formname.clear();
current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc); formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
} else { } else {
// Report right click to server // Report right click to server
@ -3844,14 +3841,28 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
1. Delete formspec menu reference if menu was removed 1. Delete formspec menu reference if menu was removed
2. Else, make sure formspec menu is on top 2. Else, make sure formspec menu is on top
*/ */
if (current_formspec) { auto formspec = m_game_ui->getFormspecGUI();
if (current_formspec->getReferenceCount() == 1) { do { // breakable. only runs for one iteration
current_formspec->drop(); if (!formspec)
current_formspec = NULL; break;
} else if (isMenuActive()) {
guiroot->bringToFront(current_formspec); if (formspec->getReferenceCount() == 1) {
m_game_ui->deleteFormspec();
break;
} }
}
auto &loc = formspec->getFormspecLocation();
if (loc.type == InventoryLocation::NODEMETA) {
NodeMetadata *meta = client->getEnv().getClientMap().getNodeMetadata(loc.p);
if (!meta || meta->getString("formspec").empty()) {
formspec->quitMenu();
break;
}
}
if (isMenuActive())
guiroot->bringToFront(formspec);
} while (false);
/* /*
Drawing begins Drawing begins
@ -4048,7 +4059,7 @@ void Game::extendedResourceCleanup()
void Game::showDeathFormspec() void Game::showDeathFormspec()
{ {
static std::string formspec = static std::string formspec_str =
std::string(FORMSPEC_VERSION_STRING) + std::string(FORMSPEC_VERSION_STRING) +
SIZE_TAG SIZE_TAG
"bgcolor[#320000b4;true]" "bgcolor[#320000b4;true]"
@ -4059,12 +4070,13 @@ void Game::showDeathFormspec()
/* Create menu */ /* Create menu */
/* Note: FormspecFormSource and LocalFormspecHandler * /* Note: FormspecFormSource and LocalFormspecHandler *
* are deleted by guiFormSpecMenu */ * are deleted by guiFormSpecMenu */
FormspecFormSource *fs_src = new FormspecFormSource(formspec); FormspecFormSource *fs_src = new FormspecFormSource(formspec_str);
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client); LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src, auto *&formspec = m_game_ui->getFormspecGUI();
txt_dst, client->getFormspecPrepend()); GUIFormSpecMenu::create(formspec, client, &input->joystick,
current_formspec->setFocus("btn_respawn"); fs_src, txt_dst, client->getFormspecPrepend());
formspec->setFocus("btn_respawn");
} }
#define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name()) #define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name())
@ -4188,10 +4200,11 @@ void Game::showPauseMenu()
FormspecFormSource *fs_src = new FormspecFormSource(os.str()); FormspecFormSource *fs_src = new FormspecFormSource(os.str());
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU"); LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, auto *&formspec = m_game_ui->getFormspecGUI();
GUIFormSpecMenu::create(formspec, client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend()); fs_src, txt_dst, client->getFormspecPrepend());
current_formspec->setFocus("btn_continue"); formspec->setFocus("btn_continue");
current_formspec->doPause = true; formspec->doPause = true;
} }
/****************************************************************************/ /****************************************************************************/

View File

@ -302,3 +302,15 @@ void GameUI::toggleProfiler()
showTranslatedStatusText("Profiler hidden"); showTranslatedStatusText("Profiler hidden");
} }
} }
void GameUI::deleteFormspec()
{
if (m_formspec)
m_formspec->quitMenu();
delete m_formspec;
m_formspec = nullptr;
m_formname.clear();
}

View File

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once #pragma once
#include <IGUIEnvironment.h> #include <IGUIEnvironment.h>
#include "gui/guiFormSpecMenu.h"
#include "util/enriched_string.h" #include "util/enriched_string.h"
#include "util/pointedthing.h" #include "util/pointedthing.h"
#include "game.h" #include "game.h"
@ -88,6 +89,16 @@ public:
void toggleHud(); void toggleHud();
void toggleProfiler(); void toggleProfiler();
GUIFormSpecMenu *&updateFormspec(const std::string &formname)
{
m_formname = formname;
return m_formspec;
}
const std::string &getFormspecName() { return m_formname; }
GUIFormSpecMenu *&getFormspecGUI() { return m_formspec; }
void deleteFormspec();
private: private:
Flags m_flags; Flags m_flags;
@ -107,4 +118,9 @@ private:
gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text
u8 m_profiler_current_page = 0; u8 m_profiler_current_page = 0;
const u8 m_profiler_max_page = 3; const u8 m_profiler_max_page = 3;
// Default: "". If other than "": Empty show_formspec packets will only
// close the formspec when the formname matches
std::string m_formname;
GUIFormSpecMenu *m_formspec = nullptr;
}; };

View File

@ -170,8 +170,8 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
std::vector<CollisionInfo> *collision_info) std::vector<CollisionInfo> *collision_info)
{ {
if (!collision_info || collision_info->empty()) { if (!collision_info || collision_info->empty()) {
// Node below the feet, update each ClientEnvironment::step() // Node at feet position, update each ClientEnvironment::step()
m_standing_node = floatToInt(m_position, BS) - v3s16(0, 1, 0); m_standing_node = floatToInt(m_position, BS);
} }
// Temporary option for old move code // Temporary option for old move code
@ -309,7 +309,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
collision_info->push_back(colinfo); collision_info->push_back(colinfo);
if (colinfo.type != COLLISION_NODE || if (colinfo.type != COLLISION_NODE ||
colinfo.new_speed.Y != 0 || colinfo.axis != COLLISION_AXIS_Y ||
(could_sneak && m_sneak_node_exists)) (could_sneak && m_sneak_node_exists))
continue; continue;
@ -320,6 +320,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
if (is_first || len < distance) { if (is_first || len < distance) {
m_standing_node = colinfo.node_p; m_standing_node = colinfo.node_p;
distance = len; distance = len;
is_first = false;
} }
} }
} }
@ -435,11 +436,11 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
Check properties of the node on which the player is standing Check properties of the node on which the player is standing
*/ */
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(m_standing_node)); const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(m_standing_node));
// Determine if jumping is possible // Determine if jumping is possible
m_can_jump = (touching_ground && !in_liquid && !is_climbing) m_disable_jump = itemgroup_get(f.groups, "disable_jump");
|| sneak_can_jump; m_can_jump = ((touching_ground && !is_climbing)
if (itemgroup_get(f.groups, "disable_jump")) || sneak_can_jump) && !m_disable_jump;
m_can_jump = false;
// Jump key pressed while jumping off from a bouncy block // Jump key pressed while jumping off from a bouncy block
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") && if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
@ -636,18 +637,14 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
setSpeed(speedJ); setSpeed(speedJ);
m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_JUMP)); m_client->getEventManager()->put(new SimpleTriggerEvent(MtEvent::PLAYER_JUMP));
} }
} } else if (in_liquid && !m_disable_jump) {
else if(in_liquid) if (fast_climb)
{
if(fast_climb)
speedV.Y = movement_speed_fast; speedV.Y = movement_speed_fast;
else else
speedV.Y = movement_speed_walk; speedV.Y = movement_speed_walk;
swimming_vertical = true; swimming_vertical = true;
} } else if (is_climbing && !m_disable_jump) {
else if(is_climbing) if (fast_climb)
{
if(fast_climb)
speedV.Y = movement_speed_fast; speedV.Y = movement_speed_fast;
else else
speedV.Y = movement_speed_climb; speedV.Y = movement_speed_climb;
@ -908,6 +905,12 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
pos_max_d, m_collisionbox, player_stepheight, dtime, pos_max_d, m_collisionbox, player_stepheight, dtime,
&position, &m_speed, accel_f); &position, &m_speed, accel_f);
// Positition was slightly changed; update standing node pos
if (touching_ground)
m_standing_node = floatToInt(m_position - v3f(0, 0.1f * BS, 0), BS);
else
m_standing_node = floatToInt(m_position, BS);
/* /*
If the player's feet touch the topside of any node, this is If the player's feet touch the topside of any node, this is
set to true. set to true.
@ -1048,11 +1051,13 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
/* /*
Check properties of the node on which the player is standing Check properties of the node on which the player is standing
*/ */
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(getStandingNodePos())); const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(
getStandingNodePos()));
// Determine if jumping is possible // Determine if jumping is possible
m_can_jump = touching_ground && !in_liquid; m_disable_jump = itemgroup_get(f.groups, "disable_jump");
if (itemgroup_get(f.groups, "disable_jump")) m_can_jump = touching_ground && !m_disable_jump;
m_can_jump = false;
// Jump key pressed while jumping off from a bouncy block // Jump key pressed while jumping off from a bouncy block
if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") && if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
m_speed.Y >= -0.5 * BS) { m_speed.Y >= -0.5 * BS) {

View File

@ -183,6 +183,7 @@ private:
// ***** End of variables for temporary option ***** // ***** End of variables for temporary option *****
bool m_can_jump = false; bool m_can_jump = false;
bool m_disable_jump = false;
u16 m_breath = PLAYER_MAX_BREATH_DEFAULT; u16 m_breath = PLAYER_MAX_BREATH_DEFAULT;
f32 m_yaw = 0.0f; f32 m_yaw = 0.0f;
f32 m_pitch = 0.0f; f32 m_pitch = 0.0f;

View File

@ -59,7 +59,7 @@ struct NearbyCollisionInfo {
// Checks for collision of a moving aabbox with a static aabbox // Checks for collision of a moving aabbox with a static aabbox
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision // Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
// The time after which the collision occurs is stored in dtime. // The time after which the collision occurs is stored in dtime.
int axisAlignedCollision( CollisionAxis axisAlignedCollision(
const aabb3f &staticbox, const aabb3f &movingbox, const aabb3f &staticbox, const aabb3f &movingbox,
const v3f &speed, f32 d, f32 *dtime) const v3f &speed, f32 d, f32 *dtime)
{ {
@ -86,11 +86,11 @@ int axisAlignedCollision(
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) && (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) &&
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
return 0; return COLLISION_AXIS_X;
} }
else if(relbox.MinEdge.X > xsize) else if(relbox.MinEdge.X > xsize)
{ {
return -1; return COLLISION_AXIS_NONE;
} }
} }
else if(speed.X < 0) // Check for collision with X+ plane else if(speed.X < 0) // Check for collision with X+ plane
@ -101,11 +101,11 @@ int axisAlignedCollision(
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) && (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO) &&
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
return 0; return COLLISION_AXIS_X;
} }
else if(relbox.MaxEdge.X < 0) else if(relbox.MaxEdge.X < 0)
{ {
return -1; return COLLISION_AXIS_NONE;
} }
} }
@ -119,11 +119,11 @@ int axisAlignedCollision(
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
return 1; return COLLISION_AXIS_Y;
} }
else if(relbox.MinEdge.Y > ysize) else if(relbox.MinEdge.Y > ysize)
{ {
return -1; return COLLISION_AXIS_NONE;
} }
} }
else if(speed.Y < 0) // Check for collision with Y+ plane else if(speed.Y < 0) // Check for collision with Y+ plane
@ -134,11 +134,11 @@ int axisAlignedCollision(
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
(relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) && (relbox.MinEdge.Z + speed.Z * (*dtime) < zsize) &&
(relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO)) (relbox.MaxEdge.Z + speed.Z * (*dtime) > COLL_ZERO))
return 1; return COLLISION_AXIS_Y;
} }
else if(relbox.MaxEdge.Y < 0) else if(relbox.MaxEdge.Y < 0)
{ {
return -1; return COLLISION_AXIS_NONE;
} }
} }
@ -152,11 +152,11 @@ int axisAlignedCollision(
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
(relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) && (relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) &&
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO)) (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO))
return 2; return COLLISION_AXIS_Z;
} }
//else if(relbox.MinEdge.Z > zsize) //else if(relbox.MinEdge.Z > zsize)
//{ //{
// return -1; // return COLLISION_AXIS_NONE;
//} //}
} }
else if(speed.Z < 0) // Check for collision with Z+ plane else if(speed.Z < 0) // Check for collision with Z+ plane
@ -167,15 +167,15 @@ int axisAlignedCollision(
(relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) && (relbox.MaxEdge.X + speed.X * (*dtime) > COLL_ZERO) &&
(relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) && (relbox.MinEdge.Y + speed.Y * (*dtime) < ysize) &&
(relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO)) (relbox.MaxEdge.Y + speed.Y * (*dtime) > COLL_ZERO))
return 2; return COLLISION_AXIS_Z;
} }
//else if(relbox.MaxEdge.Z < 0) //else if(relbox.MaxEdge.Z < 0)
//{ //{
// return -1; // return COLLISION_AXIS_NONE;
//} //}
} }
return -1; return COLLISION_AXIS_NONE;
} }
// Helper function: // Helper function:
@ -442,7 +442,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
movingbox.MinEdge += *pos_f; movingbox.MinEdge += *pos_f;
movingbox.MaxEdge += *pos_f; movingbox.MaxEdge += *pos_f;
int nearest_collided = -1; CollisionAxis nearest_collided = COLLISION_AXIS_NONE;
f32 nearest_dtime = dtime; f32 nearest_dtime = dtime;
int nearest_boxindex = -1; int nearest_boxindex = -1;
@ -457,7 +457,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
// Find nearest collision of the two boxes (raytracing-like) // Find nearest collision of the two boxes (raytracing-like)
f32 dtime_tmp; f32 dtime_tmp;
int collided = axisAlignedCollision(box_info.box, CollisionAxis collided = axisAlignedCollision(box_info.box,
movingbox, *speed_f, d, &dtime_tmp); movingbox, *speed_f, d, &dtime_tmp);
if (collided == -1 || dtime_tmp >= nearest_dtime) if (collided == -1 || dtime_tmp >= nearest_dtime)
@ -468,7 +468,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
nearest_boxindex = boxindex; nearest_boxindex = boxindex;
} }
if (nearest_collided == -1) { if (nearest_collided == COLLISION_AXIS_NONE) {
// No collision with any collision box. // No collision with any collision box.
*pos_f += *speed_f * dtime; *pos_f += *speed_f * dtime;
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
@ -477,7 +477,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex]; NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex];
const aabb3f& cbox = nearest_info.box; const aabb3f& cbox = nearest_info.box;
// Check for stairs. // Check for stairs.
bool step_up = (nearest_collided != 1) && // must not be Y direction bool step_up = (nearest_collided != COLLISION_AXIS_Y) && // must not be Y direction
(movingbox.MinEdge.Y < cbox.MaxEdge.Y) && (movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) && (movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
(!wouldCollideWithCeiling(cinfo, movingbox, (!wouldCollideWithCeiling(cinfo, movingbox,
@ -491,11 +491,11 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
if (nearest_dtime < 0) { if (nearest_dtime < 0) {
// Handle negative nearest_dtime (can be caused by the d allowance) // Handle negative nearest_dtime (can be caused by the d allowance)
if (!step_up) { if (!step_up) {
if (nearest_collided == 0) if (nearest_collided == COLLISION_AXIS_X)
pos_f->X += speed_f->X * nearest_dtime; pos_f->X += speed_f->X * nearest_dtime;
if (nearest_collided == 1) if (nearest_collided == COLLISION_AXIS_Y)
pos_f->Y += speed_f->Y * nearest_dtime; pos_f->Y += speed_f->Y * nearest_dtime;
if (nearest_collided == 2) if (nearest_collided == COLLISION_AXIS_Z)
pos_f->Z += speed_f->Z * nearest_dtime; pos_f->Z += speed_f->Z * nearest_dtime;
} }
} else { } else {
@ -522,19 +522,19 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
// Special case: Handle stairs // Special case: Handle stairs
nearest_info.is_step_up = true; nearest_info.is_step_up = true;
is_collision = false; is_collision = false;
} else if (nearest_collided == 0) { // X } else if (nearest_collided == COLLISION_AXIS_X) {
if (fabs(speed_f->X) > BS * 3) if (fabs(speed_f->X) > BS * 3)
speed_f->X *= bounce; speed_f->X *= bounce;
else else
speed_f->X = 0; speed_f->X = 0;
result.collides = true; result.collides = true;
} else if (nearest_collided == 1) { // Y } else if (nearest_collided == COLLISION_AXIS_Y) {
if(fabs(speed_f->Y) > BS * 3) if(fabs(speed_f->Y) > BS * 3)
speed_f->Y *= bounce; speed_f->Y *= bounce;
else else
speed_f->Y = 0; speed_f->Y = 0;
result.collides = true; result.collides = true;
} else if (nearest_collided == 2) { // Z } else if (nearest_collided == COLLISION_AXIS_Z) {
if (fabs(speed_f->Z) > BS * 3) if (fabs(speed_f->Z) > BS * 3)
speed_f->Z *= bounce; speed_f->Z *= bounce;
else else
@ -547,6 +547,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
is_collision = false; is_collision = false;
if (is_collision) { if (is_collision) {
info.axis = nearest_collided;
result.collisions.push_back(info); result.collisions.push_back(info);
} }
} }

View File

@ -33,11 +33,20 @@ enum CollisionType
COLLISION_OBJECT, COLLISION_OBJECT,
}; };
enum CollisionAxis
{
COLLISION_AXIS_NONE = -1,
COLLISION_AXIS_X,
COLLISION_AXIS_Y,
COLLISION_AXIS_Z,
};
struct CollisionInfo struct CollisionInfo
{ {
CollisionInfo() = default; CollisionInfo() = default;
CollisionType type = COLLISION_NODE; CollisionType type = COLLISION_NODE;
CollisionAxis axis = COLLISION_AXIS_NONE;
v3s16 node_p = v3s16(-32768,-32768,-32768); // COLLISION_NODE v3s16 node_p = v3s16(-32768,-32768,-32768); // COLLISION_NODE
v3f old_speed; v3f old_speed;
v3f new_speed; v3f new_speed;
@ -66,7 +75,7 @@ collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
// Checks for collision of a moving aabbox with a static aabbox // Checks for collision of a moving aabbox with a static aabbox
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision // Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
// dtime receives time until first collision, invalid if -1 is returned // dtime receives time until first collision, invalid if -1 is returned
int axisAlignedCollision( CollisionAxis axisAlignedCollision(
const aabb3f &staticbox, const aabb3f &movingbox, const aabb3f &staticbox, const aabb3f &movingbox,
const v3f &speed, f32 d, f32 *dtime); const v3f &speed, f32 d, f32 *dtime);

View File

@ -633,17 +633,15 @@ int LuaEntitySAO::punch(v3f dir,
return 0; return 0;
} }
ItemStack *punchitem = NULL; FATAL_ERROR_IF(!puncher, "Punch action called without SAO");
ItemStack punchitem_static;
if (puncher) { s32 old_hp = getHP();
punchitem_static = puncher->getWieldedItem(); const ItemStack &punchitem = puncher->getWieldedItem();
punchitem = &punchitem_static;
}
PunchDamageResult result = getPunchDamage( PunchDamageResult result = getPunchDamage(
m_armor_groups, m_armor_groups,
toolcap, toolcap,
punchitem, &punchitem,
time_from_last_punch); time_from_last_punch);
bool damage_handled = m_env->getScriptIface()->luaentity_Punch(m_id, puncher, bool damage_handled = m_env->getScriptIface()->luaentity_Punch(m_id, puncher,
@ -654,14 +652,6 @@ int LuaEntitySAO::punch(v3f dir,
setHP((s32)getHP() - result.damage, setHP((s32)getHP() - result.damage,
PlayerHPChangeReason(PlayerHPChangeReason::SET_HP)); PlayerHPChangeReason(PlayerHPChangeReason::SET_HP));
if (result.damage > 0) {
std::string punchername = puncher ? puncher->getDescription() : "nil";
actionstream << getDescription() << " punched by "
<< punchername << ", damage " << result.damage
<< " hp, health now " << getHP() << " hp" << std::endl;
}
std::string str = gob_cmd_punched(getHP()); std::string str = gob_cmd_punched(getHP());
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
@ -676,6 +666,12 @@ int LuaEntitySAO::punch(v3f dir,
m_env->getScriptIface()->luaentity_on_death(m_id, puncher); m_env->getScriptIface()->luaentity_on_death(m_id, puncher);
} }
actionstream << puncher->getDescription() << " (id=" << puncher->getId() <<
", hp=" << puncher->getHP() << ") punched " <<
getDescription() << " (id=" << m_id << ", hp=" << m_hp <<
"), damage=" << (old_hp - (s32)getHP()) <<
(damage_handled ? " (handled by Lua)" : "") << std::endl;
return result.wear; return result.wear;
} }
@ -893,6 +889,9 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t p
m_breath = m_prop.breath_max; m_breath = m_prop.breath_max;
// Disable zoom in survival mode using a value of 0 // Disable zoom in survival mode using a value of 0
m_prop.zoom_fov = g_settings->getBool("creative_mode") ? 15.0f : 0.0f; m_prop.zoom_fov = g_settings->getBool("creative_mode") ? 15.0f : 0.0f;
if (!g_settings->getBool("enable_damage"))
m_armor_groups["immortal"] = 1;
} }
PlayerSAO::~PlayerSAO() PlayerSAO::~PlayerSAO()
@ -995,7 +994,7 @@ void PlayerSAO::getStaticData(std::string * result) const
void PlayerSAO::step(float dtime, bool send_recommended) void PlayerSAO::step(float dtime, bool send_recommended)
{ {
if (m_drowning_interval.step(dtime, 2.0f)) { if (!isImmortal() && m_drowning_interval.step(dtime, 2.0f)) {
// Get nose/mouth position, approximate with eye position // Get nose/mouth position, approximate with eye position
v3s16 p = floatToInt(getEyePosition(), BS); v3s16 p = floatToInt(getEyePosition(), BS);
MapNode n = m_env->getMap().getNodeNoEx(p); MapNode n = m_env->getMap().getNodeNoEx(p);
@ -1025,7 +1024,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
setBreath(m_breath + 1); setBreath(m_breath + 1);
} }
if (m_node_hurt_interval.step(dtime, 1.0f)) { if (!isImmortal() && m_node_hurt_interval.step(dtime, 1.0f)) {
u32 damage_per_second = 0; u32 damage_per_second = 0;
std::string nodename; std::string nodename;
// Lowest and highest damage points are 0.1 within collisionbox // Lowest and highest damage points are 0.1 within collisionbox
@ -1284,6 +1283,8 @@ int PlayerSAO::punch(v3f dir,
if (!toolcap) if (!toolcap)
return 0; return 0;
FATAL_ERROR_IF(!puncher, "Punch action called without SAO");
// No effect if PvP disabled // No effect if PvP disabled
if (!g_settings->getBool("enable_pvp")) { if (!g_settings->getBool("enable_pvp")) {
if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) { if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
@ -1295,14 +1296,10 @@ int PlayerSAO::punch(v3f dir,
} }
} }
s32 old_hp = getHP();
HitParams hitparams = getHitParams(m_armor_groups, toolcap, HitParams hitparams = getHitParams(m_armor_groups, toolcap,
time_from_last_punch); time_from_last_punch);
std::string punchername = "nil";
if (puncher != 0)
punchername = puncher->getDescription();
PlayerSAO *playersao = m_player->getPlayerSAO(); PlayerSAO *playersao = m_player->getPlayerSAO();
bool damage_handled = m_env->getScriptIface()->on_punchplayer(playersao, bool damage_handled = m_env->getScriptIface()->on_punchplayer(playersao,
@ -1321,15 +1318,11 @@ int PlayerSAO::punch(v3f dir,
} }
} }
actionstream << puncher->getDescription() << " (id=" << puncher->getId() <<
actionstream << "Player " << m_player->getName() << " punched by " ", hp=" << puncher->getHP() << ") punched " <<
<< punchername; getDescription() << " (id=" << m_id << ", hp=" << m_hp <<
if (!damage_handled) { "), damage=" << (old_hp - (s32)getHP()) <<
actionstream << ", damage " << hitparams.hp << " HP"; (damage_handled ? " (handled by Lua)" : "") << std::endl;
} else {
actionstream << ", damage handled by lua";
}
actionstream << std::endl;
return hitparams.wear; return hitparams.wear;
} }
@ -1348,7 +1341,7 @@ void PlayerSAO::setHP(s32 hp, const PlayerHPChangeReason &reason)
hp = rangelim(oldhp + hp_change, 0, m_prop.hp_max); hp = rangelim(oldhp + hp_change, 0, m_prop.hp_max);
} }
if (hp < oldhp && !g_settings->getBool("enable_damage")) if (hp < oldhp && isImmortal())
return; return;
m_hp = hp; m_hp = hp;

View File

@ -45,6 +45,8 @@ public:
inline bool isAttached() const inline bool isAttached() const
{ return getParent(); } { return getParent(); }
inline bool isImmortal() const
{ return itemgroup_get(m_armor_groups, "immortal"); }
void setArmorGroups(const ItemGroupList &armor_groups); void setArmorGroups(const ItemGroupList &armor_groups);
const ItemGroupList &getArmorGroups(); const ItemGroupList &getArmorGroups();

View File

@ -304,6 +304,11 @@ public:
regenerateGui(m_screensize_old); regenerateGui(m_screensize_old);
} }
const InventoryLocation &getFormspecLocation()
{
return m_current_inventory_location;
}
void setFormspecPrepend(const std::string &formspecPrepend) void setFormspecPrepend(const std::string &formspecPrepend)
{ {
m_formspec_prepend = formspecPrepend; m_formspec_prepend = formspecPrepend;

View File

@ -799,7 +799,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt)
return; return;
} }
if (g_settings->getBool("enable_damage")) { if (!playersao->isImmortal()) {
if (playersao->isDead()) { if (playersao->isDead()) {
verbosestream << "Server::ProcessData(): Info: " verbosestream << "Server::ProcessData(): Info: "
"Ignoring damage as player " << player->getName() "Ignoring damage as player " << player->getName()
@ -1156,10 +1156,6 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
if (pointed_object->isGone()) if (pointed_object->isGone())
return; return;
actionstream<<player->getName()<<" punches object "
<<pointed.object_id<<": "
<<pointed_object->getDescription()<<std::endl;
ItemStack punchitem = playersao->getWieldedItemOrHand(); ItemStack punchitem = playersao->getWieldedItemOrHand();
ToolCapabilities toolcap = ToolCapabilities toolcap =
punchitem.getToolCapabilities(m_itemdef); punchitem.getToolCapabilities(m_itemdef);

View File

@ -20,9 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serialization.h" #include "serialization.h"
#include "util/serialize.h" #include "util/serialize.h"
#if defined(_WIN32) && !defined(WIN32_NO_ZLIB_WINAPI)
#define ZLIB_WINAPI
#endif
#include "zlib.h" #include "zlib.h"
/* report a zlib or i/o error */ /* report a zlib or i/o error */

View File

@ -1426,7 +1426,7 @@ void Server::SendMovement(session_t peer_id)
void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason) void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
{ {
if (!g_settings->getBool("enable_damage")) if (playersao->isImmortal())
return; return;
session_t peer_id = playersao->getPeerID(); session_t peer_id = playersao->getPeerID();