diff --git a/.gitignore b/.gitignore index 353032637..21e2371a8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,13 +4,16 @@ *bak* tags *.vim +*.orig +*.rej ## Non-static Minetest directories /bin/ /games/* !/games/minimal/ /cache/ -/textures/ +/textures/* +!/textures/base/ /sounds/ /mods/* !/mods/minetest/ @@ -41,7 +44,9 @@ src/cguittfont/libcguittfont.a src/cguittfont/cmake_install.cmake src/cguittfont/Makefile src/json/CMakeFiles/ -src/json/libjson.a +src/json/libjsoncpp.a +src/sqlite/CMakeFiles/* +src/sqlite/libsqlite3.a CMakeCache.txt CPackConfig.cmake CPackSourceConfig.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fbf46d059..437d31cf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ 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 4-d1) +set(VERSION_PATCH 5) if(VERSION_EXTRA) set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA}) endif() @@ -133,6 +133,11 @@ endif() install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client" DESTINATION "${SHAREDIR}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games") +set(COMMON_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/common") +if(EXISTS ${COMMON_SOURCE} AND IS_DIRECTORY ${COMMON_SOURCE}) + install(FILES ${COMMON_SOURCE}/README.txt DESTINATION "${SHAREDIR}/games/common/") + install(DIRECTORY ${COMMON_SOURCE}/mods DESTINATION "${SHAREDIR}/games/common") +endif() set(MINETEST_GAME_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game") if(EXISTS ${MINETEST_GAME_SOURCE} AND IS_DIRECTORY ${MINETEST_GAME_SOURCE}) install(FILES ${MINETEST_GAME_SOURCE}/game.conf DESTINATION "${SHAREDIR}/games/minetest_game/") diff --git a/README.txt b/README.txt index 20917d772..74940a147 100644 --- a/README.txt +++ b/README.txt @@ -9,9 +9,10 @@ and contributors (see source file comments and the version control log) In case you downloaded the source code: --------------------------------------- If you downloaded the Minetest Engine source code in which this file is -contained, you probably want to download the minetest_game project too: +contained, you probably want to download these projects too: + https://github.com/minetest/common/ https://github.com/minetest/minetest_game/ -See the README.txt in it. +See the README.txt in them. Further documentation ---------------------- @@ -80,17 +81,24 @@ Compiling on GNU/Linux: ----------------------- Install dependencies. Here's an example for Debian/Ubuntu: -$ 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 +$ 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 libcurl4-gnutls-dev libfreetype6-dev Download source, extract (this is the URL to the latest of source repository, which might not work at all times): $ wget https://github.com/minetest/minetest/tarball/master -O master.tar.gz $ tar xf master.tar.gz $ cd minetest-minetest-286edd4 (or similar) +Download common (needed for minetest_game and some others) +$ cd games/ +$ wget https://github.com/minetest/common/tarball/master -O common.tar.gz +$ tar xf common.tar.gz +$ mv minetest-common-* common +$ cd .. + Download minetest_game (otherwise only the "Minimal development test" game is available) $ cd games/ -$ wget https://github.com/minetest/minetest_game/tarball/master -O master.tar.gz -$ tar xf master.tar.gz +$ wget https://github.com/minetest/minetest_game/tarball/master -O minetest_game.tar.gz +$ tar xf minetest_game.tar.gz $ mv minetest-minetest_game-* minetest_game $ cd .. @@ -107,11 +115,12 @@ $ ./minetest - 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 +- If you build a bare server, you don't need to have Irrlicht installed. In that case use -DIRRLICHT_SOURCE_DIR=/the/irrlicht/source Compiling on Windows: --------------------- - This section is outdated. In addition to what is described here: - - In addition to minetest, you need to download minetest_game. + - In addition to minetest, you need to download common and minetest_game. - If you wish to have sound support, you need libogg, libvorbis and libopenal - You need: diff --git a/builtin/falling.lua b/builtin/falling.lua index d3af36f29..1c09f9856 100644 --- a/builtin/falling.lua +++ b/builtin/falling.lua @@ -57,6 +57,10 @@ minetest.register_entity("__builtin:falling_node", { -- Note: walkable is in the node definition, not in item groups if minetest.registered_nodes[bcn.name] and minetest.registered_nodes[bcn.name].walkable then + if minetest.registered_nodes[bcn.name].buildable_to then + minetest.env:remove_node(bcp) + return + end local np = {x=bcp.x, y=bcp.y+1, z=bcp.z} -- Check what's here local n2 = minetest.env:get_node(np) @@ -80,6 +84,7 @@ minetest.register_entity("__builtin:falling_node", { -- Create node and remove entity minetest.env:add_node(np, {name=self.nodename}) self.object:remove() + nodeupdate(np) else -- Do nothing end @@ -144,7 +149,8 @@ function nodeupdate_single(p) n_bottom = minetest.env:get_node(p_bottom) -- Note: walkable is in the node definition, not in item groups if minetest.registered_nodes[n_bottom.name] and - not minetest.registered_nodes[n_bottom.name].walkable then + (not minetest.registered_nodes[n_bottom.name].walkable or + minetest.registered_nodes[n_bottom.name].buildable_to) then minetest.env:remove_node(p) spawn_falling_node(p, n.name) nodeupdate(p) diff --git a/builtin/item.lua b/builtin/item.lua index 1349fdf63..8e2f75a1a 100644 --- a/builtin/item.lua +++ b/builtin/item.lua @@ -129,11 +129,18 @@ function minetest.item_place_node(itemstack, placer, pointed_thing) end local under = pointed_thing.under - local oldnode_under = minetest.env:get_node(under) + local oldnode_under = minetest.env:get_node_or_nil(under) + local above = pointed_thing.above + local oldnode_above = minetest.env:get_node_or_nil(above) + + if not oldnode_under or not oldnode_above then + minetest.log("info", placer:get_player_name() .. " tried to place" + .. " node in unloaded position " .. minetest.pos_to_string(above)) + return itemstack + end + local olddef_under = ItemStack({name=oldnode_under.name}):get_definition() olddef_under = olddef_under or minetest.nodedef_default - local above = pointed_thing.above - local oldnode_above = minetest.env:get_node(above) local olddef_above = ItemStack({name=oldnode_above.name}):get_definition() olddef_above = olddef_above or minetest.nodedef_default diff --git a/builtin/item_entity.lua b/builtin/item_entity.lua index 1699cb03c..50ce7eafe 100644 --- a/builtin/item_entity.lua +++ b/builtin/item_entity.lua @@ -111,6 +111,7 @@ minetest.register_entity("__builtin:item", { if self.itemstring ~= '' then local left = hitter:get_inventory():add_item("main", self.itemstring) if not left:is_empty() then + self.itemstring = left:to_string() return end end diff --git a/builtin/misc.lua b/builtin/misc.lua index e018aff85..8308b3d6b 100644 --- a/builtin/misc.lua +++ b/builtin/misc.lua @@ -14,14 +14,14 @@ minetest.register_globalstep(function(dtime) for index, timer in ipairs(minetest.timers) do timer.time = timer.time - dtime if timer.time <= 0 then - timer.func(timer.param) + timer.func(unpack(timer.args or {})) 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}) +function minetest.after(time, func, ...) + table.insert(minetest.timers_to_add, {time=time, func=func, args={...}}) end function minetest.check_player_privs(name, privs) @@ -99,3 +99,10 @@ function minetest.setting_get_pos(name) return minetest.string_to_pos(value) end +function minetest.formspec_escape(str) + str = string.gsub(str, "\\", "\\\\") + str = string.gsub(str, "%[", "\\[") + str = string.gsub(str, "%]", "\\]") + return str +end + diff --git a/client/shaders/test_shader_2/opengl_vertex.glsl b/client/shaders/test_shader_2/opengl_vertex.glsl index 80fd6d427..2881bad21 100644 --- a/client/shaders/test_shader_2/opengl_vertex.glsl +++ b/client/shaders/test_shader_2/opengl_vertex.glsl @@ -8,9 +8,7 @@ varying vec3 vPosition; void main(void) { - vec4 pos = gl_Vertex; - pos.y -= 2.0; - gl_Position = mWorldViewProj * pos; + gl_Position = mWorldViewProj * gl_Vertex; vPosition = (mWorldViewProj * gl_Vertex).xyz; diff --git a/cmake/Modules/FindJson.cmake b/cmake/Modules/FindJson.cmake index bc4e71a29..a9178a225 100644 --- a/cmake/Modules/FindJson.cmake +++ b/cmake/Modules/FindJson.cmake @@ -2,17 +2,17 @@ #FIND_PATH(JSON_INCLUDE_DIR json.h) -#FIND_LIBRARY(JSON_LIBRARY NAMES json) +#FIND_LIBRARY(JSON_LIBRARY NAMES jsoncpp) #IF(JSON_LIBRARY AND JSON_INCLUDE_DIR) # SET( JSON_FOUND TRUE ) #ENDIF(JSON_LIBRARY AND JSON_INCLUDE_DIR) #IF(JSON_FOUND) -# MESSAGE(STATUS "Found system json header file in ${JSON_INCLUDE_DIR}") -# MESSAGE(STATUS "Found system json library ${JSON_LIBRARY}") +# MESSAGE(STATUS "Found system jsoncpp header file in ${JSON_INCLUDE_DIR}") +# MESSAGE(STATUS "Found system jsoncpp library ${JSON_LIBRARY}") #ELSE(JSON_FOUND) SET(JSON_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/json) - SET(JSON_LIBRARY json) - MESSAGE(STATUS "Using project json library") + SET(JSON_LIBRARY jsoncpp) + MESSAGE(STATUS "Using project jsoncpp library") #ENDIF(JSON_FOUND) diff --git a/cmake/Modules/FindOpenGLES2.cmake b/cmake/Modules/FindOpenGLES2.cmake new file mode 100644 index 000000000..42d31c898 --- /dev/null +++ b/cmake/Modules/FindOpenGLES2.cmake @@ -0,0 +1,130 @@ +#------------------------------------------------------------------- +# This file is stolen from part of the CMake build system for OGRE (Object-oriented Graphics Rendering Engine) http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- + +# - Try to find OpenGLES and EGL +# Once done this will define +# +# OPENGLES2_FOUND - system has OpenGLES +# OPENGLES2_INCLUDE_DIR - the GL include directory +# OPENGLES2_LIBRARIES - Link these to use OpenGLES +# +# EGL_FOUND - system has EGL +# EGL_INCLUDE_DIR - the EGL include directory +# EGL_LIBRARIES - Link these to use EGL + +# win32, apple, android NOT TESED +# linux tested and works + +IF (WIN32) + IF (CYGWIN) + + FIND_PATH(OPENGLES2_INCLUDE_DIR GLES2/gl2.h ) + + FIND_LIBRARY(OPENGLES2_gl_LIBRARY libGLESv2 ) + + ELSE (CYGWIN) + + IF(BORLAND) + SET (OPENGLES2_gl_LIBRARY import32 CACHE STRING "OpenGL ES 2.x library for win32") + ELSE(BORLAND) + # todo + # SET (OPENGLES_gl_LIBRARY ${SOURCE_DIR}/Dependencies/lib/release/libGLESv2.lib CACHE STRING "OpenGL ES 2.x library for win32" + ENDIF(BORLAND) + + ENDIF (CYGWIN) + +ELSE (WIN32) + + IF (APPLE) + + create_search_paths(/Developer/Platforms) + findpkg_framework(OpenGLES2) + set(OPENGLES2_gl_LIBRARY "-framework OpenGLES") + + ELSE(APPLE) + + FIND_PATH(OPENGLES2_INCLUDE_DIR GLES2/gl2.h + /usr/openwin/share/include + /opt/graphics/OpenGL/include /usr/X11R6/include + /usr/include + ) + + FIND_LIBRARY(OPENGLES2_gl_LIBRARY + NAMES GLESv2 + PATHS /opt/graphics/OpenGL/lib + /usr/openwin/lib + /usr/shlib /usr/X11R6/lib + /usr/lib + ) + + IF (NOT BUILD_ANDROID) + FIND_PATH(EGL_INCLUDE_DIR EGL/egl.h + /usr/openwin/share/include + /opt/graphics/OpenGL/include /usr/X11R6/include + /usr/include + ) + + FIND_LIBRARY(EGL_egl_LIBRARY + NAMES EGL + PATHS /opt/graphics/OpenGL/lib + /usr/openwin/lib + /usr/shlib /usr/X11R6/lib + /usr/lib + ) + + # On Unix OpenGL most certainly always requires X11. + # Feel free to tighten up these conditions if you don't + # think this is always true. + # It's not true on OSX. + + IF (OPENGLES2_gl_LIBRARY) + IF(NOT X11_FOUND) + INCLUDE(FindX11) + ENDIF(NOT X11_FOUND) + IF (X11_FOUND) + IF (NOT APPLE) + SET (OPENGLES2_LIBRARIES ${X11_LIBRARIES}) + ENDIF (NOT APPLE) + ENDIF (X11_FOUND) + ENDIF (OPENGLES2_gl_LIBRARY) + ENDIF () + + ENDIF(APPLE) +ENDIF (WIN32) + +#SET( OPENGLES2_LIBRARIES ${OPENGLES2_gl_LIBRARY} ${OPENGLES2_LIBRARIES}) + +IF (BUILD_ANDROID) + IF(OPENGLES2_gl_LIBRARY) + SET( OPENGLES2_LIBRARIES ${OPENGLES2_gl_LIBRARY} ${OPENGLES2_LIBRARIES}) + SET( EGL_LIBRARIES) + SET( OPENGLES2_FOUND "YES" ) + ENDIF(OPENGLES2_gl_LIBRARY) +ELSE () + + SET( OPENGLES2_LIBRARIES ${OPENGLES2_gl_LIBRARY} ${OPENGLES2_LIBRARIES}) + + IF(OPENGLES2_gl_LIBRARY AND EGL_egl_LIBRARY) + SET( OPENGLES2_LIBRARIES ${OPENGLES2_gl_LIBRARY} ${OPENGLES2_LIBRARIES}) + SET( EGL_LIBRARIES ${EGL_egl_LIBRARY} ${EGL_LIBRARIES}) + SET( OPENGLES2_FOUND "YES" ) + ENDIF(OPENGLES2_gl_LIBRARY AND EGL_egl_LIBRARY) + +ENDIF () + +MARK_AS_ADVANCED( + OPENGLES2_INCLUDE_DIR + OPENGLES2_gl_LIBRARY + EGL_INCLUDE_DIR + EGL_egl_LIBRARY +) + +IF(OPENGLES2_FOUND) + MESSAGE(STATUS "Found system opengles2 library ${OPENGLES2_LIBRARIES}") +ELSE () + SET(OPENGLES2_LIBRARIES "") +ENDIF () diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 005d7c010..beb70db15 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1,4 +1,4 @@ -Minetest Lua Modding API Reference 0.4.4 +Minetest Lua Modding API Reference 0.4.5 ========================================== More information at http://c55.me/minetest/ @@ -27,6 +27,39 @@ Startup Mods are loaded during server startup from the mod load paths by running the init.lua scripts in a shared environment. +Paths +----- +RUN_IN_PLACE=1: (Windows release, local build) + $path_user: Linux: + Windows: + $path_share: Linux: + Windows: + +RUN_IN_PLACE=0: (Linux release) + $path_share: Linux: /usr/share/minetest + Windows: /minetest-0.4.x + $path_user: Linux: ~/.minetest + Windows: C:/users//AppData/minetest (maybe) + +Games +----- +Games are looked up from: + $path_share/games/gameid/ + $path_user/games/gameid/ +where gameid is unique to each game. + +The game directory contains the file game.conf, which contains these fields: + name = + common_mods = +eg. + name = Minetest + common_mods = bucket, default, doors, fire, stairs + +Common mods are loaded from the pseudo-game "common". + +The game directory can contain the file minetest.conf, which will be used +to set default settings when running the particular game. + Mod load path ------------- Generic: @@ -170,18 +203,18 @@ from the available ones of the following files: Examples of sound parameter tables: -- Play locationless on all clients { - gain = 1.0, -- default + gain = 1.0, -- default } -- Play locationless to a player { - to_player = name, - gain = 1.0, -- default + to_player = name, + gain = 1.0, -- default } -- Play in a location { - pos = {x=1,y=2,z=3}, - gain = 1.0, -- default - max_hear_distance = 32, -- default + pos = {x=1,y=2,z=3}, + gain = 1.0, -- default + max_hear_distance = 32, -- default } -- Play connected to an object, looped { @@ -233,11 +266,11 @@ local drawtype = get_nodedef_field(nodename, "drawtype") Example: minetest.get_item_group(name, group) has been implemented as: 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] + 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 Nodes @@ -277,6 +310,10 @@ param2 is reserved for the engine when any of these are used: paramtype2 == "facedir" ^ The rotation of the node is stored in param2. Furnaces and chests are rotated this way. Can be made by using minetest.dir_to_facedir(). + Values range 0 - 23 + facedir modulo 4 = axisdir + 0 = y+ 1 = z+ 2 = z- 3 = x+ 4 = x- 5 = y- + facedir's two less significant bits are rotation around the axis Nodes can also contain extra data. See "Node Metadata". @@ -335,6 +372,28 @@ A box is defined as: A box of a regular node would look like: {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, +Ore types +--------------- +These tell in what manner the ore is generated. +All default ores are of the uniformly-distributed scatter type. + +- scatter + Randomly chooses a location and generates a cluster of ore. + If noise_params is specified, the ore will be placed if the 3d perlin noise at + that point is greater than the noise_threshhold, giving the ability to create a non-equal + distribution of ore. +- sheet + Creates a sheet of ore in a blob shape according to the 2d perlin noise described by noise_params. + The relative height of the sheet can be controlled by the same perlin noise as well, by specifying + a non-zero 'scale' parameter in noise_params. IMPORTANT: The noise is not transformed by offset or + scale when comparing against the noise threshhold, but scale is used to determine relative height. + The height of the blob is randomly scattered, with a maximum height of clust_size. + clust_scarcity and clust_num_ores are ignored. + This is essentially an improved version of the so-called "stratus" ore seen in some unofficial mods. +- claylike - NOT YET IMPLEMENTED + Places ore if there are no more than clust_scarcity number of specified nodes within a Von Neumann + neighborhood of clust_size radius. + Representations of simple things -------------------------------- Position/vector: @@ -412,9 +471,11 @@ a node is destroyable and how long it takes to destroy by a tool. Groups of entities ------------------- For entities, groups are, as of now, used only for calculating damage. +The rating is the percentage of damage caused by tools with this damage group. +See "Entity damage mechanism". -object.get_armor_groups() -> a group-rating table (eg. {fleshy=3}) -object.set_armor_groups({level=2, fleshy=2, cracky=2}) +object.get_armor_groups() -> a group-rating table (eg. {fleshy=100}) +object.set_armor_groups({fleshy=30, cracky=80}) Groups of tools ---------------- @@ -435,7 +496,7 @@ An example: Make meat soup from any meat, any water and any bowl } An another example: Make red wool from white wool and red dye { - type = 'shapeless', + type = 'shapeless', output = 'wool:red', recipe = {'wool:white', 'group:dye,basecolor_red'}, } @@ -446,7 +507,7 @@ Special groups - level: Can be used to give an additional sense of progression in the game. - A larger level will cause eg. a weapon of a lower level make much less damage, and get weared out much faster, or not be able to get drops - from destroyed nodes. + from destroyed nodes. - 0 is something that is directly accessible at the start of gameplay - There is no upper limit - dig_immediate: (player can always pick up node without tool wear) @@ -463,7 +524,6 @@ Special groups Known damage and digging time defining groups ---------------------------------------------- -Valid ratings for these are 0, 1, 2 and 3, unless otherwise stated. - crumbly: dirt, sand - cracky: tough but crackable stuff like stone. - snappy: something that can be cut using fine tools; eg. leaves, small @@ -516,6 +576,7 @@ groups to enable interaction with tools. * Uses (until the tool breaks) * Maximum level (usually 0, 1, 2 or 3) * Digging times + * Damage groups **Full punch interval**: When used as a weapon, the tool will do full damage if this time is spent @@ -547,17 +608,19 @@ maximum level. result in the tool to be able to dig nodes that have a rating of 2 or 3 for this group, and unable to dig the rating 1, which is the toughest. Unless there is a matching group that enables digging otherwise. - * For entities, damage equals the amount of nodes dug in the time spent - between hits, with a maximum time of ''full_punch_interval''. + +**Damage groups** +List of damage for groups of entities. See "Entity damage mechanism". Example definition of the capabilities of a tool ------------------------------------------------- tool_capabilities = { - full_punch_interval=1.5, - max_drop_level=1, - groupcaps={ - crumbly={maxlevel=2, uses=20, times={[1]=1.60, [2]=1.20, [3]=0.80}} - } + full_punch_interval=1.5, + max_drop_level=1, + groupcaps={ + crumbly={maxlevel=2, uses=20, times={[1]=1.60, [2]=1.20, [3]=0.80}} + } + damage_groups = {fleshy=2}, } This makes the tool be able to dig nodes that fullfill both of these: @@ -588,10 +651,12 @@ Notes: Entity damage mechanism ------------------------ Damage calculation: -- Take the time spent after the last hit -- Limit time to full_punch_interval -- Take the damage groups and imagine a bunch of nodes that have them -- Damage in HP is the amount of nodes destroyed in this time. +damage = 0 +foreach group in cap.damage_groups: + damage += cap.damage_groups[group] * limit(actual_interval / cap.full_punch_interval, 0.0, 1.0) + * (object.armor_groups[group] / 100.0) + -- Where object.armor_groups[group] is 0 for inexisting values +return damage Client predicts damage based on damage groups. Because of this, it is able to give an immediate response when an entity is damaged or dies; the response is @@ -717,7 +782,7 @@ field[,;,;;