Compare commits

...

123 Commits

Author SHA1 Message Date
Perttu Ahola
d38b465b7c Call this 0.4.2-rc1 2012-07-28 16:31:45 +03:00
Perttu Ahola
fd7ec2da91 Fix inventory segfault when rollback recording is disabled 2012-07-28 14:44:18 +03:00
Perttu Ahola
c9ed379e39 Add enable_rollback_recording setting, defaulting to false 2012-07-28 03:08:09 +03:00
Perttu Ahola
e64feefc61 Handle max<min in LuaPseudoRandom::l_next() 2012-07-27 19:03:15 +03:00
Perttu Ahola
3e754382af Tweak rollback and liquids 2012-07-27 15:46:51 +03:00
Perttu Ahola
7ef0a13250 Tweak rollback stuff 2012-07-27 14:52:29 +03:00
Perttu Ahola
0de3fb786d Increase automatic suspect guess timeframe 2012-07-27 13:54:14 +03:00
Perttu Ahola
1d44a98f2f ABM and liquid overload skip 2012-07-27 13:45:49 +03:00
Perttu Ahola
98ff4eb4ee Fix server build (a missing header) 2012-07-27 13:43:25 +03:00
Perttu Ahola
a9d8df83d2 Make the rollback system VERY FUCKING GOD DAMN POWERFUL 2012-07-27 13:24:28 +03:00
Perttu Ahola
508b7b5e51 Don't track liquids for rollback because of too much log 2012-07-27 02:46:54 +03:00
Perttu Ahola
f7dc72f8aa Properly rollback chat command triggered things 2012-07-27 02:37:04 +03:00
Perttu Ahola
0190f9b077 Experimental-ish rollback functionality 2012-07-27 02:27:18 +03:00
Perttu Ahola
0c91a0d59d Working group-shapeless and multigroup recipes 2012-07-26 13:49:13 +03:00
Perttu Ahola
a26a66a8c4 Restore focus to formspec menu when pressing a button 2012-07-25 18:28:40 +03:00
Perttu Ahola
100345f1e4 Deprecate minetest.add_to_creative_inventory and use group not_in_creative_inventory instead 2012-07-25 18:05:31 +03:00
Perttu Ahola
4535166a3b Add notice in the minimal game 2012-07-25 17:10:31 +03:00
Perttu Ahola
0346e68deb Add special return value -1 to inventry callbacks 2012-07-25 16:52:00 +03:00
Perttu Ahola
db62c227c8 Improve formspec positioning 2012-07-25 16:30:23 +03:00
Perttu Ahola
983e45ae92 Improve inventory callbacks a bit 2012-07-25 15:39:39 +03:00
Perttu Ahola
0a18dda158 Remove special handling of creative mode 2012-07-25 14:07:45 +03:00
Perttu Ahola
9eaf93d41d Detached inventory callbacks and reworked node metadata callbacks 2012-07-25 02:36:54 +03:00
Perttu Ahola
2ac20982e0 Detached inventories 2012-07-24 20:57:17 +03:00
Perttu Ahola
96eac87d47 builtin/item.lua: callbacks with copies of positions and nodes rather than recycle the same ones, which callbacks can modify 2012-07-24 17:46:17 +03:00
Perttu Ahola
0cf1ed544c darkrose should work at a nuclear power plant.
It'd take years to figure out what caused the accident.
2012-07-24 16:36:50 +03:00
Perttu Ahola
558e284e25 Update minetestmapper.py to support ver. 24 and 25 2012-07-24 15:17:00 +03:00
Perttu Ahola
5c31445117 Improve node timer format (map format version 25) and update mapformat.txt 2012-07-24 15:03:46 +03:00
Perttu Ahola
717ae67995 Add node timer test in minimal/experimental 2012-07-24 14:51:13 +03:00
Perttu Ahola
e8331f0c1d Add oldnode parameter to minetest.register_on_placenode callback 2012-07-23 20:44:56 +03:00
Perttu Ahola
c009aa3a22 Fix building on top of (pointable && buildable_to) nodes 2012-07-23 20:42:08 +03:00
Perttu Ahola
9af9d8f5d0 Describe node definition fields better in lua_api.txt 2012-07-23 20:17:44 +03:00
Perttu Ahola
2c027b03db Move /give, /giveme, /spawnentity and /pulverize to builtin/chatcommands.lua 2012-07-23 17:43:08 +03:00
Perttu Ahola
aef1332e42 Improve build configuration options 2012-07-23 15:23:33 +03:00
Perttu Ahola
16fc8b5fc2 Update lua_api.txt a bit 2012-07-23 08:48:55 +03:00
Perttu Ahola
fd845f27f5 Fix map deserialization and remove old serialization code 2012-07-23 08:18:39 +03:00
darkrose
ea62ee4b61 Increase node id/param0 to 16 bits, leaving param2 always with 8 bits 2012-07-23 08:18:39 +03:00
darkrose
cd6becd442 Implement node timers 2012-07-23 08:18:37 +03:00
Perttu Ahola
829f262c79 Fix terrible grammar in comment! 2012-07-22 20:36:06 +03:00
Perttu Ahola
246520b5cb Fix compressZlib() 2012-07-22 20:29:09 +03:00
Perttu Ahola
38bb649582 Test zlib wrapper's handling of large data 2012-07-22 20:27:55 +03:00
Perttu Ahola
82855a04ec Tweak test.c overally a bit 2012-07-22 20:26:54 +03:00
Perttu Ahola
6dfefaf229 Formspec button_exit[] and image_button_exit[] 2012-07-22 17:40:48 +03:00
darkrose
d44f8a854b Doc updates for formspec 2012-07-22 17:40:48 +03:00
Perttu Ahola
acf3a43095 Add /test1 command to minimal for testing a more complicated player inventory form 2012-07-22 17:40:48 +03:00
Perttu Ahola
4cc98d7add minetest.register_on_player_receive_fields() 2012-07-22 17:40:48 +03:00
darkrose
506203345b Implement formspec 2012-07-22 17:40:41 +03:00
Matthew I
c259f7c8bd Update Lua API documentation to include minetest.get_modnames() 2012-07-22 13:36:17 +03:00
Matthew I
c62a121cca Add "/mods" command to list mods to client 2012-07-22 13:36:10 +03:00
Matthew I
136eb32389 Add minetest.get_modnames() to Lua API 2012-07-22 13:36:03 +03:00
Perttu Ahola
e3ddbe8c6b Version 0.4.1 2012-07-21 23:14:23 +03:00
Andreas Zwinkau
d085139057 Fix signedness warning in base64.cpp 2012-07-21 22:10:29 +03:00
Andreas Zwinkau
28e7443f9b Fix wctomb use
wctomb(NULL, _) returns "nonzero if the encoding has nontrivial shift state, or zero if the encoding is stateless."

I assume the intentation was to get the size of the target buffer.
Use MB_CUR_MAX for this.
2012-07-21 22:09:17 +03:00
Andreas Zwinkau
e79ad21aeb Remove mbtowc warnings
As mbtowc(_, _, 1) reads at most one char, everything other than a
return value of 1 is an error. Since the input strings are static,
an assert protects against future changes.

Likewise, wctomb should currently never encounter a character, which
actually needs a multibyte representation.
2012-07-21 22:08:20 +03:00
Perttu Ahola
0b61253931 Actually fix facedir-rotated nodes placed using minetest.env:place_node() 2012-07-21 21:23:15 +03:00
Matthew I
a2738dec59 Fix hovering after mining a block underneath you while sneaking 2012-07-21 20:56:56 +03:00
Perttu Ahola
1788709e2d Rotate facedir-rotated top and bottom textures too, and re-implement nodebox side rotation 2012-07-21 20:23:32 +03:00
Perttu Ahola
47d30d12cb Facedir rotation of nodebox textures 2012-07-21 18:59:12 +03:00
Perttu Ahola
43df78102c Check whether node is known before reading definition in __builtin:item:on_step() 2012-07-21 16:36:14 +03:00
Bad-Command
cc10eec6c6 Fix signed overflow in getPointedThing 2012-07-21 16:13:51 +03:00
Perttu Ahola
15bf9a7026 Fix typo in scriptapi.cpp in minetest.get_craft_recipe() 2012-07-21 15:32:46 +03:00
Perttu Ahola
2795f44f03 Server-side checking of digging; disable_anticheat setting 2012-07-21 14:38:49 +03:00
Perttu Ahola
b0ba05c9ac BITCH, THIS IS 0.4.0. 2012-07-21 03:37:07 +03:00
Perttu Ahola
71c6845a94 Define M_PI on MSVC 2012-07-21 03:36:34 +03:00
Perttu Ahola
4b97023251 Add a random-ish contributor list to credit screen 2012-07-21 03:14:58 +03:00
darkrose
369046bbb4 Check for table type when reading groups from Lua 2012-07-21 02:35:45 +03:00
darkrose
38580fbee7 Add minetest.get_craft_recipe() 2012-07-21 02:33:22 +03:00
darkrose
08e1d40d6e Add support for "textures/all" (and thus texture packs) to server 2012-07-21 02:33:19 +03:00
darkrose
80f35467d8 Make lava buckets work as fuel in minimal game 2012-07-21 02:33:11 +03:00
darkrose
1b19020bf4 Remove trenches from map generator (cyisfor) (glitches: read below)
This causes glitches in very high cliffs by not making mud "flow" down from
them. Those are quite rare currently because of the lame height differences
generated.
2012-07-21 02:32:04 +03:00
Calinou
61e58ee9b7 Message cleanups (consistency) and prevent /me when not allowed to shout 2012-07-21 02:27:58 +03:00
darkrose
f21af8da9c Handle nil placer as it might occur when using minetest.env:place_node. (Uberi) 2012-07-21 02:27:46 +03:00
Perttu Ahola
dece3a3600 Remove util/old/genmap.py, because it is uselessly old 2012-07-19 21:17:31 +03:00
Perttu Ahola
16ad10e62f Allow defining player's inventory form in Lua 2012-07-19 14:09:16 +03:00
Perttu Ahola
02fb912a95 Fix /builtin/misc.lua:47: attempt to call method 'is_player' (a nil value) 2012-06-19 00:50:07 +03:00
Perttu Ahola
48790c0751 Fix random glitches in transparent animations 2012-06-18 00:21:23 +03:00
Perttu Ahola
c57e5083e8 Add pointed_thing to lua_api.txt 2012-06-17 19:47:55 +03:00
Perttu Ahola
c9a2058361 Hopefully fix includes on mingw 2012-06-17 18:05:13 +03:00
Perttu Ahola
7039dfafd6 Increment protocol version 2012-06-17 17:49:12 +03:00
Perttu Ahola
22ae83a589 Explain node boxes in lua_api.txt 2012-06-17 17:23:58 +03:00
Kahrl
1575448b1a Custom boxy nodes (stairs, slabs) and collision changes 2012-06-17 16:34:39 +03:00
Perttu Ahola
9f031a6759 Optimize headers 2012-06-17 04:03:39 +03:00
Perttu Ahola
d0ea6f9920 Properly and efficiently use split utility headers 2012-06-17 02:40:36 +03:00
Perttu Ahola
1bc37d576c Initially split utility.h to multiple files in util/ 2012-06-17 01:29:13 +03:00
Perttu Ahola
d159591b9a Mention node drawtypes in lua_api.txt 2012-06-16 23:42:04 +03:00
Perttu Ahola
57550b2b3d Fix /setpassword and /clearpassword 2012-06-16 23:35:11 +03:00
Perttu Ahola
d15d6c4e6b Fix "Node placement prediction failed for (places __default) - Name not known" 2012-06-16 22:45:35 +03:00
Perttu Ahola
6b598f61a6 Add desynchronize_mapblock_texture_animation setting and improve minetest.conf.example a bit 2012-06-16 22:37:20 +03:00
Perttu Ahola
9e21204f8b Fix build error due to DEBUGFILE 2012-06-16 21:36:54 +03:00
Perttu Ahola
e6b86fa304 Revert back proper crack texture 2012-06-16 20:48:05 +03:00
Perttu Ahola
268e50dfbd Clean up constants.h a bit 2012-06-16 18:15:06 +03:00
Perttu Ahola
07ccc15fc2 Allow node cracking animations of any length 2012-06-16 18:02:56 +03:00
Perttu Ahola
2b500d72e5 Remove tiles and special_tiles from node definition prototype because otherwise the old names can't be used 2012-06-16 18:02:26 +03:00
Perttu Ahola
cd0014b24f Update field names to non-deprecated ones in node definition prototype 2012-06-16 17:05:21 +03:00
Perttu Ahola
b3786d84c5 Use new field names and reorder fields a bit in minimal game 2012-06-16 16:47:41 +03:00
Perttu Ahola
fd1135c7af Node texture animation 2012-06-16 16:47:28 +03:00
Perttu Ahola
f0678979b1 Add comment about ItemSAO being deprecated 2012-06-11 22:10:48 +03:00
Perttu Ahola
f4a7e11bce Add some missing object properties to doc/lua_api.txt 2012-06-10 15:04:24 +03:00
Perttu Ahola
6a0388bb4b Node placement client-side prediction 2012-06-10 12:46:48 +03:00
Perttu Ahola
7ba72f2763 Remove a random old comment and a #define from game.cpp 2012-06-09 13:40:07 +03:00
Perttu Ahola
f7147d9c0a Add experimental_tester_tool_1.png to minimal game (was accidentally left out) 2012-06-08 16:46:02 +03:00
Perttu Ahola
523a5fd2e5 Move genmap.py and pnoise.py to old/ 2012-06-08 15:50:27 +03:00
Perttu Ahola
ff85e2343c Update minetestmapper.py to support the current map format (and previous ones) 2012-06-08 15:17:03 +03:00
Perttu Ahola
e74668ef7f Update and fix doc/mapformat.txt; make current format more solid in mapblock.cpp 2012-06-08 14:57:02 +03:00
Perttu Ahola
22502f80db Don't deprecate minetest.register_on_placenode and minetest.register_on_dignode 2012-06-08 01:51:23 +03:00
Perttu Ahola
4b2cc38aba Add disallow_empty_password setting 2012-06-07 02:11:28 +03:00
Perttu Ahola
a8eb68142e Call this 0.4.dev-20120606 2012-06-07 00:40:04 +03:00
Perttu Ahola
81554fbf72 Add minetest.serialize() and minetest.deserialize() 2012-06-07 00:05:00 +03:00
Perttu Ahola
a435cfcd82 Allow groups in crafting recipes 2012-06-06 23:39:17 +03:00
Perttu Ahola
7631918a12 Remove obsolete "footprints" default setting from defaultsettings.cpp 2012-06-06 20:04:05 +03:00
Kahrl
e070f1e525 Allow replacements in cooking and fuel recipes 2012-06-06 00:22:34 +03:00
Perttu Ahola
430d6e1cca Fix small errors in lua_api.txt 2012-06-06 00:15:33 +03:00
Perttu Ahola
3a0562bebc Add after_destruct and cache the existence of on_construct, on_destruct and after_destruct for quick skipping when a node does not have them 2012-06-05 23:51:37 +03:00
Perttu Ahola
c3658e7c79 place_node, dig_node and punch_node; an in-game tester tool; remove old code 2012-06-05 23:10:07 +03:00
Perttu Ahola
b0f81c3253 Fix NDT_RAILLIKE tweakings 2012-06-05 21:51:01 +03:00
darkrose
31c171fc1e Shadily clean up NDT_RAILLIKE to surely differ from the few leftover non-LGPLv2 parts from the standpoint of copyright law. 2012-06-05 19:47:19 +03:00
Perttu Ahola
e9c123b1b9 Clean and optimize clouds.cpp enough to not really contain any of the small amount of non-LGPLv2/later code left 2012-06-05 18:54:42 +03:00
Perttu Ahola
037b259197 Switch the license to be LGPLv2/later, with small parts still remaining as GPLv2/later, by agreement of major contributors 2012-06-05 18:54:07 +03:00
Perttu Ahola
a569961e0f Update translation template po/minetest.pot 2012-06-04 23:29:14 +03:00
Perttu Ahola
7eabde6aee Use gettext for more basic user interface strings 2012-06-04 23:24:31 +03:00
Perttu Ahola
ed772da0cc Remove misdesigned exception from ReliablePacketBuffer 2012-06-04 22:43:33 +03:00
Perttu Ahola
f48882213e Add ignore_world_load_errors configuration option and provide better error messages 2012-06-04 22:34:40 +03:00
Perttu Ahola
1cd2076d42 Improve GUIMessageMenu (move and resize elements based on size of text) 2012-06-04 22:33:47 +03:00
Perttu Ahola
816b9c8d71 Fix loading of old signs 2012-06-04 18:19:23 +03:00
242 changed files with 12372 additions and 7039 deletions

View File

@@ -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 dev-20120603)
set(VERSION_PATCH 2-rc1)
if(VERSION_EXTRA)
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
endif()
@@ -62,7 +62,7 @@ if(WIN32)
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(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}")
set(BINDIR "bin")
set(DOCDIR "share/doc/${PROJECT_NAME}")
set(EXAMPLE_CONF_DIR ${DOCDIR})
@@ -78,17 +78,58 @@ elseif(UNIX) # Linux, BSD etc
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(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}")
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
set(DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}")
set(MANDIR "${CMAKE_INSTALL_PREFIX}/share/man")
set(EXAMPLE_CONF_DIR ${DOCDIR})
set(XDG_APPS_DIR "share/applications")
set(ICONDIR "share/icons")
set(LOCALEDIR "share/locale")
set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
set(ICONDIR "${CMAKE_INSTALL_PREFIX}/share/icons")
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale")
endif()
endif()
set(CUSTOM_SHAREDIR "" CACHE STRING "Directory to install data files into")
if(NOT CUSTOM_SHAREDIR STREQUAL "")
set(SHAREDIR "${CUSTOM_SHAREDIR}")
message(STATUS "Using SHAREDIR=${SHAREDIR}")
endif()
set(CUSTOM_BINDIR "" CACHE STRING "Directory to install binaries into")
if(NOT CUSTOM_BINDIR STREQUAL "")
set(BINDIR "${CUSTOM_BINDIR}")
message(STATUS "Using BINDIR=${BINDIR}")
endif()
set(CUSTOM_DOCDIR "" CACHE STRING "Directory to install documentation into")
if(NOT CUSTOM_DOCDIR STREQUAL "")
set(DOCDIR "${CUSTOM_DOCDIR}")
message(STATUS "Using DOCDIR=${DOCDIR}")
endif()
set(CUSTOM_MANDIR "" CACHE STRING "Directory to install manpages into")
if(NOT CUSTOM_MANDIR STREQUAL "")
set(MANDIR "${CUSTOM_MANDIR}")
message(STATUS "Using MANDIR=${MANDIR}")
endif()
set(CUSTOM_EXAMPLE_CONF_DIR "" CACHE STRING "Directory to install example config file into")
if(NOT CUSTOM_EXAMPLE_CONF_DIR STREQUAL "")
set(EXAMPLE_CONF_DIR "${CUSTOM_EXAMPLE_CONF_DIR}")
message(STATUS "Using EXAMPLE_CONF_DIR=${EXAMPLE_CONF_DIR}")
endif()
set(CUSTOM_XDG_APPS_DIR "" CACHE STRING "Directory to install .desktop files into")
if(NOT CUSTOM_XDG_APPS_DIR STREQUAL "")
set(XDG_APPS_DIR "${CUSTOM_XDG_APPS_DIR}")
message(STATUS "Using XDG_APPS_DIR=${XDG_APPS_DIR}")
endif()
set(CUSTOM_ICONDIR "" CACHE STRING "Directory to install icons into")
if(NOT CUSTOM_ICONDIR STREQUAL "")
set(ICONDIR "${CUSTOM_ICONDIR}")
message(STATUS "Using ICONDIR=${ICONDIR}")
endif()
set(CUSTOM_LOCALEDIR "" CACHE STRING "Directory to install l10n files into")
if(NOT CUSTOM_LOCALEDIR STREQUAL "")
set(LOCALEDIR "${CUSTOM_LOCALEDIR}")
message(STATUS "Using LOCALEDIR=${LOCALEDIR}")
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_game")

View File

@@ -260,8 +260,8 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -269,7 +269,7 @@ 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
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

View File

@@ -10,6 +10,7 @@ print = minetest.debug
math.randomseed(os.time())
-- Load other files
dofile(minetest.get_modpath("__builtin").."/serialize.lua")
dofile(minetest.get_modpath("__builtin").."/misc_helpers.lua")
dofile(minetest.get_modpath("__builtin").."/item.lua")
dofile(minetest.get_modpath("__builtin").."/misc_register.lua")
@@ -20,4 +21,5 @@ 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")
dofile(minetest.get_modpath("__builtin").."/detached_inventory.lua")

View File

@@ -41,7 +41,7 @@ end)
--
-- Register C++ commands without functions
minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)"})
minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)", privs = {shout=true}})
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}})
@@ -193,12 +193,27 @@ minetest.register_chatcommand("setpassword", {
description = "set given password",
privs = {password=true},
func = function(name, param)
if param == "" then
minetest.chat_send_player(name, "Password field required")
local toname, raw_password = string.match(param, "^([^ ]+) +(.+)$")
if not toname then
toname = string.match(param, "^([^ ]+) *$")
raw_password = nil
end
if not toname then
minetest.chat_send_player(name, "Name field required")
return
end
minetest.set_player_password(name, param)
minetest.chat_send_player(name, "Password set")
local actstr = "?"
if not raw_password then
minetest.set_player_password(toname, "")
actstr = "cleared"
else
minetest.set_player_password(toname, minetest.get_password_hash(toname, raw_password))
actstr = "set"
end
minetest.chat_send_player(name, "Password of player \""..toname.."\" "..actstr)
if toname ~= name then
minetest.chat_send_player(toname, "Your password was "..actstr.." by "..name)
end
end,
})
minetest.register_chatcommand("clearpassword", {
@@ -206,8 +221,13 @@ minetest.register_chatcommand("clearpassword", {
description = "set empty password",
privs = {password=true},
func = function(name, param)
minetest.set_player_password(name, '')
minetest.chat_send_player(name, "Password cleared")
toname = param
if not toname then
minetest.chat_send_player(toname, "Name field required")
return
end
minetest.set_player_password(toname, '')
minetest.chat_send_player(name, "Password of player \""..toname.."\" cleared")
end,
})
@@ -351,3 +371,207 @@ minetest.register_chatcommand("set", {
end,
})
minetest.register_chatcommand("mods", {
params = "",
description = "lists mods installed on the server",
privs = {},
func = function(name, param)
local response = ""
local modnames = minetest.get_modnames()
for i, mod in ipairs(modnames) do
response = response .. mod
-- Add space if not at the end
if i ~= #modnames then
response = response .. " "
end
end
minetest.chat_send_player(name, response)
end,
})
local function handle_give_command(cmd, giver, receiver, stackstring)
minetest.log("action", giver.." invoked "..cmd..', 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_chatcommand("give", {
params = "<name> <itemstring>",
description = "give item to player",
privs = {give=true},
func = function(name, param)
local toname, itemstring = string.match(param, "^([^ ]+) +(.+)$")
if not toname or not itemstring then
minetest.chat_send_player(name, "name and itemstring required")
return
end
handle_give_command("/give", name, toname, itemstring)
end,
})
minetest.register_chatcommand("giveme", {
params = "<itemstring>",
description = "give item to yourself",
privs = {give=true},
func = function(name, param)
local itemstring = string.match(param, "(.+)$")
if not itemstring then
minetest.chat_send_player(name, "itemstring required")
return
end
handle_give_command("/giveme", name, name, itemstring)
end,
})
minetest.register_chatcommand("spawnentity", {
params = "<entityname>",
description = "spawn entity at your position",
privs = {give=true, interact=true},
func = function(name, param)
local entityname = string.match(param, "(.+)$")
if not entityname then
minetest.chat_send_player(name, "entityname required")
return
end
print('/spawnentity 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.');
end,
})
minetest.register_chatcommand("pulverize", {
params = "",
description = "delete item in hand",
privs = {},
func = function(name, param)
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
end,
})
-- Key = player name
minetest.rollback_punch_callbacks = {}
minetest.register_on_punchnode(function(pos, node, puncher)
local name = puncher:get_player_name()
if minetest.rollback_punch_callbacks[name] then
minetest.rollback_punch_callbacks[name](pos, node, puncher)
minetest.rollback_punch_callbacks[name] = nil
end
end)
minetest.register_chatcommand("rollback_check", {
params = "[<range>] [<seconds>]",
description = "check who has last touched a node or near it, "..
"max. <seconds> ago (default range=0, seconds=86400=24h)",
privs = {rollback=true},
func = function(name, param)
local range, seconds = string.match(param, "(%d+) *(%d*)")
range = tonumber(range) or 0
seconds = tonumber(seconds) or 86400
minetest.chat_send_player(name, "Punch a node (limits set: range="..
dump(range).." seconds="..dump(seconds).."s)")
minetest.rollback_punch_callbacks[name] = function(pos, node, puncher)
local name = puncher:get_player_name()
minetest.chat_send_player(name, "Checking...")
local actor, act_p, act_seconds =
minetest.rollback_get_last_node_actor(pos, range, seconds)
if actor == "" then
minetest.chat_send_player(name, "Nobody has touched the "..
"specified location in "..dump(seconds).." seconds")
return
end
local nodedesc = "this node"
if act_p.x ~= pos.x or act_p.y ~= pos.y or act_p.z ~= pos.z then
nodedesc = minetest.pos_to_string(act_p)
end
local nodename = minetest.env:get_node(act_p).name
minetest.chat_send_player(name, "Last actor on "..nodedesc..
" was "..actor..", "..dump(act_seconds)..
"s ago (node is now "..nodename..")")
end
end,
})
minetest.register_chatcommand("rollback", {
params = "<player name> [<seconds>] | :<actor> [<seconds>]",
description = "revert actions of a player; default for <seconds> is 60",
privs = {rollback=true},
func = function(name, param)
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
if not target_name then
local player_name = nil;
player_name, seconds = string.match(param, "([^ ]+) *(%d*)")
if not player_name then
minetest.chat_send_player(name, "Invalid parameters. See /help rollback and /help rollback_check")
return
end
target_name = "player:"..player_name
end
seconds = tonumber(seconds) or 60
minetest.chat_send_player(name, "Reverting actions of "..
dump(target_name).." since "..dump(seconds).." seconds.")
local success, log = minetest.rollback_revert_actions_by(
target_name, seconds)
if #log > 10 then
minetest.chat_send_player(name, "(log is too long to show)")
else
for _,line in ipairs(log) do
minetest.chat_send_player(name, line)
end
end
if success then
minetest.chat_send_player(name, "Reverting actions succeeded.")
else
minetest.chat_send_player(name, "Reverting actions FAILED.")
end
end,
})

View File

@@ -16,4 +16,11 @@ minetest.digprop_woodlike = digprop_err
minetest.digprop_leaveslike = digprop_err
minetest.digprop_glasslike = digprop_err
minetest.node_metadata_inventory_move_allow_all = function()
minetest.log("info", "WARNING: minetest.node_metadata_inventory_move_allow_all is obsolete and does nothing.")
end
minetest.add_to_creative_inventory = function(itemstring)
minetest.log('info', "WARNING: minetest.add_to_creative_inventory: This function is deprecated and does nothing.")
end

View File

@@ -0,0 +1,19 @@
-- Minetest: builtin/detached_inventory.lua
minetest.detached_inventories = {}
function minetest.create_detached_inventory(name, callbacks)
local stuff = {}
stuff.name = name
if callbacks then
stuff.allow_move = callbacks.allow_move
stuff.allow_put = callbacks.allow_put
stuff.allow_take = callbacks.allow_take
stuff.on_move = callbacks.on_move
stuff.on_put = callbacks.on_put
stuff.on_take = callbacks.on_take
end
minetest.detached_inventories[name] = stuff
return minetest.create_detached_inventory_raw(name)
end

View File

@@ -124,53 +124,84 @@ 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 def.type ~= "node" or pointed_thing.type ~= "node" then
return itemstack
end
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
local under = pointed_thing.under
local oldnode_under = minetest.env:get_node(under)
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
minetest.log("action", placer:get_player_name() .. " places node "
.. def.name .. " at " .. minetest.pos_to_string(pos))
if not olddef_above.buildable_to and not olddef_under.buildable_to then
minetest.log("info", placer:get_player_name() .. " tried to place"
.. " node in invalid position " .. minetest.pos_to_string(above)
.. ", replacing " .. oldnode_above.name)
return
end
local newnode = {name = def.name, param1 = 0, param2 = 0}
-- Place above pointed node
local place_to = {x = above.x, y = above.y, z = above.z}
-- 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}
-- If node under is buildable_to, place into it instead (eg. snow)
if olddef_under.buildable_to then
minetest.log("info", "node under is buildable to")
place_to = {x = under.x, y = under.y, z = under.z}
end
minetest.log("action", placer:get_player_name() .. " places node "
.. def.name .. " at " .. minetest.pos_to_string(place_to))
local oldnode = minetest.env:get_node(place_to)
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 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 placer_pos = placer:getpos()
if placer_pos then
local dir = {
x = above.x - placer_pos.x,
y = above.y - placer_pos.y,
z = above.z - placer_pos.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)
-- Run callback
if def.after_place_node then
def.after_place_node(pos, placer)
end
-- Run script hook (deprecated)
local _, callback
for _, callback in ipairs(minetest.registered_on_placenodes) do
callback(pos, newnode, placer)
end
itemstack:take_item()
end
-- Add node and update
minetest.env:add_node(place_to, newnode)
-- Run callback
if def.after_place_node then
-- Copy place_to because callback can modify it
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
def.after_place_node(place_to_copy, placer)
end
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_placenodes) do
-- Copy pos and node because callback can modify them
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
local newnode_copy = {name=newnode.name, param1=newnode.param1, param2=newnode.param2}
local oldnode_copy = {name=oldnode.name, param1=oldnode.param1, param2=oldnode.param2}
callback(place_to_copy, newnode_copy, placer, oldnode_copy)
end
itemstack:take_item()
return itemstack
end
@@ -220,9 +251,11 @@ 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)
-- Copy pos and node because callback can modify them
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
callback(pos_copy, node_copy, puncher)
end
end
function minetest.node_dig(pos, node, digger)
@@ -240,27 +273,25 @@ function minetest.node_dig(pos, node, digger)
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())
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)
-- Wear out tool
local tp = wielded:get_tool_capabilities()
local dp = minetest.get_dig_params(def.groups, tp)
wielded:add_wear(dp.wear)
digger:set_wielded_item(wielded)
-- Add dropped items
-- Add dropped items to object's inventory
if digger:get_inventory() then
local _, dropped_item
for _, dropped_item in ipairs(drops) do
digger:get_inventory():add_item("main", dropped_item)
end
end
local oldnode = nil
local oldmetadata = nil
if def.after_dig_node then
oldnode = node;
oldmetadata = minetest.env:get_meta(pos):to_table()
end
@@ -269,51 +300,22 @@ function minetest.node_dig(pos, node, digger)
-- Run callback
if def.after_dig_node then
def.after_dig_node(pos, oldnode, oldmetadata, digger)
-- Copy pos and node because callback can modify them
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
def.after_dig_node(pos_copy, node_copy, oldmetadata, digger)
end
-- Run script hook (deprecated)
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_dignodes) do
callback(pos, node, digger)
-- Copy pos and node because callback can modify them
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
callback(pos_copy, node_copy, digger)
end
end
function minetest.node_metadata_inventory_move_allow_all(pos, from_list,
from_index, to_list, to_index, count, player)
minetest.log("verbose", "node_metadata_inventory_move_allow_all")
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
local from_stack = inv:get_stack(from_list, from_index)
local taken_items = from_stack:take_item(count)
inv:set_stack(from_list, from_index, from_stack)
local to_stack = inv:get_stack(to_list, to_index)
to_stack:add_item(taken_items)
inv:set_stack(to_list, to_index, to_stack)
end
function minetest.node_metadata_inventory_offer_allow_all(pos, listname, index, stack, player)
minetest.log("verbose", "node_metadata_inventory_offer_allow_all")
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
local the_stack = inv:get_stack(listname, index)
the_stack:add_item(stack)
inv:set_stack(listname, index, the_stack)
return ItemStack("")
end
function minetest.node_metadata_inventory_take_allow_all(pos, listname, index, count, player)
minetest.log("verbose", "node_metadata_inventory_take_allow_all")
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
local the_stack = inv:get_stack(listname, index)
local taken_items = the_stack:take_item(count)
inv:set_stack(listname, index, the_stack)
return taken_items
end
-- This is used to allow mods to redefine minetest.item_place and so on
-- NOTE: This is not the preferred way. Preferred way is to provide enough
-- callbacks to not require redefining global functions. -celeron55
@@ -340,6 +342,7 @@ minetest.nodedef_default = {
usable = false,
liquids_pointable = false,
tool_capabilities = nil,
node_placement_prediction = nil,
-- Interaction callbacks
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
@@ -359,11 +362,13 @@ minetest.nodedef_default = {
-- Node properties
drawtype = "normal",
visual_scale = 1.0,
tile_images = {""},
special_materials = {
{image="", backface_culling=true},
{image="", backface_culling=true},
},
-- Don't define these because otherwise the old tile_images and
-- special_materials wouldn't be read
--tiles ={""},
--special_tiles = {
-- {name="", backface_culling=true},
-- {name="", backface_culling=true},
--},
alpha = 255,
post_effect_color = {a=0, r=0, g=0, b=0},
paramtype = "none",

View File

@@ -72,7 +72,8 @@ minetest.register_entity("__builtin:item", {
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 then
-- If node is not registered or node is walkably solid
if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable then
if self.physical_state then
self.object:setvelocity({x=0,y=0,z=0})
self.object:setacceleration({x=0, y=0, z=0})

View File

@@ -244,6 +244,7 @@ minetest.register_item(":unknown", {
inventory_image = "unknown_item.png",
on_place = minetest.item_place,
on_drop = minetest.item_drop,
groups = {not_in_creative_inventory=1},
})
minetest.register_node(":air", {
@@ -258,6 +259,7 @@ minetest.register_node(":air", {
diggable = false,
buildable_to = true,
air_equivalent = true,
groups = {not_in_creative_inventory=1},
})
minetest.register_node(":ignore", {
@@ -272,23 +274,15 @@ minetest.register_node(":ignore", {
diggable = false,
buildable_to = true, -- A way to remove accidentally placed ignores
air_equivalent = true,
groups = {not_in_creative_inventory=1},
})
-- The hand (bare definition)
minetest.register_item(":", {
type = "none",
groups = {not_in_creative_inventory=1},
})
--
-- Creative inventory
--
minetest.creative_inventory = {}
minetest.add_to_creative_inventory = function(itemstring)
table.insert(minetest.creative_inventory, itemstring)
end
--
-- Callback registration
--
@@ -299,26 +293,22 @@ local function make_registration()
return t, registerfunc
end
local function make_registration_reverse()
local t = {}
local registerfunc = function(func) table.insert(t, 1, 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_punchnodes, minetest.register_on_punchnode = 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_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()
minetest.registered_on_placenodes = {}
minetest.register_on_placenode = function(callback)
minetest.log("info", debug.traceback())
minetest.log("info", "WARNING: minetest.register_on_placenode is deprecated. Use on_construct or after_place_node in node definition instead.")
table.insert(minetest.registered_on_placenodes, callback)
end
minetest.registered_on_dignodes = {}
minetest.register_on_dignode = function(callback)
minetest.log("info", debug.traceback())
minetest.log("info", "WARNING: minetest.register_on_dignode is deprecated. Use on_destruct or after_dig_node in node definition instead.")
table.insert(minetest.registered_on_dignodes, callback)
end
minetest.registered_on_player_receive_fields, minetest.register_on_player_receive_fields = make_registration_reverse()

View File

@@ -44,5 +44,5 @@ minetest.register_privilege("fast", {
description = "Can walk fast using the fast_move mode",
give_to_singleplayer = false,
})
minetest.register_privilege("rollback", "Can use the rollback functionality")

207
builtin/serialize.lua Normal file
View File

@@ -0,0 +1,207 @@
-- Minetest: builtin/serialize.lua
-- https://github.com/fab13n/metalua/blob/no-dll/src/lib/serialize.lua
-- Copyright (c) 2006-2997 Fabien Fleutot <metalua@gmail.com>
-- License: MIT
--------------------------------------------------------------------------------
-- Serialize an object into a source code string. This string, when passed as
-- an argument to deserialize(), returns an object structurally identical
-- to the original one. The following are currently supported:
-- * strings, numbers, booleans, nil
-- * tables thereof. Tables can have shared part, but can't be recursive yet.
-- Caveat: metatables and environments aren't saved.
--------------------------------------------------------------------------------
local no_identity = { number=1, boolean=1, string=1, ['nil']=1 }
function minetest.serialize(x)
local gensym_max = 0 -- index of the gensym() symbol generator
local seen_once = { } -- element->true set of elements seen exactly once in the table
local multiple = { } -- element->varname set of elements seen more than once
local nested = { } -- transient, set of elements currently being traversed
local nest_points = { }
local nest_patches = { }
local function gensym()
gensym_max = gensym_max + 1 ; return gensym_max
end
-----------------------------------------------------------------------------
-- nest_points are places where a table appears within itself, directly or not.
-- for instance, all of these chunks create nest points in table x:
-- "x = { }; x[x] = 1", "x = { }; x[1] = x", "x = { }; x[1] = { y = { x } }".
-- To handle those, two tables are created by mark_nest_point:
-- * nest_points [parent] associates all keys and values in table parent which
-- create a nest_point with boolean `true'
-- * nest_patches contain a list of { parent, key, value } tuples creating
-- a nest point. They're all dumped after all the other table operations
-- have been performed.
--
-- mark_nest_point (p, k, v) fills tables nest_points and nest_patches with
-- informations required to remember that key/value (k,v) create a nest point
-- in table parent. It also marks `parent' as occuring multiple times, since
-- several references to it will be required in order to patch the nest
-- points.
-----------------------------------------------------------------------------
local function mark_nest_point (parent, k, v)
local nk, nv = nested[k], nested[v]
assert (not nk or seen_once[k] or multiple[k])
assert (not nv or seen_once[v] or multiple[v])
local mode = (nk and nv and "kv") or (nk and "k") or ("v")
local parent_np = nest_points [parent]
local pair = { k, v }
if not parent_np then parent_np = { }; nest_points [parent] = parent_np end
parent_np [k], parent_np [v] = nk, nv
table.insert (nest_patches, { parent, k, v })
seen_once [parent], multiple [parent] = nil, true
end
-----------------------------------------------------------------------------
-- First pass, list the tables and functions which appear more than once in x
-----------------------------------------------------------------------------
local function mark_multiple_occurences (x)
if no_identity [type(x)] then return end
if seen_once [x] then seen_once [x], multiple [x] = nil, true
elseif multiple [x] then -- pass
else seen_once [x] = true end
if type (x) == 'table' then
nested [x] = true
for k, v in pairs (x) do
if nested[k] or nested[v] then mark_nest_point (x, k, v) else
mark_multiple_occurences (k)
mark_multiple_occurences (v)
end
end
nested [x] = nil
end
end
local dumped = { } -- multiply occuring values already dumped in localdefs
local localdefs = { } -- already dumped local definitions as source code lines
-- mutually recursive functions:
local dump_val, dump_or_ref_val
--------------------------------------------------------------------
-- if x occurs multiple times, dump the local var rather than the
-- value. If it's the first time it's dumped, also dump the content
-- in localdefs.
--------------------------------------------------------------------
function dump_or_ref_val (x)
if nested[x] then return 'false' end -- placeholder for recursive reference
if not multiple[x] then return dump_val (x) end
local var = dumped [x]
if var then return "_[" .. var .. "]" end -- already referenced
local val = dump_val(x) -- first occurence, create and register reference
var = gensym()
table.insert(localdefs, "_["..var.."]="..val)
dumped [x] = var
return "_[" .. var .. "]"
end
-----------------------------------------------------------------------------
-- Second pass, dump the object; subparts occuring multiple times are dumped
-- in local variables which can be referenced multiple times;
-- care is taken to dump locla vars in asensible order.
-----------------------------------------------------------------------------
function dump_val(x)
local t = type(x)
if x==nil then return 'nil'
elseif t=="number" then return tostring(x)
elseif t=="string" then return string.format("%q", x)
elseif t=="boolean" then return x and "true" or "false"
elseif t=="table" then
local acc = { }
local idx_dumped = { }
local np = nest_points [x]
for i, v in ipairs(x) do
if np and np[v] then
table.insert (acc, 'false') -- placeholder
else
table.insert (acc, dump_or_ref_val(v))
end
idx_dumped[i] = true
end
for k, v in pairs(x) do
if np and (np[k] or np[v]) then
--check_multiple(k); check_multiple(v) -- force dumps in localdefs
elseif not idx_dumped[k] then
table.insert (acc, "[" .. dump_or_ref_val(k) .. "] = " .. dump_or_ref_val(v))
end
end
return "{ "..table.concat(acc,", ").." }"
else
error ("Can't serialize data of type "..t)
end
end
local function dump_nest_patches()
for _, entry in ipairs(nest_patches) do
local p, k, v = unpack (entry)
assert (multiple[p])
local set = dump_or_ref_val (p) .. "[" .. dump_or_ref_val (k) .. "] = " ..
dump_or_ref_val (v) .. " -- rec "
table.insert (localdefs, set)
end
end
mark_multiple_occurences (x)
local toplevel = dump_or_ref_val (x)
dump_nest_patches()
if next (localdefs) then
return "local _={ }\n" ..
table.concat (localdefs, "\n") ..
"\nreturn " .. toplevel
else
return "return " .. toplevel
end
end
-- Deserialization.
-- http://stackoverflow.com/questions/5958818/loading-serialized-data-into-a-table
--
local function stringtotable(sdata)
if sdata:byte(1) == 27 then return nil, "binary bytecode prohibited" end
local f, message = assert(loadstring(sdata))
if not f then return nil, message end
setfenv(f, table)
return f()
end
function minetest.deserialize(sdata)
local table = {}
local okay,results = pcall(stringtotable, sdata)
if okay then
return results
end
print('error:'.. results)
return nil
end
-- Run some unit tests
local function unit_test()
function unitTest(name, success)
if not success then
error(name .. ': failed')
end
end
unittest_input = {cat={sound="nyan", speed=400}, dog={sound="woof"}}
unittest_output = minetest.deserialize(minetest.serialize(unittest_input))
unitTest("test 1a", unittest_input.cat.sound == unittest_output.cat.sound)
unitTest("test 1b", unittest_input.cat.speed == unittest_output.cat.speed)
unitTest("test 1c", unittest_input.dog.sound == unittest_output.dog.sound)
unittest_input = {escapechars="\n\r\t\v\\\"\'\[\]", noneuropean="θשׁ٩∂"}
unittest_output = minetest.deserialize(minetest.serialize(unittest_input))
unitTest("test 3a", unittest_input.escapechars == unittest_output.escapechars)
unitTest("test 3b", unittest_input.noneuropean == unittest_output.noneuropean)
end
unit_test() -- Run it
unit_test = nil -- Hide it

View File

@@ -1,4 +1,4 @@
Minetest Lua Modding API Reference 0.4.dev
Minetest Lua Modding API Reference 0.4.0
==========================================
More information at http://c55.me/minetest/
@@ -254,9 +254,9 @@ Nodes are passed by value between Lua and the engine.
They are represented by a table:
{name="name", param1=num, param2=num}
param1 and param2 are 8 bit and 4 bit integers, respectively. The engine
uses them for certain automated functions. If you don't use these
functions, you can use them to store arbitrary values.
param1 and param2 are 8 bit integers. The engine uses them for certain
automated functions. If you don't use these functions, you can use them to
store arbitrary values.
The functions of param1 and param2 are determined by certain fields in the
node definition:
@@ -280,6 +280,61 @@ param2 is reserved for the engine when any of these are used:
Nodes can also contain extra data. See "Node Metadata".
Node drawtypes
---------------
There are a bunch of different looking node types. These are mostly just
copied from Minetest 0.3; more may be made in the future.
Look for examples in games/minimal or games/minetest_game.
- normal
- airlike
- liquid
- flowingliquid
- glasslike
- allfaces
- allfaces_optional
- torchlike
- signlike
- plantlike
- fencelike
- raillike
- nodebox -- See below. EXPERIMENTAL
Node boxes
-----------
Node selection boxes are defined using "node boxes"
The "nodebox" node drawtype allows defining visual of nodes consisting of
arbitrary number of boxes. It allows defining stuff like stairs. Only the
"fixed" box type is supported for these.
^ Please note that this is still experimental, and may be incompatibly
changed in the future.
A nodebox is defined as any of:
{
-- A normal cube; the default in most things
type = "regular"
}
{
-- A fixed box (facedir param2 is used, if applicable)
type = "fixed",
fixed = box OR {box1, box2, ...}
}
{
-- A box like the selection box for torches
-- (wallmounted param2 is used, if applicable)
type = "wallmounted",
wall_top = box,
wall_bottom = box,
wall_side = box
}
A box is defined as:
{x1, y1, z1, x2, y2, z2}
A box of a regular node would look like:
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
Representations of simple things
--------------------------------
Position/vector:
@@ -287,6 +342,11 @@ Position/vector:
Currently the API does not provide any helper functions for addition,
subtraction and whatever; you can define those that you need yourself.
pointed_thing:
{type="nothing"}
{type="node", under=pos, above=pos}
{type="object", ref=ObjectRef}
Items
------
Node (register_node):
@@ -363,8 +423,7 @@ effective towards.
Groups in crafting recipes
---------------------------
- Not implemented yet. (TODO)
- Will probably look like this:
An example: Make meat soup from any meat, any water and any bowl
{
output = 'food:meat_soup_raw',
recipe = {
@@ -372,7 +431,13 @@ Groups in crafting recipes
{'group:water'},
{'group:bowl'},
},
preserve = {'group:bowl'},
-- preserve = {'group:bowl'}, -- Not implemented yet (TODO)
}
An another example: Make red wool from white wool and red dye
{
type = 'shapeless',
output = 'wool:red',
recipe = {'wool:white', 'group:dye,basecolor_red'},
}
Special groups
@@ -569,7 +634,7 @@ Example stuff:
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"list[current_name;main;0,0;8,4;]"..
"list[context;main;0,0;8,4;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", "Chest");
local inv = meta:get_inventory()
@@ -580,7 +645,7 @@ meta:from_table({
main = {[1] = "default:dirt", [2] = "", [3] = "", [4] = "", [5] = "", [6] = "", [7] = "", [8] = "", [9] = "", [10] = "", [11] = "", [12] = "", [13] = "", [14] = "default:cobble", [15] = "", [16] = "", [17] = "", [18] = "", [19] = "", [20] = "default:cobble", [21] = "", [22] = "", [23] = "", [24] = "", [25] = "", [26] = "", [27] = "", [28] = "", [29] = "", [30] = "", [31] = "", [32] = ""}
},
fields = {
formspec = "invsize[8,9;]list[current_name;main;0,0;8,4;]list[current_player;main;0,5;8,4;]",
formspec = "invsize[8,9;]list[context;main;0,0;8,4;]list[current_player;main;0,5;8,4;]",
infotext = "Chest"
}
})
@@ -596,13 +661,13 @@ examples.
Examples:
- Chest:
invsize[8,9;]
list[current_name;main;0,0;8,4;]
list[context;main;0,0;8,4;]
list[current_player;main;0,5;8,4;]
- Furnace:
invsize[8,9;]
list[current_name;fuel;2,3;1,1;]
list[current_name;src;2,1;1,1;]
list[current_name;dst;5,1;2,2;]
list[context;fuel;2,3;1,1;]
list[context;src;2,1;1,1;]
list[context;dst;5,1;2,2;]
list[current_player;main;0,5;8,4;]
- Minecraft-like player inventory
invsize[8,7.5;]
@@ -613,10 +678,12 @@ Examples:
Elements:
invsize[<W>,<H>;]
size[<W>,<H>]
^ Define the size of the menu in inventory slots
^ deprecated: invsize[<W>,<H>;]
list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]
list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]
^ Show an inventory list
image[<X>,<Y>;<W>,<H>;<texture name>]
@@ -625,20 +692,53 @@ image[<X>,<Y>;<W>,<H>;<texture name>]
field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]
^ Textual field; will be sent to server when a button is clicked
^ x and y position the field relative to the top left of the menu
^ w and h are the size of the field
^ fields are a set height, but will be vertically centred on h
^ Position and size units are inventory slots
^ name is the name of the field as returned in fields to on_receive_fields
^ label, if not blank, will be text printed on the top left above the field
^ default is the default value of the field
^ default may contain variable references such as '${text}' which
will fill the value from the metadata value 'text'
^ Note: no extra text or more than a single variable is supported ATM.
field[<name>;<label>;<default>]
^ as above but without position/size units
^ special field for creating simple forms, such as sign text input
^ must be used without a size[] element
^ a 'Proceed' button will be added automatically
label[<X>,<Y>;<label>]
^ x and y work as per field
^ label is the text on the label
^ Position and size units are inventory slots
^ Not implemented
button[<X>,<Y>;<W>,<H>;<name>;<label>]
^ Clickable button. When clicked, fields will be sent.
^ Button will be visible as a field, with the value "active".
^ x, y and name work as per field
^ w and h are the size of the button
^ label is the text on the button
^ Position and size units are inventory slots
^ Not implemented
image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]
^ x, y, w, h, and name work as per button
^ image is the filename of an image
^ Position and size units are inventory slots
button_exit[<X>,<Y>;<W>,<H>;<name>;<label>]
^ When clicked, fields will be sent and the form will quit.
image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]
^ When clicked, fields will be sent and the form will quit.
Inventory location:
- "context": Selected node metadata (deprecated: "current_name")
- "current_player": Player to whom the menu is shown
- "player:<name>": Any player
- "nodemeta:<X>,<Y>,<Z>": Any node metadata
- "detached:<name>": A detached inventory
Helper functions
-----------------
@@ -659,6 +759,8 @@ minetest namespace reference
minetest.get_current_modname() -> string
minetest.get_modpath(modname) -> eg. "/home/user/.minetest/usermods/modname"
^ Useful for loading additional .lua modules or static data from mod
minetest.get_modnames() -> list of installed mods
^ Return a list of installed mods, sorted alphabetically
minetest.get_worldpath() -> eg. "/home/user/.minetest/world"
^ Useful for storing custom data
minetest.is_singleplayer()
@@ -681,11 +783,11 @@ minetest.register_craft(recipe)
Global callback registration functions: (Call these only at load time)
minetest.register_globalstep(func(dtime))
^ Called every server step, usually interval of 0.05s
minetest.register_on_placenode(func(pos, newnode, placer))
minetest.register_on_placenode(func(pos, newnode, placer, oldnode))
^ Called when a node has been placed
^ Deprecated: Use on_construct or after_place_node in node definition instead
minetest.register_on_dignode(func(pos, oldnode, digger))
^ Called when a node has been dug. digger can be nil.
^ Called when a node has been dug.
^ Deprecated: Use on_destruct or after_dig_node in node definition instead
minetest.register_on_punchnode(func(pos, node, puncher))
^ Called when a node is punched
@@ -700,7 +802,16 @@ minetest.register_on_respawnplayer(func(ObjectRef))
^ Called when player is to be respawned
^ Called _before_ repositioning of player occurs
^ return true in func to disable regular player placement
minetest.register_on_joinplayer(func(ObjectRef))
^ Called when a player joins the game
minetest.register_on_leaveplayer(func(ObjectRef))
^ Called when a player leaves the game
minetest.register_on_chat_message(func(name, message))
^ Called always when a player says something
minetest.register_on_player_receive_fields(func(player, formname, fields))
^ Called when a button is pressed in player's inventory form
^ Newest functions are called first
^ If function returns true, remaining functions are not called
Other registration functions:
minetest.register_chatcommand(cmd, chatcommand definition)
@@ -745,6 +856,10 @@ Inventory:
minetest.get_inventory(location) -> InvRef
^ location = eg. {type="player", name="celeron55"}
{type="node", pos={x=, y=, z=}}
{type="detached", name="creative"}
minetest.create_detached_inventory(name, callbacks) -> InvRef
^ callbacks: See "Detached inventory callbacks"
^ Creates a detached inventory. If it already exists, it is cleared.
Item handling:
minetest.inventorycube(img1, img2, img3)
@@ -766,6 +881,21 @@ minetest.get_craft_result(input) -> output, decremented_input
^ output.item = ItemStack, if unsuccessful: empty ItemStack
^ output.time = number, if unsuccessful: 0
^ decremented_input = like input
minetest.get_craft_recipe(output) -> input
^ output is a node or item type such as 'default:torch'
^ input.method = 'normal' or 'cooking' or 'fuel'
^ input.width = for example 3
^ input.items = for example { stack 1, stack 2, stack 3, stack 4,
stack 5, stack 6, stack 7, stack 8, stack 9 }
^ input.items = nil if no recipe found
Rollbacks:
minetest.rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
^ Find who has done something to a node, or near a node
^ actor: "player:<name>", also "liquid".
minetest.rollback_revert_actions_by(actor, seconds) -> bool, log messages
^ Revert latest actions of someone
^ actor: "player:<name>", also "liquid".
Defaults for the on_* item definition functions:
(These return the leftover itemstack)
@@ -806,6 +936,17 @@ minetest.get_item_group(name, group) -> rating
^ Get rating of a group of an item. (0 = not in group)
minetest.get_node_group(name, group) -> rating
^ Deprecated: An alias for the former.
minetest.serialize(table) -> string
^ Convert a table containing tables, strings, numbers, booleans and nils
into string form readable by minetest.deserialize
^ Example: serialize({foo='bar'}) -> 'return { ["foo"] = "bar" }'
minetest.deserialize(string) -> table
^ Convert a string returned by minetest.deserialize into a table
^ String is loaded in an empty sandbox environment.
^ Will load functions, but they cannot access the global environment.
^ Example: deserialize('return { ["foo"] = "bar" }') -> {foo='bar'}
^ Example: deserialize('print("foo")') -> nil (function call fails)
^ error:[string "print("foo")"]:1: attempt to call global 'print' (a nil value)
Global objects:
minetest.env - EnvRef of the server environment and world.
@@ -842,18 +983,30 @@ EnvRef: basically ServerEnvironment and ServerMap combined.
methods:
- set_node(pos, node)
- add_node(pos, node): alias set_node(pos, node)
- remove_node(pos): equivalent to set_node(pos, "air")
^ Set node at position (node = {name="foo", param1=0, param2=0})
- remove_node(pos)
^ Equivalent to set_node(pos, "air")
- get_node(pos)
^ Returns {name="ignore", ...} for unloaded area
- get_node_or_nil(pos)
^ Returns nil for unloaded area
- get_node_light(pos, timeofday) -> 0...15 or nil
^ timeofday: nil = current time, 0 = night, 0.5 = day
- place_node(pos, node)
^ Place node with the same effects that a player would cause
- dig_node(pos)
^ Dig node with the same effects that a player would cause
- punch_node(pos)
^ Punch node with the same effects that a player would cause
- get_meta(pos) -- Get a NodeMetaRef at that position
- get_node_timer(pos) -- Get NodeTimerRef
- add_entity(pos, name): Spawn Lua-defined entity at position
^ Returns ObjectRef, or nil if failed
- add_item(pos, itemstring): Spawn item
- add_item(pos, item): Spawn item
^ Returns ObjectRef, or nil if failed
- get_meta(pos) -- Get a NodeMetaRef at that position
- get_player_by_name(name) -- Get an ObjectRef to a player
- get_objects_inside_radius(pos, radius)
- set_timeofday(val): val: 0...1; 0 = midnight, 0.5 = midday
@@ -882,6 +1035,26 @@ methods:
- to_table() -> nil or {fields = {...}, inventory = {list1 = {}, ...}}
- from_table(nil or {})
^ See "Node Metadata"
NodeTimerRef: Node Timers - a high resolution persistent per-node timer
- Can be gotten via minetest.env:get_node_timer(pos)
methods:
- set(timeout,elapsed)
^ set a timer's state
^ timeout is in seconds, and supports fractional values (0.1 etc)
^ elapsed is in seconds, and supports fractional values (0.1 etc)
^ will trigger the node's on_timer function after timeout-elapsed seconds
- start(timeout)
^ start a timer
^ equivelent to set(timeout,0)
- stop()
^ stops the timer
- get_timeout() -> current timeout in seconds
^ if timeout is 0, timer is inactive
- get_elapsed() -> current elapsed time in seconds
^ the node's on_timer function will be called after timeout-elapsed seconds
- is_started() -> boolean state of timer
^ returns true if timer is started, otherwise false
ObjectRef: Moving things in the game are generally these
(basically reference to a C++ ServerActiveObject)
@@ -913,8 +1086,8 @@ LuaEntitySAO-only: (no-op for other objects)
- settexturemod(mod)
- setsprite(p={x=0,y=0}, num_frames=1, framelength=0.2,
- select_horiz_by_yawpitch=false)
- ^ Select sprite from spritesheet with optional animation and DM-style
- texture selection based on yaw relative to camera
^ Select sprite from spritesheet with optional animation and DM-style
texture selection based on yaw relative to camera
- get_entity_name() (DEPRECATED: Will be removed in a future version)
- get_luaentity()
Player-only: (no-op for other objects)
@@ -923,6 +1096,10 @@ Player-only: (no-op for other objects)
- get_look_dir(): get camera direction as a unit vector
- get_look_pitch(): pitch in radians
- get_look_yaw(): yaw in radians (wraps around pretty randomly as of now)
- set_inventory_formspec(formspec)
^ Redefine player's inventory form
^ Should usually be called in on_joinplayer
- get_inventory_formspec() -> formspec string
InvRef: Reference to an inventory
methods:
@@ -1016,7 +1193,9 @@ Definition tables
Object Properties
{
hp_max = 1,
physical = true,
weight = 5,
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "cube"/"sprite"/"upright_sprite",
visual_size = {x=1, y=1},
@@ -1025,6 +1204,7 @@ Object Properties
initial_sprite_basepos = {x=0, y=0},
is_visible = true,
makes_footstep_sound = false,
automatic_rotate = false,
}
Entity definition (register_entity)
@@ -1080,10 +1260,19 @@ Item definition (register_node, register_craftitem, register_tool)
choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0}
}
}
node_placement_prediction = nil,
^ If nil and item is node, prediction is made automatically
^ If nil and item is not a node, no prediction is made
^ If "" and item is anything, no prediction is made
^ Otherwise should be name of node which the client immediately places
on ground when the player places the item. Server will always update
actual result to client in a short moment.
on_place = func(itemstack, placer, pointed_thing),
^ Shall place item and return the leftover itemstack
^ default: minetest.item_place
on_drop = func(itemstack, dropper, pos),
^ Shall drop item and return the leftover itemstack
^ default: minetest.item_drop
on_use = func(itemstack, user, pointed_thing),
^ default: nil
@@ -1094,37 +1283,49 @@ Item definition (register_node, register_craftitem, register_tool)
^ The default functions handle regular use cases.
}
Tile definition:
- "image.png"
- {name="image.png", animation={Tile Animation definition}}
- {name="image.png", backface_culling=bool}
^ backface culling only supported in special tiles
- deprecated still supported field names:
- image -> name
Tile animation definition:
- {type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}
Node definition (register_node)
{
<all fields allowed in item definitions>,
drawtype = "normal",
drawtype = "normal", -- See "Node drawtypes"
visual_scale = 1.0,
tile_images = {"default_unknown_block.png"},
special_materials = {
{image="", backface_culling=true},
{image="", backface_culling=true},
},
tiles = {tile definition 1, def2, def3, def4, def5, def6},
^ Textures of node; +Y, -Y, +X, -X, +Z, -Z (old field name: tile_images)
^ List can be shortened to needed length
special_tiles = {tile definition 1, Tile definition 2},
^ Special textures of node; used rarely (old field name: special_materials)
^ List can be shortened to needed length
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,
drop = "",
-- alternatively drop = { max_items = ..., items = { ... } }
liquidtype = "none",
liquid_alternative_flowing = "",
liquid_alternative_source = "",
liquid_viscosity = 0,
light_source = 0,
damage_per_second = 0,
selection_box = {type="regular"},
post_effect_color = {a=0, r=0, g=0, b=0}, -- If player is inside node
paramtype = "none", -- See "Nodes"
paramtype2 = "none", -- See "Nodes"
is_ground_content = false, -- Currently not used for anything
sunlight_propagates = false, -- If true, sunlight will go infinitely through this
walkable = true, -- If true, objects collide with node
pointable = true, -- If true, can be pointed at
diggable = true, -- If false, can never be dug
climbable = false, -- If true, can be climbed on (ladder)
buildable_to = false, -- If true, placed nodes can replace this node
drop = "", -- alternatively drop = { max_items = ..., items = { ... } }
liquidtype = "none", -- "none"/"source"/"flowing"
liquid_alternative_flowing = "", -- Flowing version of source liquid
liquid_alternative_source = "", -- Source version of flowing liquid
liquid_viscosity = 0, -- Higher viscosity = slower flow (max. 7)
light_source = 0, -- Amount of light emitted by node
damage_per_second = 0, -- If player is inside node, this damage is caused
node_box = {type="regular"}, -- See "Node boxes"
selection_box = {type="regular"}, -- See "Node boxes"
legacy_facedir_simple = false, -- Support maps made in and before January 2012
legacy_wallmounted = false, -- Support maps made in and before January 2012
sounds = {
@@ -1140,15 +1341,18 @@ Node definition (register_node)
on_destruct = func(pos),
^ Node destructor; always called before removing node
^ default: nil
after_destruct = func(pos, oldnode),
^ Node destructor; always called after removing node
^ default: nil
after_place_node = func(pos, placer),
^ Called after constructing node when node was placed using
minetest.item_place_node
minetest.item_place_node / minetest.env:place_node
^ default: nil
after_dig_node = func(pos, oldnode, oldmetadata, digger),
^ oldmetadata is in table format
^ Called after destructing node when node was dug using
minetest.node_dig
minetest.node_dig / minetest.env:dig_node
^ default: nil
can_dig = function(pos,player)
^ returns true if node can be dug, or false if not
@@ -1157,59 +1361,57 @@ Node definition (register_node)
on_punch = func(pos, node, puncher),
^ default: minetest.node_punch
^ By default: does nothing
on_dig = func(pos, node, digger),
on_dig = func(pos, node, digger),
^ default: minetest.node_dig
^ By default: checks privileges, wears out tool and removes node
on_timer = function(pos,elapsed),
^ default: nil
^ called by NodeTimers, see EnvRef and NodeTimerRef
^ elapsed is the total time passed since the timer was started
^ return true to run the timer for another cycle with the same timeout value
on_receive_fields = func(pos, formname, fields, sender),
^ fields = {name1 = value1, name2 = value2, ...}
^ Called when an UI form (eg. sign text input) returns data
^ default: nil
on_metadata_inventory_move = func(pos, from_list, from_index,
to_list, to_index, count, player),
^ Called when a player wants to move items inside the metadata
^ Should move items, or some items, if permitted. If not, should do
nothing.
^ The engine ensures the action is valid, i.e. the stack fits at the
given position
^ default: minetest.node_metadata_inventory_move_allow_all
allow_metadata_inventory_move = func(pos, from_list, from_index,
to_list, to_index, count, player),
^ Called when a player wants to move items inside the inventory
^ Return value: number of items allowed to move
allow_metadata_inventory_put = func(pos, listname, index, stack, player),
^ Called when a player wants to put something into the inventory
^ Return value: number of items allowed to put
^ Return value: -1: Allow and don't modify item count in inventory
allow_metadata_inventory_take = func(pos, listname, index, stack, player),
^ Called when a player wants to take something out of the inventory
^ Return value: number of items allowed to take
^ Return value: -1: Allow and don't modify item count in inventory
on_metadata_inventory_offer = func(pos, listname, index, stack, player),
^ Called when a player wants to put something into the metadata
inventory
^ Should check if the action is permitted (the engine ensures the
action is valid, i.e. the stack fits at the given position)
^ If permitted, modify the metadata inventory and return the
"leftover" stack (normally nil).
^ If not permitted, return itemstack.
^ default: minetest.node_metadata_inventory_offer_allow_all
on_metadata_inventory_take = func(pos, listname, index, count, player),
^ Called when a player wants to take something out of the metadata
inventory
^ Should check if the action is permitted (the engine ensures the
action is valid, i.e. there's a stack of at least “count” items at
that position)
^ If permitted, modify the metadata inventory and return the
stack of items
^ If not permitted, return nil.
^ default: minetest.node_metadata_inventory_take_allow_all
on_metadata_inventory_move = func(pos, from_list, from_index,
to_list, to_index, count, player),
on_metadata_inventory_put = func(pos, listname, index, stack, player),
on_metadata_inventory_take = func(pos, listname, index, stack, player),
^ Called after the actual action has happened, according to what was allowed.
^ No return value
}
Recipe: (register_craft)
Recipe for register_craft: (shaped)
{
output = 'default:pick_stone',
recipe = {
{'default:cobble', 'default:cobble', 'default:cobble'},
{'', 'default:stick', ''},
{'', 'default:stick', ''},
{'', 'default:stick', ''}, -- Also groups; eg. 'group:crumbly'
},
replacements = <optional list of item pairs,
replace one input item with another item on crafting>
}
Recipe (shapeless):
Recipe for register_craft (shapeless)
{
type = "shapeless",
output = 'mushrooms:mushroom_stew',
@@ -1222,13 +1424,13 @@ Recipe (shapeless):
replace one input item with another item on crafting>
}
Recipe (tool repair):
Recipe for register_craft (tool repair)
{
type = "toolrepair",
additional_wear = -0.02,
}
Recipe (cooking):
Recipe for register_craft (cooking)
{
type = "cooking",
output = "default:glass",
@@ -1236,7 +1438,7 @@ Recipe (cooking):
cooktime = 3,
}
Recipe (furnace fuel):
Recipe for register_craft (furnace fuel)
{
type = "fuel",
recipe = "default:leaves",
@@ -1251,3 +1453,26 @@ Chatcommand definition (register_chatcommand)
func = function(name, param), -- called when command is run
}
Detached inventory callbacks
{
allow_move = func(inv, from_list, from_index, to_list, to_index, count, player),
^ Called when a player wants to move items inside the inventory
^ Return value: number of items allowed to move
allow_put = func(inv, listname, index, stack, player),
^ Called when a player wants to put something into the inventory
^ Return value: number of items allowed to put
^ Return value: -1: Allow and don't modify item count in inventory
allow_take = func(inv, listname, index, stack, player),
^ Called when a player wants to take something out of the inventory
^ Return value: number of items allowed to take
^ Return value: -1: Allow and don't modify item count in inventory
on_move = func(inv, from_list, from_index, to_list, to_index, count, player),
on_put = func(inv, listname, index, stack, player),
on_take = func(inv, listname, index, stack, player),
^ Called after the actual action has happened, according to what was allowed.
^ No return value
}

View File

@@ -1,13 +1,16 @@
=================================================
Minetest World Format used as of 0.4.dev-20120322
=================================================
=============================
Minetest World Format 22...25
=============================
This applies to a world format carrying the block serialization version 22
which is used at least in version 0.4.dev-20120322.
This applies to a world format carrying the block serialization version
22...25, used at least in
- 0.4.dev-20120322 ... 0.4.dev-20120606 (22...23)
- 0.4.0 (23)
- 24 was never released as stable and existed for ~2 days
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.
The block serialization version does not fully specify every aspect of this
format; if compliance with this format is to be checked, it needs to be
done by detecting if the files and data indeed follows it.
Legacy stuff
=============
@@ -20,8 +23,8 @@ 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.
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
@@ -260,17 +263,26 @@ u8 flags
u8 content_width
- Number of bytes in the content (param0) fields of nodes
- Always 1
if map format version <= 23:
- Always 1
if map format version >= 24:
- Always 2
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
if content_width == 1:
- content:
u8[4096]: param0 fields
u8[4096]: param1 fields
u8[4096]: param2 fields
if content_width == 2:
- content:
u16[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
@@ -283,9 +295,19 @@ zlib-compressed node metadata list
u16 content_size
u8[content_size] (content of metadata)
u16 mapblockobject_count
- Always 0
- Should be removed in version 23 (TODO)
- Node timers
if map format version == 23:
u8 unused version (always 0)
if map format version == 24: (NOTE: Not released as stable)
u8 nodetimer_version
if nodetimer_version == 0:
(nothing else)
if nodetimer_version == 1:
u16 num_of_timers
foreach num_of_timers:
u16 timer position (z*16*16 + y*16 + x)
s32 timeout*1000
s32 elapsed*1000
u8 static object version:
- Always 0
@@ -315,17 +337,29 @@ foreach num_name_id_mappings
u16 name_len
u8[name_len] name
- Node timers
if map format version == 25:
u8 length of the data of a single timer (always 2+4+4=10)
u16 num_of_timers
foreach num_of_timers:
u16 timer position (z*16*16 + y*16 + x)
s32 timeout*1000
s32 elapsed*1000
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)
if map format version <= 23:
The content id of a node is determined as so:
- If param0 < 0x80,
content_id = param0
- Otherwise
content_id = (param0<<4) + (param2>>4)
if map format version >= 24:
The content id of a node is param0.
The purpose of param1 and param2 depend on the definition of the node.

View File

@@ -90,6 +90,6 @@ bucket.register_liquid(
minetest.register_craft({
type = "fuel",
recipe = "default:bucket_lava",
recipe = "bucket:bucket_lava",
burntime = 60,
})

View File

@@ -14,6 +14,14 @@ default = {}
-- Load other files
dofile(minetest.get_modpath("default").."/mapgen.lua")
-- Set a noticeable inventory formspec for players
minetest.register_on_joinplayer(function(player)
local cb = function(player)
minetest.chat_send_player(player:get_player_name(), "This is the [minimal] \"Minimal Development Test\" game. Use [minetest_game] for the real thing.")
end
minetest.after(2.0, cb, player)
end)
--
-- Tool definition
--
@@ -701,7 +709,7 @@ end
minetest.register_node("default:stone", {
description = "Stone",
tile_images = {"default_stone.png"},
tiles ={"default_stone.png"},
is_ground_content = true,
groups = {cracky=3},
drop = 'default:cobble',
@@ -711,7 +719,7 @@ minetest.register_node("default:stone", {
minetest.register_node("default:stone_with_coal", {
description = "Stone with coal",
tile_images = {"default_stone.png^default_mineral_coal.png"},
tiles ={"default_stone.png^default_mineral_coal.png"},
is_ground_content = true,
groups = {cracky=3},
drop = 'default:coal_lump',
@@ -720,7 +728,7 @@ minetest.register_node("default:stone_with_coal", {
minetest.register_node("default:stone_with_iron", {
description = "Stone with iron",
tile_images = {"default_stone.png^default_mineral_iron.png"},
tiles ={"default_stone.png^default_mineral_iron.png"},
is_ground_content = true,
groups = {cracky=3},
drop = 'default:iron_lump',
@@ -729,7 +737,7 @@ minetest.register_node("default:stone_with_iron", {
minetest.register_node("default:dirt_with_grass", {
description = "Dirt with grass",
tile_images = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
tiles ={"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
is_ground_content = true,
groups = {crumbly=3},
drop = 'default:dirt',
@@ -740,7 +748,7 @@ minetest.register_node("default:dirt_with_grass", {
minetest.register_node("default:dirt_with_grass_footsteps", {
description = "Dirt with grass and footsteps",
tile_images = {"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
tiles ={"default_grass_footsteps.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
is_ground_content = true,
groups = {crumbly=3},
drop = 'default:dirt',
@@ -751,7 +759,7 @@ minetest.register_node("default:dirt_with_grass_footsteps", {
minetest.register_node("default:dirt", {
description = "Dirt",
tile_images = {"default_dirt.png"},
tiles ={"default_dirt.png"},
is_ground_content = true,
groups = {crumbly=3},
sounds = default.node_sound_dirt_defaults(),
@@ -759,7 +767,7 @@ minetest.register_node("default:dirt", {
minetest.register_node("default:sand", {
description = "Sand",
tile_images = {"default_sand.png"},
tiles ={"default_sand.png"},
is_ground_content = true,
groups = {crumbly=3},
sounds = default.node_sound_sand_defaults(),
@@ -767,7 +775,7 @@ minetest.register_node("default:sand", {
minetest.register_node("default:gravel", {
description = "Gravel",
tile_images = {"default_gravel.png"},
tiles ={"default_gravel.png"},
is_ground_content = true,
groups = {crumbly=2},
sounds = default.node_sound_dirt_defaults({
@@ -777,7 +785,7 @@ minetest.register_node("default:gravel", {
minetest.register_node("default:sandstone", {
description = "Sandstone",
tile_images = {"default_sandstone.png"},
tiles ={"default_sandstone.png"},
is_ground_content = true,
groups = {crumbly=2,cracky=2},
drop = 'default:sand',
@@ -786,7 +794,7 @@ minetest.register_node("default:sandstone", {
minetest.register_node("default:clay", {
description = "Clay",
tile_images = {"default_clay.png"},
tiles ={"default_clay.png"},
is_ground_content = true,
groups = {crumbly=3},
drop = 'default:clay_lump 4',
@@ -797,7 +805,7 @@ minetest.register_node("default:clay", {
minetest.register_node("default:brick", {
description = "Brick",
tile_images = {"default_brick.png"},
tiles ={"default_brick.png"},
is_ground_content = true,
groups = {cracky=3},
drop = 'default:clay_brick 4',
@@ -806,7 +814,7 @@ minetest.register_node("default:brick", {
minetest.register_node("default:tree", {
description = "Tree",
tile_images = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
tiles ={"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
is_ground_content = true,
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=1},
sounds = default.node_sound_wood_defaults(),
@@ -814,7 +822,7 @@ minetest.register_node("default:tree", {
minetest.register_node("default:jungletree", {
description = "Jungle Tree",
tile_images = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
tiles ={"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
is_ground_content = true,
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=1},
sounds = default.node_sound_wood_defaults(),
@@ -824,7 +832,7 @@ minetest.register_node("default:junglegrass", {
description = "Jungle Grass",
drawtype = "plantlike",
visual_scale = 1.3,
tile_images = {"default_junglegrass.png"},
tiles ={"default_junglegrass.png"},
inventory_image = "default_junglegrass.png",
wield_image = "default_junglegrass.png",
paramtype = "light",
@@ -837,7 +845,7 @@ minetest.register_node("default:leaves", {
description = "Leaves",
drawtype = "allfaces_optional",
visual_scale = 1.3,
tile_images = {"default_leaves.png"},
tiles ={"default_leaves.png"},
paramtype = "light",
groups = {snappy=3},
drop = {
@@ -860,7 +868,7 @@ minetest.register_node("default:leaves", {
minetest.register_node("default:cactus", {
description = "Cactus",
tile_images = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
tiles ={"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
is_ground_content = true,
groups = {snappy=2,choppy=3},
sounds = default.node_sound_wood_defaults(),
@@ -869,7 +877,7 @@ minetest.register_node("default:cactus", {
minetest.register_node("default:papyrus", {
description = "Papyrus",
drawtype = "plantlike",
tile_images = {"default_papyrus.png"},
tiles ={"default_papyrus.png"},
inventory_image = "default_papyrus.png",
wield_image = "default_papyrus.png",
paramtype = "light",
@@ -881,7 +889,7 @@ minetest.register_node("default:papyrus", {
minetest.register_node("default:bookshelf", {
description = "Bookshelf",
tile_images = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
tiles ={"default_wood.png", "default_wood.png", "default_bookshelf.png"},
is_ground_content = true,
groups = {snappy=2,choppy=3,oddly_breakable_by_hand=2},
sounds = default.node_sound_wood_defaults(),
@@ -890,7 +898,7 @@ minetest.register_node("default:bookshelf", {
minetest.register_node("default:glass", {
description = "Glass",
drawtype = "glasslike",
tile_images = {"default_glass.png"},
tiles ={"default_glass.png"},
inventory_image = minetest.inventorycube("default_glass.png"),
paramtype = "light",
sunlight_propagates = true,
@@ -902,7 +910,7 @@ minetest.register_node("default:glass", {
minetest.register_node("default:fence_wood", {
description = "Wooden Fence",
drawtype = "fencelike",
tile_images = {"default_wood.png"},
tiles ={"default_wood.png"},
inventory_image = "default_fence.png",
wield_image = "default_fence.png",
paramtype = "light",
@@ -918,7 +926,7 @@ minetest.register_node("default:fence_wood", {
minetest.register_node("default:rail", {
description = "Rail",
drawtype = "raillike",
tile_images = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
tiles ={"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
inventory_image = "default_rail.png",
wield_image = "default_rail.png",
paramtype = "light",
@@ -926,7 +934,7 @@ minetest.register_node("default:rail", {
walkable = false,
selection_box = {
type = "fixed",
--fixed = <default>
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {bendy=2,snappy=1,dig_immediate=2},
})
@@ -934,7 +942,7 @@ minetest.register_node("default:rail", {
minetest.register_node("default:ladder", {
description = "Ladder",
drawtype = "signlike",
tile_images = {"default_ladder.png"},
tiles ={"default_ladder.png"},
inventory_image = "default_ladder.png",
wield_image = "default_ladder.png",
paramtype = "light",
@@ -955,7 +963,7 @@ minetest.register_node("default:ladder", {
minetest.register_node("default:wood", {
description = "Wood",
tile_images = {"default_wood.png"},
tiles ={"default_wood.png"},
is_ground_content = true,
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
sounds = default.node_sound_wood_defaults(),
@@ -963,7 +971,7 @@ minetest.register_node("default:wood", {
minetest.register_node("default:mese", {
description = "Mese",
tile_images = {"default_mese.png"},
tiles ={"default_mese.png"},
is_ground_content = true,
groups = {cracky=1,level=2},
sounds = default.node_sound_defaults(),
@@ -971,7 +979,7 @@ minetest.register_node("default:mese", {
minetest.register_node("default:cloud", {
description = "Cloud",
tile_images = {"default_cloud.png"},
tiles ={"default_cloud.png"},
is_ground_content = true,
sounds = default.node_sound_defaults(),
})
@@ -980,7 +988,11 @@ minetest.register_node("default:water_flowing", {
description = "Water (flowing)",
inventory_image = minetest.inventorycube("default_water.png"),
drawtype = "flowingliquid",
tile_images = {"default_water.png"},
tiles ={"default_water.png"},
special_tiles = {
{name="default_water.png", backface_culling=false},
{name="default_water.png", backface_culling=true},
},
alpha = WATER_ALPHA,
paramtype = "light",
walkable = false,
@@ -992,10 +1004,6 @@ minetest.register_node("default:water_flowing", {
liquid_alternative_source = "default:water_source",
liquid_viscosity = WATER_VISC,
post_effect_color = {a=64, r=100, g=100, b=200},
special_materials = {
{image="default_water.png", backface_culling=false},
{image="default_water.png", backface_culling=true},
},
groups = {water=3, liquid=3},
})
@@ -1003,7 +1011,11 @@ minetest.register_node("default:water_source", {
description = "Water",
inventory_image = minetest.inventorycube("default_water.png"),
drawtype = "liquid",
tile_images = {"default_water.png"},
tiles ={"default_water.png"},
special_tiles = {
-- New-style water source material (mostly unused)
{name="default_water.png", backface_culling=false},
},
alpha = WATER_ALPHA,
paramtype = "light",
walkable = false,
@@ -1015,10 +1027,6 @@ minetest.register_node("default:water_source", {
liquid_alternative_source = "default:water_source",
liquid_viscosity = WATER_VISC,
post_effect_color = {a=64, r=100, g=100, b=200},
special_materials = {
-- New-style water source material (mostly unused)
{image="default_water.png", backface_culling=false},
},
groups = {water=3, liquid=3},
})
@@ -1026,7 +1034,19 @@ minetest.register_node("default:lava_flowing", {
description = "Lava (flowing)",
inventory_image = minetest.inventorycube("default_lava.png"),
drawtype = "flowingliquid",
tile_images = {"default_lava.png"},
tiles ={"default_lava.png"},
special_tiles = {
{
image="default_lava_flowing_animated.png",
backface_culling=false,
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
},
{
image="default_lava_flowing_animated.png",
backface_culling=true,
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
},
},
paramtype = "light",
light_source = LIGHT_MAX - 1,
walkable = false,
@@ -1039,10 +1059,6 @@ minetest.register_node("default:lava_flowing", {
liquid_viscosity = LAVA_VISC,
damage_per_second = 4*2,
post_effect_color = {a=192, r=255, g=64, b=0},
special_materials = {
{image="default_lava.png", backface_culling=false},
{image="default_lava.png", backface_culling=true},
},
groups = {lava=3, liquid=2, hot=3},
})
@@ -1050,7 +1066,14 @@ minetest.register_node("default:lava_source", {
description = "Lava",
inventory_image = minetest.inventorycube("default_lava.png"),
drawtype = "liquid",
tile_images = {"default_lava.png"},
--tiles ={"default_lava.png"},
tiles ={
{name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}}
},
special_tiles = {
-- New-style lava source material (mostly unused)
{name="default_lava.png", backface_culling=false},
},
paramtype = "light",
light_source = LIGHT_MAX - 1,
walkable = false,
@@ -1063,17 +1086,13 @@ minetest.register_node("default:lava_source", {
liquid_viscosity = LAVA_VISC,
damage_per_second = 4*2,
post_effect_color = {a=192, r=255, g=64, b=0},
special_materials = {
-- New-style lava source material (mostly unused)
{image="default_lava.png", backface_culling=false},
},
groups = {lava=3, liquid=2, hot=3},
})
minetest.register_node("default:torch", {
description = "Torch",
drawtype = "torchlike",
tile_images = {"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
tiles ={"default_torch_on_floor.png", "default_torch_on_ceiling.png", "default_torch.png"},
inventory_image = "default_torch_on_floor.png",
wield_image = "default_torch_on_floor.png",
paramtype = "light",
@@ -1095,14 +1114,13 @@ minetest.register_node("default:torch", {
minetest.register_node("default:sign_wall", {
description = "Sign",
drawtype = "signlike",
tile_images = {"default_sign_wall.png"},
tiles ={"default_sign_wall.png"},
inventory_image = "default_sign_wall.png",
wield_image = "default_sign_wall.png",
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
walkable = false,
metadata_name = "sign",
selection_box = {
type = "wallmounted",
--wall_top = <default>
@@ -1115,7 +1133,7 @@ minetest.register_node("default:sign_wall", {
on_construct = function(pos)
--local n = minetest.env:get_node(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", "hack:sign_text_input")
meta:set_string("formspec", "field[text;;${text}]")
meta:set_string("infotext", "\"\"")
end,
on_receive_fields = function(pos, formname, fields, sender)
@@ -1131,7 +1149,7 @@ minetest.register_node("default:sign_wall", {
minetest.register_node("default:chest", {
description = "Chest",
tile_images = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
"default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
paramtype2 = "facedir",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
@@ -1140,7 +1158,7 @@ minetest.register_node("default:chest", {
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"size[8,9]"..
"list[current_name;main;0,0;8,4;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", "Chest")
@@ -1152,25 +1170,6 @@ minetest.register_node("default:chest", {
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
on_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
minetest.log("action", player:get_player_name()..
" moves stuff in chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_move_allow_all(
pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_offer = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name()..
" moves stuff to chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_offer_allow_all(
pos, listname, index, stack, player)
end,
on_metadata_inventory_take = function(pos, listname, index, count, player)
minetest.log("action", player:get_player_name()..
" takes stuff from chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_take_allow_all(
pos, listname, index, count, player)
end,
})
local function has_locked_chest_privilege(meta, player)
@@ -1182,7 +1181,7 @@ end
minetest.register_node("default:chest_locked", {
description = "Locked Chest",
tile_images = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
tiles ={"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
"default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
paramtype2 = "facedir",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
@@ -1197,7 +1196,7 @@ minetest.register_node("default:chest_locked", {
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"size[8,9]"..
"list[current_name;main;0,0;8,4;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", "Locked Chest")
@@ -1210,53 +1209,55 @@ minetest.register_node("default:chest_locked", {
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
on_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return
return 0
end
return count
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return 0
end
return stack:get_count()
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return 0
end
return stack:get_count()
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", player:get_player_name()..
" moves stuff in locked chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_move_allow_all(
pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_offer = function(pos, listname, index, stack, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return stack
end
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name()..
" moves stuff to locked chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_offer_allow_all(
pos, listname, index, stack, player)
end,
on_metadata_inventory_take = function(pos, listname, index, count, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return
end
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name()..
" takes stuff from locked chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_take_allow_all(
pos, listname, index, count, player)
end,
})
default.furnace_inactive_formspec =
"invsize[8,9;]"..
"size[8,9]"..
"image[2,2;1,1;default_furnace_fire_bg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;1,1;]"..
@@ -1265,7 +1266,7 @@ default.furnace_inactive_formspec =
minetest.register_node("default:furnace", {
description = "Furnace",
tile_images = {"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
paramtype2 = "facedir",
groups = {cracky=2},
@@ -1296,7 +1297,7 @@ minetest.register_node("default:furnace", {
minetest.register_node("default:furnace_active", {
description = "Furnace",
tile_images = {"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
tiles ={"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
paramtype2 = "facedir",
light_source = 8,
@@ -1395,7 +1396,7 @@ minetest.register_abm({
meta:set_string("infotext","Furnace active: "..percent.."%")
hacky_swap_node(pos,"default:furnace_active")
meta:set_string("formspec",
"invsize[8,9;]"..
"size[8,9]"..
"image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-percent)..":default_furnace_fire_fg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
@@ -1444,7 +1445,7 @@ minetest.register_abm({
minetest.register_node("default:cobble", {
description = "Cobble",
tile_images = {"default_cobble.png"},
tiles ={"default_cobble.png"},
is_ground_content = true,
groups = {cracky=3},
sounds = default.node_sound_stone_defaults(),
@@ -1452,7 +1453,7 @@ minetest.register_node("default:cobble", {
minetest.register_node("default:mossycobble", {
description = "Mossy Cobble",
tile_images = {"default_mossycobble.png"},
tiles ={"default_mossycobble.png"},
is_ground_content = true,
groups = {cracky=3},
sounds = default.node_sound_stone_defaults(),
@@ -1460,7 +1461,7 @@ minetest.register_node("default:mossycobble", {
minetest.register_node("default:steelblock", {
description = "Steel Block",
tile_images = {"default_steel_block.png"},
tiles ={"default_steel_block.png"},
is_ground_content = true,
groups = {snappy=1,bendy=2},
sounds = default.node_sound_stone_defaults(),
@@ -1468,7 +1469,7 @@ minetest.register_node("default:steelblock", {
minetest.register_node("default:nyancat", {
description = "Nyancat",
tile_images = {"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
tiles ={"default_nc_side.png", "default_nc_side.png", "default_nc_side.png",
"default_nc_side.png", "default_nc_back.png", "default_nc_front.png"},
inventory_image = "default_nc_front.png",
paramtype2 = "facedir",
@@ -1479,7 +1480,7 @@ minetest.register_node("default:nyancat", {
minetest.register_node("default:nyancat_rainbow", {
description = "Nyancat Rainbow",
tile_images = {"default_nc_rb.png"},
tiles ={"default_nc_rb.png"},
inventory_image = "default_nc_rb.png",
groups = {cracky=2},
sounds = default.node_sound_defaults(),
@@ -1489,7 +1490,7 @@ minetest.register_node("default:sapling", {
description = "Sapling",
drawtype = "plantlike",
visual_scale = 1.0,
tile_images = {"default_sapling.png"},
tiles ={"default_sapling.png"},
inventory_image = "default_sapling.png",
wield_image = "default_sapling.png",
paramtype = "light",
@@ -1502,7 +1503,7 @@ minetest.register_node("default:apple", {
description = "Apple",
drawtype = "plantlike",
visual_scale = 1.0,
tile_images = {"default_apple.png"},
tiles ={"default_apple.png"},
inventory_image = "default_apple.png",
paramtype = "light",
sunlight_propagates = true,
@@ -1562,40 +1563,6 @@ minetest.register_craftitem("default:scorched_stuff", {
inventory_image = "default_scorched_stuff.png",
})
--
-- Creative inventory
--
minetest.add_to_creative_inventory('default:pick_mese')
minetest.add_to_creative_inventory('default:pick_steel')
minetest.add_to_creative_inventory('default:axe_steel')
minetest.add_to_creative_inventory('default:shovel_steel')
minetest.add_to_creative_inventory('default:torch')
minetest.add_to_creative_inventory('default:cobble')
minetest.add_to_creative_inventory('default:dirt')
minetest.add_to_creative_inventory('default:stone')
minetest.add_to_creative_inventory('default:sand')
minetest.add_to_creative_inventory('default:sandstone')
minetest.add_to_creative_inventory('default:clay')
minetest.add_to_creative_inventory('default:brick')
minetest.add_to_creative_inventory('default:tree')
minetest.add_to_creative_inventory('default:wood')
minetest.add_to_creative_inventory('default:leaves')
minetest.add_to_creative_inventory('default:cactus')
minetest.add_to_creative_inventory('default:papyrus')
minetest.add_to_creative_inventory('default:bookshelf')
minetest.add_to_creative_inventory('default:glass')
minetest.add_to_creative_inventory('default:fence_wood')
minetest.add_to_creative_inventory('default:rail')
minetest.add_to_creative_inventory('default:mese')
minetest.add_to_creative_inventory('default:chest')
minetest.add_to_creative_inventory('default:furnace')
minetest.add_to_creative_inventory('default:sign_wall')
minetest.add_to_creative_inventory('default:water_source')
minetest.add_to_creative_inventory('default:lava_source')
minetest.add_to_creative_inventory('default:ladder')
--
-- Aliases for the current map generator outputs
--
@@ -1712,133 +1679,24 @@ function on_punchnode(p, node)
end
minetest.register_on_punchnode(on_punchnode)
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)
--
-- Test some things
--
local function test_get_craft_result()
print("test_get_craft_result()")
minetest.log("info", "test_get_craft_result()")
-- normal
local input = {
method = "normal",
width = 2,
items = {"", "default:coal_lump", "", "default:stick"}
}
print("torch crafting input: "..dump(input))
minetest.log("info", "torch crafting input: "..dump(input))
local output, decremented_input = minetest.get_craft_result(input)
print("torch crafting output: "..dump(output))
print("torch crafting decremented input: "..dump(decremented_input))
minetest.log("info", "torch crafting output: "..dump(output))
minetest.log("info", "torch crafting decremented input: "..dump(decremented_input))
assert(output.item)
print("torch crafting output.item:to_table(): "..dump(output.item:to_table()))
minetest.log("info", "torch crafting output.item:to_table(): "..dump(output.item:to_table()))
assert(output.item:get_name() == "default:torch")
assert(output.item:get_count() == 4)
-- fuel
@@ -1847,10 +1705,10 @@ local function test_get_craft_result()
width = 1,
items = {"default:coal_lump"}
}
print("coal fuel input: "..dump(input))
minetest.log("info", "coal fuel input: "..dump(input))
local output, decremented_input = minetest.get_craft_result(input)
print("coal fuel output: "..dump(output))
print("coal fuel decremented input: "..dump(decremented_input))
minetest.log("info", "coal fuel output: "..dump(output))
minetest.log("info", "coal fuel decremented input: "..dump(decremented_input))
assert(output.time)
assert(output.time > 0)
-- cook
@@ -1859,14 +1717,14 @@ local function test_get_craft_result()
width = 1,
items = {"default:cobble"}
}
print("cobble cooking input: "..dump(output))
minetest.log("info", "cobble cooking input: "..dump(output))
local output, decremented_input = minetest.get_craft_result(input)
print("cobble cooking output: "..dump(output))
print("cobble cooking decremented input: "..dump(decremented_input))
minetest.log("info", "cobble cooking output: "..dump(output))
minetest.log("info", "cobble cooking decremented input: "..dump(decremented_input))
assert(output.time)
assert(output.time > 0)
assert(output.item)
print("cobble cooking output.item:to_table(): "..dump(output.item:to_table()))
minetest.log("info", "cobble cooking output.item:to_table(): "..dump(output.item:to_table()))
assert(output.item:get_name() == "default:stone")
assert(output.item:get_count() == 1)
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -6,6 +6,11 @@
experimental = {}
function experimental.print_to_everything(msg)
minetest.log("action", msg)
minetest.chat_send_all(msg)
end
--[[
experimental.player_visual_index = 0
function switch_player_visual()
@@ -97,235 +102,10 @@ function on_step(dtime)
end
minetest.register_globalstep(on_step)
-- An example furnace-thing implemented in Lua
--[[
minetest.register_node("experimental:luafurnace", {
tile_images = {"default_lava.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_front.png"},
--inventory_image = "furnace_front.png",
inventory_image = minetest.inventorycube("default_furnace_front.png"),
paramtype = "facedir_simple",
metadata_name = "generic",
material = minetest.digprop_stonelike(3.0),
})
minetest.register_on_placenode(function(pos, newnode, placer)
if newnode.name == "experimental:luafurnace" then
local meta = minetest.env:get_meta(pos)
meta:inventory_set_list("fuel", {""})
meta:inventory_set_list("src", {""})
meta:inventory_set_list("dst", {"","","",""})
meta:set_inventory_draw_spec(
"invsize[8,9;]"
.."list[current_name;fuel;2,3;1,1;]"
.."list[current_name;src;2,1;1,1;]"
.."list[current_name;dst;5,1;2,2;]"
.."list[current_player;main;0,5;8,4;]"
)
local total_cooked = 0;
meta:set_string("total_cooked", total_cooked)
meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
end
end)
minetest.register_abm({
nodenames = {"experimental:luafurnace"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.env:get_meta(pos)
for i, name in ipairs({
"fuel_totaltime",
"fuel_time",
"src_totaltime",
"src_time"
}) do
if not meta:get_string(name) then
meta:set_string(name, 0)
end
end
local inv = meta:get_inventory()
local fuelitem = inv:get_stack("fuel", 1):peek_item()
local srcitem = inv:get_stack("src", 1):peek_item()
--print("fuelitem="..dump(fuelitem))
--print("srcitem="..dump(srcitem))
local was_active = false
local src_cooktime = -1
local result_stackstring = nil
if srcitem then
local prop = get_item_definition(srcitem)
if prop and prop.cookresult_itemstring ~= "" then
result_stackstring = prop.cookresult_itemstring
src_cooktime = prop.furnace_cooktime or 3
end
end
print("src_cooktime="..dump(src_cooktime))
print("result_stackstring="..dump(result_stackstring))
if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
was_active = true
meta:set_string("fuel_time", tonumber(meta:get_string("fuel_time")) + 1)
meta:set_string("src_time", tonumber(meta:get_string("src_time")) + 1)
--print("result_stackstring="..dump(result_stackstring))
--print('tonumber(meta:get_string("src_time"))='..dump(tonumber(meta:get_string("src_time"))))
--print("src_cooktime="..dump(src_cooktime))
if result_stackstring and tonumber(meta:get_string("src_time")) >= src_cooktime and src_cooktime >= 0 then
-- Put result in "dst" list
success = inv:autoinsert_stackstring("dst", result_stackstring)
if not success then
print("Could not autoinsert '"..result_stackstring.."'")
end
-- If succeeded, take stuff from "src" list
if success then
srcstack = inv:get_stack("src", 1)
srcstack:take_item()
inv:set_stack("src", 1, srcstack)
end
meta:set_string("src_time", 0)
end
end
if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
meta:set_infotext("Furnace active: "..(tonumber(meta:get_string("fuel_time"))/tonumber(meta:get_string("fuel_totaltime"))*100).."%")
return
end
local srcitem = inv:get_stack("src", 1):peek_item()
local src_cooktime = 0
local result_stackstring = nil
if srcitem then
local prop = get_item_definition(srcitem)
if prop and prop.cookresult_itemstring ~= "" then
result_stackstring = prop.cookresult_itemstring
src_cooktime = prop.furnace_cooktime or 3
end
end
local fuelitem = inv:get_stack("fuel", 1):peek_item()
if not result_stackstring or not fuelitem then
if was_active then
meta:set_infotext("Furnace is empty")
end
return
end
local burntime = -1
if fuelitem then
local prop = get_item_definition(fuelitem)
if prop then
burntime = prop.furnace_burntime or -1
end
end
if burntime <= 0 then
meta:set_infotext("Furnace out of fuel")
return
end
meta:set_string("fuel_totaltime", burntime)
meta:set_string("fuel_time", 0)
local stack = inv:get_stack("fuel", 1)
stack:take_item()
inv:set_stack("fuel", 1, stack)
end,
})
minetest.register_abm({
nodenames = {"experimental:luafurnace"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.env:get_meta(pos)
local fuellist = meta:inventory_get_list("fuel")
local srclist = meta:inventory_get_list("src")
local dstlist = meta:inventory_get_list("dst")
if fuellist == nil or srclist == nil or dstlist == nil then
return
end
_, srcitem = stackstring_take_item(srclist[1])
_, fuelitem = stackstring_take_item(fuellist[1])
if not srcitem or not fuelitem then return end
if fuelitem.type == "node" then
local prop = minetest.registered_nodes[fuelitem.name]
if prop == nil then return end
if prop.furnace_burntime < 0 then return end
else
return
end
local resultstack = nil
if srcitem.type == "node" then
local prop = minetest.registered_nodes[srcitem.name]
if prop == nil then return end
if prop.cookresult_item == "" then return end
resultstack = prop.cookresult_item
else
return
end
if resultstack == nil then
return
end
dstlist[1], success = stackstring_put_stackstring(dstlist[1], resultstack)
if not success then
return
end
fuellist[1], _ = stackstring_take_item(fuellist[1])
srclist[1], _ = stackstring_take_item(srclist[1])
meta:inventory_set_list("fuel", fuellist)
meta:inventory_set_list("src", srclist)
meta:inventory_set_list("dst", dstlist)
local total_cooked = meta:get_string("total_cooked")
total_cooked = tonumber(total_cooked) + 1
meta:set_string("total_cooked", total_cooked)
meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
end,
})
minetest.register_craft({
output = 'node "experimental:luafurnace" 1',
recipe = {
{'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
{'node "default:cobble"', 'node "default:steel_ingot"', 'node "default:cobble"'},
{'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
}
})
--]]
--
-- Random stuff
--
--[[
minetest.register_tool("experimental:horribletool", {
image = "default_lava.png",
basetime = 2.0
dt_weight = 0.2
dt_crackiness = 0.2
dt_crumbliness = 0.2
dt_cuttability = 0.2
basedurability = 50
dd_weight = -5
dd_crackiness = -5
dd_crumbliness = -5
dd_cuttability = -5
})
--]]
--
-- TNT (not functional)
--
@@ -662,6 +442,149 @@ minetest.register_abm({
end,
})--]]
minetest.register_node("experimental:tester_node_1", {
description = "Tester Node 1 (construct/destruct/timer)",
tile_images = {"wieldhand.png"},
groups = {oddly_breakable_by_hand=2},
sounds = default.node_sound_wood_defaults(),
-- This was known to cause a bug in minetest.item_place_node() when used
-- via minetest.env:place_node(), causing a placer with no position
paramtype2 = "facedir",
on_construct = function(pos)
experimental.print_to_everything("experimental:tester_node_1:on_construct("..minetest.pos_to_string(pos)..")")
local meta = minetest.env:get_meta(pos)
meta:set_string("mine", "test")
local timer = minetest.env:get_node_timer(pos)
timer:start(4, 3)
end,
after_place_node = function(pos, placer)
experimental.print_to_everything("experimental:tester_node_1:after_place_node("..minetest.pos_to_string(pos)..")")
local meta = minetest.env:get_meta(pos)
if meta:get_string("mine") == "test" then
experimental.print_to_everything("correct metadata found")
else
experimental.print_to_everything("incorrect metadata found")
end
end,
on_destruct = function(pos)
experimental.print_to_everything("experimental:tester_node_1:on_destruct("..minetest.pos_to_string(pos)..")")
end,
after_destruct = function(pos)
experimental.print_to_everything("experimental:tester_node_1:after_destruct("..minetest.pos_to_string(pos)..")")
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
experimental.print_to_everything("experimental:tester_node_1:after_dig_node("..minetest.pos_to_string(pos)..")")
end,
on_timer = function(pos, elapsed)
experimental.print_to_everything("on_timer(): elapsed="..dump(elapsed))
return true
end,
})
minetest.register_craftitem("experimental:tester_tool_1", {
description = "Tester Tool 1",
inventory_image = "experimental_tester_tool_1.png",
on_use = function(itemstack, user, pointed_thing)
--print(dump(pointed_thing))
if pointed_thing.type == "node" then
if minetest.env:get_node(pointed_thing.under).name == "experimental:tester_node_1" then
local p = pointed_thing.under
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
minetest.env:dig_node(p)
else
local p = pointed_thing.above
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
minetest.env:place_node(p, {name="experimental:tester_node_1"})
end
end
end,
})
minetest.register_craft({
output = 'experimental:tester_tool_1',
recipe = {
{'group:crumbly'},
{'group:crumbly'},
}
})
--[[minetest.register_on_joinplayer(function(player)
minetest.after(3, function()
player:set_inventory_formspec("size[8,7.5]"..
"image[1,0.6;1,2;player.png]"..
"list[current_player;main;0,3.5;8,4;]"..
"list[current_player;craft;3,0;3,3;]"..
"list[current_player;craftpreview;7,1;1,1;]")
end)
end)]]
-- Create a detached inventory
local inv = minetest.create_detached_inventory("test_inventory", {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
experimental.print_to_everything("allow move asked")
return count -- Allow all
end,
allow_put = function(inv, listname, index, stack, player)
experimental.print_to_everything("allow put asked")
return 1 -- Allow only 1
end,
allow_take = function(inv, listname, index, stack, player)
experimental.print_to_everything("allow take asked")
return 4 -- Allow 4 at max
end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
experimental.print_to_everything(player:get_player_name().." moved items")
end,
on_put = function(inv, listname, index, stack, player)
experimental.print_to_everything(player:get_player_name().." put items")
end,
on_take = function(inv, listname, index, stack, player)
experimental.print_to_everything(player:get_player_name().." took items")
end,
})
inv:set_size("main", 4*6)
inv:add_item("main", "experimental:tester_tool_1")
inv:add_item("main", "experimental:tnt 5")
minetest.register_chatcommand("test1", {
params = "",
description = "Test 1: Modify player's inventory view",
func = function(name, param)
local player = minetest.env:get_player_by_name(name)
if not player then
return
end
player:set_inventory_formspec(
"size[13,7.5]"..
"image[6,0.6;1,2;player.png]"..
"list[current_player;main;5,3.5;8,4;]"..
"list[current_player;craft;8,0;3,3;]"..
"list[current_player;craftpreview;12,1;1,1;]"..
"list[detached:test_inventory;main;0,0;4,6;0]"..
"button[0.5,7;2,1;button1;Button 1]"..
"button_exit[2.5,7;2,1;button2;Exit Button]"
)
minetest.chat_send_player(name, "Done.");
end,
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
experimental.print_to_everything("Inventory fields 1: player="..player:get_player_name()..", fields="..dump(fields))
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
experimental.print_to_everything("Inventory fields 2: player="..player:get_player_name()..", fields="..dump(fields))
return true -- Disable the first callback
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
experimental.print_to_everything("Inventory fields 3: player="..player:get_player_name()..", fields="..dump(fields))
end)
minetest.log("experimental modname="..dump(minetest.get_current_modname()))
minetest.log("experimental modpath="..dump(minetest.get_modpath("experimental")))
minetest.log("experimental worldpath="..dump(minetest.get_worldpath()))

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

View File

@@ -11,5 +11,6 @@ minetest.register_on_newplayer(function(player)
player:get_inventory():add_item('main', 'default:pick_mese')
player:get_inventory():add_item('main', 'default:mese 99')
player:get_inventory():add_item('main', 'default:water_source 99')
player:get_inventory():add_item('main', 'experimental:tester_tool_1')
end)

View File

@@ -0,0 +1 @@
default

View File

@@ -0,0 +1,93 @@
stairs = {}
-- Node will be called stairs:stair_<subname>
function stairs.register_stair(subname, recipeitem, groups, images, description)
minetest.register_node("stairs:stair_" .. subname, {
description = description,
drawtype = "nodebox",
tile_images = images,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = true,
groups = groups,
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
{-0.5, 0, 0, 0.5, 0.5, 0.5},
},
},
})
minetest.register_craft({
output = 'stairs:stair_' .. subname .. ' 4',
recipe = {
{recipeitem, "", ""},
{recipeitem, recipeitem, ""},
{recipeitem, recipeitem, recipeitem},
},
})
end
-- Node will be called stairs:slab_<subname>
function stairs.register_slab(subname, recipeitem, groups, images, description)
minetest.register_node("stairs:slab_" .. subname, {
description = description,
drawtype = "nodebox",
tile_images = images,
paramtype = "light",
is_ground_content = true,
groups = groups,
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
},
selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
},
})
minetest.register_craft({
output = 'stairs:slab_' .. subname .. ' 3',
recipe = {
{recipeitem, recipeitem, recipeitem},
},
})
end
-- Nodes will be called stairs:{stair,slab}_<subname>
function stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab)
stairs.register_stair(subname, recipeitem, groups, images, desc_stair)
stairs.register_slab(subname, recipeitem, groups, images, desc_slab)
end
stairs.register_stair_and_slab("wood", "default:wood",
{snappy=2,choppy=2,oddly_breakable_by_hand=2},
{"default_wood.png"},
"Wooden stair",
"Wooden slab")
stairs.register_stair_and_slab("stone", "default:stone",
{cracky=3},
{"default_stone.png"},
"Stone stair",
"Stone slab")
stairs.register_stair_and_slab("cobble", "default:cobble",
{cracky=3},
{"default_cobble.png"},
"Cobble stair",
"Cobble slab")
stairs.register_stair_and_slab("brick", "default:brick",
{cracky=3},
{"default_brick.png"},
"Brick stair",
"Brick slab")
stairs.register_stair_and_slab("sandstone", "default:sandstone",
{crumbly=2,cracky=2},
{"default_sandstone.png"},
"Sandstone stair",
"Sandstone slab")

View File

@@ -52,7 +52,8 @@
# Some (temporary) keys for debugging
#keymap_print_debug_stacks = KEY_KEY_P
# The desired FPS
# Minimum FPS
# The amount of rendered stuff is dynamically set according to this
#wanted_fps = 30
# If FPS would go higher than this, limit it by sleeping
# (to not waste CPU power for no benefit)
@@ -117,6 +118,8 @@
# Sound settings
#enable_sound = true
#sound_volume = 0.7
# Whether node texture animations should be desynchronized per MapBlock
#desynchronize_mapblock_texture_animation = true
#
# Server stuff
@@ -144,14 +147,21 @@
#give_initial_stuff = false
# New users need to input this password
#default_password =
# Available privileges: build, teleport, settime, privs, shout
#default_privs = build, shout
# Available privileges: interact, shout, teleport, settime, privs, ...
# See /privs in game for a full list on your server and mod configuration.
#default_privs = interact, shout
# Whether players are shown to clients without any range limit
#unlimited_player_transfer_distance = true
# Whether to enable players killing each other
#enable_pvp = true
# If this is set, players will always (re)spawn at the given position
#static_spawnpoint = 0, 10, 0
# If true, new players cannot join with an empty password
#disallow_empty_password = false
# If true, disable cheat prevention in multiplayer
#disable_anticheat = false
# If true, actions are recorded for rollback
#enable_rollback_recording = false
# Profiler data print interval. #0 = disable.
#profiler_print_interval = 0
@@ -178,4 +188,7 @@
# To reduce lag, block transfers are slowed down when a player is building something.
# This determines how long they are slowed down after placing or removing a node.
#full_block_send_enable_min_time_from_building = 2.0
# Length of a server tick in dedicated server
#dedicated_server_step = 0.05
# Can be set to true to disable shutting down on invalid world data
#ignore_world_load_errors = false

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: minetest\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-08-02 12:36+0200\n"
"POT-Creation-Date: 2012-06-04 23:25+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,461 +17,278 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/guiKeyChangeMenu.cpp:84
msgid "KEYBINDINGS"
#: src/guiConfirmMenu.cpp:120
msgid "Yes"
msgstr ""
#: src/guiKeyChangeMenu.cpp:94
msgid "Forward"
#: src/guiConfirmMenu.cpp:126
msgid "No"
msgstr ""
#: src/guiKeyChangeMenu.cpp:111
msgid "Backward"
#: src/guiCreateWorld.cpp:116
msgid "World name"
msgstr ""
#: src/guiKeyChangeMenu.cpp:127 src/guiKeyChangeMenu.h:38
msgid "Left"
#: src/guiCreateWorld.cpp:135
msgid "Game"
msgstr ""
#: src/guiKeyChangeMenu.cpp:142 src/guiKeyChangeMenu.h:38
msgid "Right"
#: src/guiCreateWorld.cpp:159
msgid "Create"
msgstr ""
#: src/guiKeyChangeMenu.cpp:158
msgid "Use"
msgstr ""
#: src/guiKeyChangeMenu.cpp:173
msgid "Sneak"
msgstr ""
#: src/guiKeyChangeMenu.cpp:189
msgid "Jump"
msgstr ""
#: src/guiKeyChangeMenu.cpp:204
msgid "Inventory"
msgstr ""
#: src/guiKeyChangeMenu.cpp:220
msgid "Chat"
msgstr ""
#: src/guiKeyChangeMenu.cpp:236
msgid "Toggle fly"
msgstr ""
#: src/guiKeyChangeMenu.cpp:251
msgid "Toggle fast"
msgstr ""
#: src/guiKeyChangeMenu.cpp:266
msgid "Range select"
msgstr ""
#: src/guiKeyChangeMenu.cpp:283
msgid "Print stacks"
msgstr ""
#: src/guiKeyChangeMenu.cpp:298
msgid "Save"
msgstr ""
#: src/guiKeyChangeMenu.cpp:304 src/guiKeyChangeMenu.h:33
#: src/guiCreateWorld.cpp:165 src/guiKeyChangeMenu.cpp:374 src/keycode.cpp:221
msgid "Cancel"
msgstr ""
#: src/guiKeyChangeMenu.cpp:537 src/guiKeyChangeMenu.cpp:542
#: src/guiKeyChangeMenu.cpp:547 src/guiKeyChangeMenu.cpp:552
#: src/guiKeyChangeMenu.cpp:557 src/guiKeyChangeMenu.cpp:562
#: src/guiKeyChangeMenu.cpp:567 src/guiKeyChangeMenu.cpp:572
#: src/guiKeyChangeMenu.cpp:577 src/guiKeyChangeMenu.cpp:582
#: src/guiKeyChangeMenu.cpp:587 src/guiKeyChangeMenu.cpp:592
#: src/guiKeyChangeMenu.cpp:597
#: src/guiDeathScreen.cpp:96
msgid "You died."
msgstr ""
#: src/guiDeathScreen.cpp:104
msgid "Respawn"
msgstr ""
#: src/guiKeyChangeMenu.cpp:111
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
msgstr ""
#: src/guiKeyChangeMenu.cpp:121
msgid "Forward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:138
msgid "Backward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:154 src/keycode.cpp:226
msgid "Left"
msgstr ""
#: src/guiKeyChangeMenu.cpp:169 src/keycode.cpp:226
msgid "Right"
msgstr ""
#: src/guiKeyChangeMenu.cpp:185
msgid "Use"
msgstr ""
#: src/guiKeyChangeMenu.cpp:200
msgid "Sneak"
msgstr ""
#: src/guiKeyChangeMenu.cpp:216
msgid "Jump"
msgstr ""
#: src/guiKeyChangeMenu.cpp:231
msgid "Drop"
msgstr ""
#: src/guiKeyChangeMenu.cpp:246
msgid "Inventory"
msgstr ""
#: src/guiKeyChangeMenu.cpp:262
msgid "Chat"
msgstr ""
#: src/guiKeyChangeMenu.cpp:276
msgid "Command"
msgstr ""
#: src/guiKeyChangeMenu.cpp:290
msgid "Console"
msgstr ""
#: src/guiKeyChangeMenu.cpp:306
msgid "Toggle fly"
msgstr ""
#: src/guiKeyChangeMenu.cpp:321
msgid "Toggle fast"
msgstr ""
#: src/guiKeyChangeMenu.cpp:336
msgid "Range select"
msgstr ""
#: src/guiKeyChangeMenu.cpp:353
msgid "Print stacks"
msgstr ""
#: src/guiKeyChangeMenu.cpp:368
msgid "Save"
msgstr ""
#: src/guiKeyChangeMenu.cpp:626 src/guiKeyChangeMenu.cpp:631
#: src/guiKeyChangeMenu.cpp:636 src/guiKeyChangeMenu.cpp:641
#: src/guiKeyChangeMenu.cpp:646 src/guiKeyChangeMenu.cpp:651
#: src/guiKeyChangeMenu.cpp:656 src/guiKeyChangeMenu.cpp:661
#: src/guiKeyChangeMenu.cpp:666 src/guiKeyChangeMenu.cpp:671
#: src/guiKeyChangeMenu.cpp:676 src/guiKeyChangeMenu.cpp:681
#: src/guiKeyChangeMenu.cpp:686 src/guiKeyChangeMenu.cpp:691
#: src/guiKeyChangeMenu.cpp:696 src/guiKeyChangeMenu.cpp:701
msgid "press Key"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Left Button"
#: src/guiMainMenu.cpp:217
msgid "Singleplayer"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Middle Button"
#: src/guiMainMenu.cpp:218
msgid "Multiplayer"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Right Button"
#: src/guiMainMenu.cpp:219
msgid "Advanced"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "X Button 1"
#: src/guiMainMenu.cpp:220
msgid "Settings"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Back"
#: src/guiMainMenu.cpp:221
msgid "Credits"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Clear"
#: src/guiMainMenu.cpp:252
msgid "Select World:"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Return"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Tab"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "X Button 2"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Capital"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Control"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Kana"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Menu"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Pause"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Shift"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Convert"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Escape"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Final"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Junja"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Kanji"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Nonconvert"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Accept"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "End"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Home"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Mode Change"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Next"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Priot"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Space"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Down"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Execute"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Print"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Select"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Up"
msgstr ""
#: src/guiKeyChangeMenu.h:39
#: src/guiMainMenu.cpp:274 src/keycode.cpp:227
msgid "Delete"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Help"
#: src/guiMainMenu.cpp:281
msgid "New"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Insert"
#: src/guiMainMenu.cpp:289
msgid "Configure"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Snapshot"
msgstr ""
#: src/guiKeyChangeMenu.h:42
msgid "Left Windows"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Apps"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Numpad 0"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Numpad 1"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Right Windows"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Sleep"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 2"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 3"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 4"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 5"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 6"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 7"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad *"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad +"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad -"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad /"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad 8"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad 9"
msgstr ""
#: src/guiKeyChangeMenu.h:49
msgid "Num Lock"
msgstr ""
#: src/guiKeyChangeMenu.h:49
msgid "Scroll Lock"
msgstr ""
#: src/guiKeyChangeMenu.h:50
msgid "Left Shift"
msgstr ""
#: src/guiKeyChangeMenu.h:50
msgid "Right Shight"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Left Control"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Left Menu"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Right Control"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Right Menu"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Comma"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Minus"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Period"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Plus"
msgstr ""
#: src/guiKeyChangeMenu.h:57
msgid "Attn"
msgstr ""
#: src/guiKeyChangeMenu.h:57
msgid "CrSel"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "Erase OEF"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "ExSel"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "OEM Clear"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "PA1"
msgstr ""
#: src/guiKeyChangeMenu.h:58
#: src/guiMainMenu.cpp:304 src/keycode.cpp:246
msgid "Play"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "Zoom"
msgstr ""
#: src/guiMainMenu.cpp:181
msgid "Name/Password"
msgstr ""
#: src/guiMainMenu.cpp:206
msgid "Address/Port"
msgstr ""
#: src/guiMainMenu.cpp:228
msgid "Leave address blank to start a local server."
msgstr ""
#: src/guiMainMenu.cpp:235
msgid "Fancy trees"
msgstr ""
#: src/guiMainMenu.cpp:241
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:249
msgid "Start Game / Connect"
msgstr ""
#: src/guiMainMenu.cpp:258
msgid "Change keys"
msgstr ""
#: src/guiMainMenu.cpp:281
#: src/guiMainMenu.cpp:315 src/guiMainMenu.cpp:492
msgid "Creative Mode"
msgstr ""
#: src/guiMainMenu.cpp:287
#: src/guiMainMenu.cpp:321 src/guiMainMenu.cpp:498
msgid "Enable Damage"
msgstr ""
#: src/guiMainMenu.cpp:295
msgid "Delete map"
#: src/guiMainMenu.cpp:341 src/guiMainMenu.cpp:414
msgid "Name/Password"
msgstr ""
#: src/guiMessageMenu.cpp:94 src/guiTextInputMenu.cpp:112
#: src/guiMainMenu.cpp:368 src/guiMainMenu.cpp:441
msgid "Address/Port"
msgstr ""
#: src/guiMainMenu.cpp:394 src/guiMainMenu.cpp:473
msgid "Start Game / Connect"
msgstr ""
#: src/guiMainMenu.cpp:464
msgid "Leave address blank to start a local server."
msgstr ""
#: src/guiMainMenu.cpp:505 src/guiMainMenu.cpp:833
msgid "Delete world"
msgstr ""
#: src/guiMainMenu.cpp:512
msgid "Create world"
msgstr ""
#: src/guiMainMenu.cpp:546
msgid "Fancy trees"
msgstr ""
#: src/guiMainMenu.cpp:552
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:558
msgid "3D Clouds"
msgstr ""
#: src/guiMainMenu.cpp:564
msgid "Opaque water"
msgstr ""
#: src/guiMainMenu.cpp:573
msgid "Change keys"
msgstr ""
#: src/guiMainMenu.cpp:804
msgid "Address required."
msgstr ""
#: src/guiMainMenu.cpp:822
msgid "Cannot delete world: Nothing selected"
msgstr ""
#: src/guiMainMenu.cpp:837
msgid "Files to be deleted"
msgstr ""
#: src/guiMainMenu.cpp:853
msgid "Cannot create world: No games found"
msgstr ""
#: src/guiMainMenu.cpp:866
msgid "Nothing here"
msgstr ""
#: src/guiMainMenu.cpp:915
msgid "Failed to delete all world files"
msgstr ""
#: src/guiMessageMenu.cpp:109 src/guiTextInputMenu.cpp:123
msgid "Proceed"
msgstr ""
#: src/guiPasswordChange.cpp:103
#: src/guiPasswordChange.cpp:108
msgid "Old Password"
msgstr ""
#: src/guiPasswordChange.cpp:120
#: src/guiPasswordChange.cpp:125
msgid "New Password"
msgstr ""
#: src/guiPasswordChange.cpp:136
#: src/guiPasswordChange.cpp:141
msgid "Confirm Password"
msgstr ""
#: src/guiPasswordChange.cpp:153
#: src/guiPasswordChange.cpp:158
msgid "Change"
msgstr ""
#: src/guiPasswordChange.cpp:162
#: src/guiPasswordChange.cpp:167
msgid "Passwords do not match!"
msgstr ""
#: src/guiPauseMenu.cpp:111
#: src/guiPauseMenu.cpp:118
msgid "Continue"
msgstr ""
#: src/guiPauseMenu.cpp:118
#: src/guiPauseMenu.cpp:127
msgid "Change Password"
msgstr ""
#: src/guiPauseMenu.cpp:125
msgid "Disconnect"
#: src/guiPauseMenu.cpp:135
msgid "Exit to Menu"
msgstr ""
#: src/guiPauseMenu.cpp:132
#: src/guiPauseMenu.cpp:142
msgid "Exit to OS"
msgstr ""
#: src/guiPauseMenu.cpp:139
#: src/guiPauseMenu.cpp:149
msgid ""
"Default Controls:\n"
"- WASD: Walk\n"
@@ -485,3 +302,325 @@ msgid ""
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""
#: src/keycode.cpp:221
msgid "Left Button"
msgstr ""
#: src/keycode.cpp:221
msgid "Middle Button"
msgstr ""
#: src/keycode.cpp:221
msgid "Right Button"
msgstr ""
#: src/keycode.cpp:221
msgid "X Button 1"
msgstr ""
#: src/keycode.cpp:222
msgid "Back"
msgstr ""
#: src/keycode.cpp:222
msgid "Clear"
msgstr ""
#: src/keycode.cpp:222
msgid "Return"
msgstr ""
#: src/keycode.cpp:222
msgid "Tab"
msgstr ""
#: src/keycode.cpp:222
msgid "X Button 2"
msgstr ""
#: src/keycode.cpp:223
msgid "Capital"
msgstr ""
#: src/keycode.cpp:223
msgid "Control"
msgstr ""
#: src/keycode.cpp:223
msgid "Kana"
msgstr ""
#: src/keycode.cpp:223
msgid "Menu"
msgstr ""
#: src/keycode.cpp:223
msgid "Pause"
msgstr ""
#: src/keycode.cpp:223
msgid "Shift"
msgstr ""
#: src/keycode.cpp:224
msgid "Convert"
msgstr ""
#: src/keycode.cpp:224
msgid "Escape"
msgstr ""
#: src/keycode.cpp:224
msgid "Final"
msgstr ""
#: src/keycode.cpp:224
msgid "Junja"
msgstr ""
#: src/keycode.cpp:224
msgid "Kanji"
msgstr ""
#: src/keycode.cpp:224
msgid "Nonconvert"
msgstr ""
#: src/keycode.cpp:225
msgid "Accept"
msgstr ""
#: src/keycode.cpp:225
msgid "End"
msgstr ""
#: src/keycode.cpp:225
msgid "Home"
msgstr ""
#: src/keycode.cpp:225
msgid "Mode Change"
msgstr ""
#: src/keycode.cpp:225
msgid "Next"
msgstr ""
#: src/keycode.cpp:225
msgid "Prior"
msgstr ""
#: src/keycode.cpp:225
msgid "Space"
msgstr ""
#: src/keycode.cpp:226
msgid "Down"
msgstr ""
#: src/keycode.cpp:226
msgid "Execute"
msgstr ""
#: src/keycode.cpp:226
msgid "Print"
msgstr ""
#: src/keycode.cpp:226
msgid "Select"
msgstr ""
#: src/keycode.cpp:226
msgid "Up"
msgstr ""
#: src/keycode.cpp:227
msgid "Help"
msgstr ""
#: src/keycode.cpp:227
msgid "Insert"
msgstr ""
#: src/keycode.cpp:227
msgid "Snapshot"
msgstr ""
#: src/keycode.cpp:230
msgid "Left Windows"
msgstr ""
#: src/keycode.cpp:231
msgid "Apps"
msgstr ""
#: src/keycode.cpp:231
msgid "Numpad 0"
msgstr ""
#: src/keycode.cpp:231
msgid "Numpad 1"
msgstr ""
#: src/keycode.cpp:231
msgid "Right Windows"
msgstr ""
#: src/keycode.cpp:231
msgid "Sleep"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 2"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 3"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 4"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 5"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 6"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 7"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad *"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad +"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad -"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad /"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad 8"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad 9"
msgstr ""
#: src/keycode.cpp:237
msgid "Num Lock"
msgstr ""
#: src/keycode.cpp:237
msgid "Scroll Lock"
msgstr ""
#: src/keycode.cpp:238
msgid "Left Shift"
msgstr ""
#: src/keycode.cpp:238
msgid "Right Shift"
msgstr ""
#: src/keycode.cpp:239
msgid "Left Control"
msgstr ""
#: src/keycode.cpp:239
msgid "Left Menu"
msgstr ""
#: src/keycode.cpp:239
msgid "Right Control"
msgstr ""
#: src/keycode.cpp:239
msgid "Right Menu"
msgstr ""
#: src/keycode.cpp:241
msgid "Comma"
msgstr ""
#: src/keycode.cpp:241
msgid "Minus"
msgstr ""
#: src/keycode.cpp:241
msgid "Period"
msgstr ""
#: src/keycode.cpp:241
msgid "Plus"
msgstr ""
#: src/keycode.cpp:245
msgid "Attn"
msgstr ""
#: src/keycode.cpp:245
msgid "CrSel"
msgstr ""
#: src/keycode.cpp:246
msgid "Erase OEF"
msgstr ""
#: src/keycode.cpp:246
msgid "ExSel"
msgstr ""
#: src/keycode.cpp:246
msgid "OEM Clear"
msgstr ""
#: src/keycode.cpp:246
msgid "PA1"
msgstr ""
#: src/keycode.cpp:246
msgid "Zoom"
msgstr ""
#: src/main.cpp:1379
msgid "Main Menu"
msgstr ""
#: src/main.cpp:1601
msgid "Failed to initialize world"
msgstr ""
#: src/main.cpp:1613
msgid "No world selected and no address provided. Nothing to do."
msgstr ""
#: src/main.cpp:1621
msgid "Could not find or load game \""
msgstr ""
#: src/main.cpp:1635
msgid "Invalid gamespec."
msgstr ""
#: src/main.cpp:1675
msgid "Connection error (timed out?)"
msgstr ""
#: src/main.cpp:1686
msgid ""
"\n"
"Check debug.txt for details."
msgstr ""

View File

@@ -1,10 +1,6 @@
project(minetest)
cmake_minimum_required( VERSION 2.6 )
if(RUN_IN_PLACE)
add_definitions ( -DRUN_IN_PLACE )
endif(RUN_IN_PLACE)
# Set some random things default to not being visible in the GUI
mark_as_advanced(EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH)
mark_as_advanced(JTHREAD_INCLUDE_DIR JTHREAD_LIBRARY)
@@ -139,13 +135,15 @@ else()
#set(CLIENT_PLATFORM_LIBS -lXxf86vm)
# This way Xxf86vm is found on OpenBSD too
find_library(XXF86VM_LIBRARY Xxf86vm)
mark_as_advanced(XXF86VM_LIBRARY)
set(CLIENT_PLATFORM_LIBS ${CLIENT_PLATFORM_LIBS} ${XXF86VM_LIBRARY})
endif()
find_package(Jthread REQUIRED)
find_package(Sqlite3 REQUIRED)
# TODO: Create proper find script for Lua
# Do not use system-wide installation of Lua, because it'll likely be a
# different version and/or has different build options.
set(LUA_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lua/src")
set(LUA_LIBRARY "lua")
@@ -155,6 +153,8 @@ configure_file(
)
set(common_SRCS
rollback_interface.cpp
rollback.cpp
genericobject.cpp
voxelalgorithms.cpp
sound.cpp
@@ -199,11 +199,16 @@ set(common_SRCS
mapsector.cpp
map.cpp
player.cpp
utility.cpp
test.cpp
sha1.cpp
base64.cpp
ban.cpp
util/serialize.cpp
util/directiontables.cpp
util/numeric.cpp
util/pointedthing.cpp
util/string.cpp
util/timetaker.cpp
)
# This gives us the icon
@@ -246,7 +251,7 @@ set(minetest_SRCS
guiKeyChangeMenu.cpp
guiMessageMenu.cpp
guiTextInputMenu.cpp
guiInventoryMenu.cpp
guiFormSpecMenu.cpp
guiPauseMenu.cpp
guiPasswordChange.cpp
guiDeathScreen.cpp

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef ACTIVEOBJECT_HEADER
#define ACTIVEOBJECT_HEADER
#include "irrlichttypes.h"
#include "irrlichttypes_bloated.h"
#include <string>
#define ACTIVEOBJECT_TYPE_INVALID 0

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string>
#include <jthread.h>
#include <jmutex.h>
#include "common_irrlicht.h"
#include "exceptions.h"
class BanManager

View File

@@ -40,7 +40,7 @@ static inline bool is_base64(unsigned char c) {
bool base64_is_valid(std::string const& s)
{
for(int i=0; i<s.size(); i++)
for(size_t i=0; i<s.size(); i++)
if(!is_base64(s[i])) return false;
return true;
}

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -33,6 +33,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h"
#include "sound.h"
#include "event.h"
#include "util/numeric.h"
#include "util/mathconstants.h"
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
IGameDef *gamedef):
@@ -212,8 +214,22 @@ void Camera::step(f32 dtime)
void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
f32 tool_reload_ratio)
{
// Get player position
// Smooth the movement when walking up stairs
v3f old_player_position = m_playernode->getPosition();
v3f player_position = player->getPosition();
//if(player->touching_ground && player_position.Y > old_player_position.Y)
if(player->touching_ground &&
player_position.Y > old_player_position.Y)
{
f32 oldy = old_player_position.Y;
f32 newy = player_position.Y;
f32 t = exp(-23*frametime);
player_position.Y = oldy * t + newy * (1-t);
}
// Set player node transformation
m_playernode->setPosition(player->getPosition());
m_playernode->setPosition(player_position);
m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0));
m_playernode->updateAbsolutePosition();
@@ -234,17 +250,17 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
#if 1
f32 bobknob = 1.2;
f32 bobtmp = sin(pow(bobfrac, bobknob) * PI);
//f32 bobtmp2 = cos(pow(bobfrac, bobknob) * PI);
f32 bobtmp = sin(pow(bobfrac, bobknob) * M_PI);
//f32 bobtmp2 = cos(pow(bobfrac, bobknob) * M_PI);
v3f bobvec = v3f(
0.3 * bobdir * sin(bobfrac * PI),
0.3 * bobdir * sin(bobfrac * M_PI),
-0.28 * bobtmp * bobtmp,
0.);
//rel_cam_pos += 0.2 * bobvec;
//rel_cam_target += 0.03 * bobvec;
//rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * PI);
//rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * M_PI);
float f = 1.0;
f *= g_settings->getFloat("view_bobbing_amount");
rel_cam_pos += bobvec * f;
@@ -253,10 +269,10 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
rel_cam_target.Z -= 0.005 * bobvec.Z * f;
//rel_cam_target.X -= 0.005 * bobvec.X * f;
//rel_cam_target.Y -= 0.005 * bobvec.Y * f;
rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * PI * f);
rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * M_PI * f);
#else
f32 angle_deg = 1 * bobdir * sin(bobfrac * PI);
f32 angle_rad = angle_deg * PI / 180;
f32 angle_deg = 1 * bobdir * sin(bobfrac * M_PI);
f32 angle_rad = angle_deg * M_PI / 180;
f32 r = 0.05;
v3f off = v3f(
r * sin(angle_rad),
@@ -289,7 +305,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
// FOV and aspect ratio
m_aspect = (f32)screensize.X / (f32) screensize.Y;
m_fov_y = fov_degrees * PI / 180.0;
m_fov_y = fov_degrees * M_PI / 180.0;
// Increase vertical FOV on lower aspect ratios (<16:10)
m_fov_y *= MYMAX(1.0, MYMIN(1.4, sqrt(16./10. / m_aspect)));
// WTF is this? It can't be right
@@ -320,22 +336,22 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
if (m_digging_button != -1)
{
f32 digfrac = m_digging_anim;
wield_position.X -= 30 * sin(pow(digfrac, 0.8f) * PI);
wield_position.Y += 15 * sin(digfrac * 2 * PI);
wield_position.X -= 30 * sin(pow(digfrac, 0.8f) * M_PI);
wield_position.Y += 15 * sin(digfrac * 2 * M_PI);
wield_position.Z += 5 * digfrac;
// Euler angles are PURE EVIL, so why not use quaternions?
core::quaternion quat_begin(wield_rotation * core::DEGTORAD);
core::quaternion quat_end(v3f(90, -10, -130) * core::DEGTORAD);
core::quaternion quat_slerp;
quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * PI));
quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * M_PI));
quat_slerp.toEuler(wield_rotation);
wield_rotation *= core::RADTODEG;
}
else {
f32 bobfrac = my_modf(m_view_bobbing_anim);
wield_position.X -= sin(bobfrac*PI*2.0) * 3.0;
wield_position.Y += sin(my_modf(bobfrac*2.0)*PI) * 3.0;
wield_position.X -= sin(bobfrac*M_PI*2.0) * 3.0;
wield_position.Y += sin(my_modf(bobfrac*2.0)*M_PI) * 3.0;
}
m_wieldnode->setPosition(wield_position);
m_wieldnode->setRotation(wield_rotation);
@@ -538,7 +554,7 @@ void Camera::drawWieldedTool()
// Draw the wielded node (in a separate scene manager)
scene::ICameraSceneNode* cam = m_wieldmgr->getActiveCamera();
cam->setAspectRatio(m_cameranode->getAspectRatio());
cam->setFOV(72.0*PI/180.0);
cam->setFOV(72.0*M_PI/180.0);
cam->setNearValue(0.1);
cam->setFarValue(100);
m_wieldmgr->drawAll();

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,11 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CAMERA_HEADER
#define CAMERA_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "inventory.h"
#include "mesh.h"
#include "tile.h"
#include "utility.h"
#include "util/numeric.h"
#include <ICameraSceneNode.h>
class LocalPlayer;

View File

@@ -3,26 +3,27 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "chat.h"
#include "debug.h"
#include "utility.h"
#include <cassert>
#include <cctype>
#include <sstream>
#include "util/string.h"
#include "util/numeric.h"
ChatBuffer::ChatBuffer(u32 scrollback):
m_scrollback(scrollback),

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CHAT_HEADER
#define CHAT_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_bloated.h"
#include <string>
// Chat console related classes, only used by the client

View File

@@ -3,22 +3,21 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "client.h"
#include "utility.h"
#include <iostream>
#include "clientserver.h"
#include "jmutexautolock.h"
@@ -40,7 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientmap.h"
#include "filecache.h"
#include "sound.h"
#include "utility_string.h"
#include "util/string.h"
#include "hex.h"
static std::string getMediaCacheDir()
@@ -305,6 +304,15 @@ Client::~Client()
sleep_ms(100);
delete m_inventory_from_server;
// Delete detached inventories
{
for(std::map<std::string, Inventory*>::iterator
i = m_detached_inventories.begin();
i != m_detached_inventories.end(); i++){
delete i->second;
}
}
}
void Client::connect(Address address)
@@ -1689,6 +1697,34 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
}
infostream<<std::endl;
}
else if(command == TOCLIENT_INVENTORY_FORMSPEC)
{
std::string datastring((char*)&data[2], datasize-2);
std::istringstream is(datastring, std::ios_base::binary);
// Store formspec in LocalPlayer
Player *player = m_env.getLocalPlayer();
assert(player != NULL);
player->inventory_formspec = deSerializeLongString(is);
}
else if(command == TOCLIENT_DETACHED_INVENTORY)
{
std::string datastring((char*)&data[2], datasize-2);
std::istringstream is(datastring, std::ios_base::binary);
std::string name = deSerializeString(is);
infostream<<"Client: Detached inventory update: \""<<name<<"\""<<std::endl;
Inventory *inv = NULL;
if(m_detached_inventories.count(name) > 0)
inv = m_detached_inventories[name];
else{
inv = new Inventory(m_itemdef);
m_detached_inventories[name] = inv;
}
inv->deSerialize(is);
}
else
{
infostream<<"Client: Ignoring unknown command "
@@ -1764,6 +1800,29 @@ void Client::sendNodemetaFields(v3s16 p, const std::string &formname,
Send(0, data, true);
}
void Client::sendInventoryFields(const std::string &formname,
const std::map<std::string, std::string> &fields)
{
std::ostringstream os(std::ios_base::binary);
writeU16(os, TOSERVER_INVENTORY_FIELDS);
os<<serializeString(formname);
writeU16(os, fields.size());
for(std::map<std::string, std::string>::const_iterator
i = fields.begin(); i != fields.end(); i++){
const std::string &name = i->first;
const std::string &value = i->second;
os<<serializeString(name);
os<<serializeLongString(value);
}
// Make data buffer
std::string s = os.str();
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
// Send as reliable
Send(0, data, true);
}
void Client::sendInventoryAction(InventoryAction *a)
{
std::ostringstream os(std::ios_base::binary);
@@ -2058,6 +2117,13 @@ Inventory* Client::getInventory(const InventoryLocation &loc)
return meta->getInventory();
}
break;
case InventoryLocation::DETACHED:
{
if(m_detached_inventories.count(loc.name) == 0)
return NULL;
return m_detached_inventories[loc.name];
}
break;
default:
assert(0);
}

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -22,18 +22,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "connection.h"
#include "environment.h"
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "jmutex.h"
#include <ostream>
#include <set>
#include <vector>
#include "clientobject.h"
#include "utility.h" // For IntervalLimiter
#include "gamedef.h"
#include "inventorymanager.h"
#include "filesys.h"
#include "filecache.h"
#include "localplayer.h"
#include "util/pointedthing.h"
struct MeshMakeData;
class MapBlockMesh;
@@ -212,6 +212,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
void sendNodemetaFields(v3s16 p, const std::string &formname,
const std::map<std::string, std::string> &fields);
void sendInventoryFields(const std::string &formname,
const std::map<std::string, std::string> &fields);
void sendInventoryAction(InventoryAction *a);
void sendChatMessage(const std::wstring &message);
void sendChangePassword(const std::wstring oldpassword,
@@ -391,6 +393,10 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
// Privileges
std::set<std::string> m_privileges;
// Detached inventories
// key = name
std::map<std::string, Inventory*> m_detached_inventories;
};
#endif // !CLIENT_HEADER

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock.h"
#include "profiler.h"
#include "settings.h"
#include "util/mathconstants.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -46,7 +47,7 @@ ClientMap::ClientMap(
m_control(control),
m_camera_position(0,0,0),
m_camera_direction(0,0,1),
m_camera_fov(PI)
m_camera_fov(M_PI)
{
m_camera_mutex.Init();
assert(m_camera_mutex.IsInitialized());

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENTMAP_HEADER
#define CLIENTMAP_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "map.h"
struct MapDrawControl

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENTOBJECT_HEADER
#define CLIENTOBJECT_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "activeobject.h"
/*

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENTSERVER_HEADER
#define CLIENTSERVER_HEADER
#include "utility.h"
#include "util/serialize.h"
/*
changes by PROTOCOL_VERSION:
@@ -54,9 +54,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
PROTOCOL_VERSION 10:
TOCLIENT_PRIVILEGES
Version raised to force 'fly' and 'fast' privileges into effect.
Node metadata change (came in later; somewhat incompatible)
PROTOCOL_VERSION 11:
TileDef in ContentFeatures
Nodebox drawtype
(some dev snapshot)
TOCLIENT_INVENTORY_FORMSPEC
(0.4.0, 0.4.1)
PROTOCOL_VERSION 12:
TOSERVER_INVENTORY_FIELDS
16-bit node ids
TOCLIENT_DETACHED_INVENTORY
*/
#define PROTOCOL_VERSION 10
#define PROTOCOL_VERSION 12
#define PROTOCOL_ID 0x4f457403
@@ -304,6 +315,21 @@ enum ToClientCommand
u16 len
u8[len] privilege
*/
TOCLIENT_INVENTORY_FORMSPEC = 0x42,
/*
u16 command
u32 len
u8[len] formspec
*/
TOCLIENT_DETACHED_INVENTORY = 0x43,
/*
[0] u16 command
u16 len
u8[len] name
[2] serialized inventory
*/
};
enum ToServerCommand
@@ -498,6 +524,19 @@ enum ToServerCommand
u8[len] field value
*/
TOSERVER_INVENTORY_FIELDS = 0x3c,
/*
u16 command
u16 len
u8[len] form name (reserved for future use)
u16 number of fields
for each field:
u16 len
u8[len] field name
u32 len
u8[len] field value
*/
TOSERVER_REQUEST_MEDIA = 0x40,
/*
u16 command

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENTSIMPLEOBJECT_HEADER
#define CLIENTSIMPLEOBJECT_HEADER
#include "irrlichttypes.h"
#include "irrlichttypes_bloated.h"
class ClientEnvironment;
class ClientSimpleObject

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -213,8 +213,7 @@ void Clouds::render()
v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f;
video::S3DVertex v[4] =
{
video::S3DVertex v[4] = {
video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1),
video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1),
video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0),
@@ -236,88 +235,88 @@ void Clouds::render()
{
switch(i)
{
case 0: // top
for(int j=0;j<4;j++){
v[j].Normal = v3f(0,1,0);
}
v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
v[2].Pos.X= rx; v[2].Pos.Y= ry; v[2].Pos.Z= rz;
v[3].Pos.X= rx; v[3].Pos.Y= ry, v[3].Pos.Z=-rz;
break;
case 1: // back
if(CONTAINS(xi, zi-1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi-1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_1;
v[j].Normal = v3f(0,0,-1);
}
v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
break;
case 2: //right
if(CONTAINS(xi+1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi+1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_2;
v[j].Normal = v3f(1,0,0);
}
v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
break;
case 3: // front
if(CONTAINS(xi, zi+1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi+1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_1;
v[j].Normal = v3f(0,0,-1);
}
v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
break;
case 4: // left
if(CONTAINS(xi-1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi-1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_2;
v[j].Normal = v3f(-1,0,0);
}
v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
break;
case 5: // bottom
for(int j=0;j<4;j++){
v[j].Color=c_bottom;
v[j].Normal = v3f(0,-1,0);
}
v[0].Pos.X= rx; v[0].Pos.Y=-ry; v[0].Pos.Z= rz;
v[1].Pos.X=-rx; v[1].Pos.Y=-ry; v[1].Pos.Z= rz;
v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
break;
case 0: // top
for(int j=0;j<4;j++){
v[j].Normal.set(0,1,0);
}
v[0].Pos.set(-rx, ry,-rz);
v[1].Pos.set(-rx, ry, rz);
v[2].Pos.set( rx, ry, rz);
v[3].Pos.set( rx, ry,-rz);
break;
case 1: // back
if(CONTAINS(xi, zi-1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi-1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_1;
v[j].Normal.set(0,0,-1);
}
v[0].Pos.set(-rx, ry,-rz);
v[1].Pos.set( rx, ry,-rz);
v[2].Pos.set( rx,-ry,-rz);
v[3].Pos.set(-rx,-ry,-rz);
break;
case 2: //right
if(CONTAINS(xi+1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi+1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_2;
v[j].Normal.set(1,0,0);
}
v[0].Pos.set( rx, ry,-rz);
v[1].Pos.set( rx, ry, rz);
v[2].Pos.set( rx,-ry, rz);
v[3].Pos.set( rx,-ry,-rz);
break;
case 3: // front
if(CONTAINS(xi, zi+1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi+1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_1;
v[j].Normal.set(0,0,-1);
}
v[0].Pos.set( rx, ry, rz);
v[1].Pos.set(-rx, ry, rz);
v[2].Pos.set(-rx,-ry, rz);
v[3].Pos.set( rx,-ry, rz);
break;
case 4: // left
if(CONTAINS(xi-1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi-1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_2;
v[j].Normal.set(-1,0,0);
}
v[0].Pos.set(-rx, ry, rz);
v[1].Pos.set(-rx, ry,-rz);
v[2].Pos.set(-rx,-ry,-rz);
v[3].Pos.set(-rx,-ry, rz);
break;
case 5: // bottom
for(int j=0;j<4;j++){
v[j].Color = c_bottom;
v[j].Normal.set(0,-1,0);
}
v[0].Pos.set( rx,-ry, rz);
v[1].Pos.set(-rx,-ry, rz);
v[2].Pos.set(-rx,-ry,-rz);
v[3].Pos.set( rx,-ry,-rz);
break;
}
v3f pos = v3f(p0.X,m_cloud_y,p0.Y);
v3f pos(p0.X, m_cloud_y, p0.Y);
for(u16 i=0; i<4; i++)
v[i].Pos += pos;

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLOUDS_HEADER
#define CLOUDS_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include <iostream>
class Clouds : public scene::ISceneNode

View File

@@ -4,16 +4,18 @@
#define CMAKE_CONFIG_H
#define CMAKE_PROJECT_NAME "@PROJECT_NAME@"
#define CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
#define CMAKE_VERSION_STRING "@VERSION_STRING@"
#define CMAKE_RUN_IN_PLACE @RUN_IN_PLACE@
#define CMAKE_USE_GETTEXT @USE_GETTEXT@
#define CMAKE_USE_SOUND @USE_SOUND@
#define CMAKE_STATIC_SHAREDIR "@SHAREDIR@"
#ifdef NDEBUG
#define CMAKE_BUILD_TYPE "Release"
#else
#define CMAKE_BUILD_TYPE "Debug"
#endif
#define CMAKE_USE_GETTEXT @USE_GETTEXT@
#define CMAKE_USE_SOUND @USE_SOUND@
#define CMAKE_BUILD_INFO "VER=@VERSION_STRING@ BUILD_TYPE="CMAKE_BUILD_TYPE" RUN_IN_PLACE=@RUN_IN_PLACE@ USE_GETTEXT=@USE_GETTEXT@ USE_SOUND=@USE_SOUND@ INSTALL_PREFIX=@CMAKE_INSTALL_PREFIX@"
#define CMAKE_BUILD_INFO "VER=@VERSION_STRING@ BUILD_TYPE="CMAKE_BUILD_TYPE" RUN_IN_PLACE=@RUN_IN_PLACE@ USE_GETTEXT=@USE_GETTEXT@ USE_SOUND=@USE_SOUND@ STATIC_SHAREDIR=@SHAREDIR@"
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -22,32 +22,249 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h"
#include "nodedef.h"
#include "gamedef.h"
#include "log.h"
#include <vector>
#include "util/timetaker.h"
#include "main.h" // g_profiler
#include "profiler.h"
// Helper function:
// 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
// The time after which the collision occurs is stored in dtime.
int axisAlignedCollision(
const aabb3f &staticbox, const aabb3f &movingbox,
const v3f &speed, f32 d, f32 &dtime)
{
//TimeTaker tt("axisAlignedCollision");
f32 xsize = (staticbox.MaxEdge.X - staticbox.MinEdge.X);
f32 ysize = (staticbox.MaxEdge.Y - staticbox.MinEdge.Y);
f32 zsize = (staticbox.MaxEdge.Z - staticbox.MinEdge.Z);
aabb3f relbox(
movingbox.MinEdge.X - staticbox.MinEdge.X,
movingbox.MinEdge.Y - staticbox.MinEdge.Y,
movingbox.MinEdge.Z - staticbox.MinEdge.Z,
movingbox.MaxEdge.X - staticbox.MinEdge.X,
movingbox.MaxEdge.Y - staticbox.MinEdge.Y,
movingbox.MaxEdge.Z - staticbox.MinEdge.Z
);
if(speed.X > 0) // Check for collision with X- plane
{
if(relbox.MaxEdge.X <= d)
{
dtime = - relbox.MaxEdge.X / speed.X;
if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
(relbox.MaxEdge.Y + speed.Y * dtime > 0) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MaxEdge.Z + speed.Z * dtime > 0))
return 0;
}
else if(relbox.MinEdge.X > xsize)
{
return -1;
}
}
else if(speed.X < 0) // Check for collision with X+ plane
{
if(relbox.MinEdge.X >= xsize - d)
{
dtime = (xsize - relbox.MinEdge.X) / speed.X;
if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
(relbox.MaxEdge.Y + speed.Y * dtime > 0) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MaxEdge.Z + speed.Z * dtime > 0))
return 0;
}
else if(relbox.MaxEdge.X < 0)
{
return -1;
}
}
// NO else if here
if(speed.Y > 0) // Check for collision with Y- plane
{
if(relbox.MaxEdge.Y <= d)
{
dtime = - relbox.MaxEdge.Y / speed.Y;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
(relbox.MaxEdge.X + speed.X * dtime > 0) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MaxEdge.Z + speed.Z * dtime > 0))
return 1;
}
else if(relbox.MinEdge.Y > ysize)
{
return -1;
}
}
else if(speed.Y < 0) // Check for collision with Y+ plane
{
if(relbox.MinEdge.Y >= ysize - d)
{
dtime = (ysize - relbox.MinEdge.Y) / speed.Y;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
(relbox.MaxEdge.X + speed.X * dtime > 0) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MaxEdge.Z + speed.Z * dtime > 0))
return 1;
}
else if(relbox.MaxEdge.Y < 0)
{
return -1;
}
}
// NO else if here
if(speed.Z > 0) // Check for collision with Z- plane
{
if(relbox.MaxEdge.Z <= d)
{
dtime = - relbox.MaxEdge.Z / speed.Z;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
(relbox.MaxEdge.X + speed.X * dtime > 0) &&
(relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
(relbox.MaxEdge.Y + speed.Y * dtime > 0))
return 2;
}
//else if(relbox.MinEdge.Z > zsize)
//{
// return -1;
//}
}
else if(speed.Z < 0) // Check for collision with Z+ plane
{
if(relbox.MinEdge.Z >= zsize - d)
{
dtime = (zsize - relbox.MinEdge.Z) / speed.Z;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
(relbox.MaxEdge.X + speed.X * dtime > 0) &&
(relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
(relbox.MaxEdge.Y + speed.Y * dtime > 0))
return 2;
}
//else if(relbox.MaxEdge.Z < 0)
//{
// return -1;
//}
}
return -1;
}
// Helper function:
// Checks if moving the movingbox up by the given distance would hit a ceiling.
bool wouldCollideWithCeiling(
const std::vector<aabb3f> &staticboxes,
const aabb3f &movingbox,
f32 y_increase, f32 d)
{
//TimeTaker tt("wouldCollideWithCeiling");
assert(y_increase >= 0);
for(std::vector<aabb3f>::const_iterator
i = staticboxes.begin();
i != staticboxes.end(); i++)
{
const aabb3f& staticbox = *i;
if((movingbox.MaxEdge.Y - d <= staticbox.MinEdge.Y) &&
(movingbox.MaxEdge.Y + y_increase > staticbox.MinEdge.Y) &&
(movingbox.MinEdge.X < staticbox.MaxEdge.X) &&
(movingbox.MaxEdge.X > staticbox.MinEdge.X) &&
(movingbox.MinEdge.Z < staticbox.MaxEdge.Z) &&
(movingbox.MaxEdge.Z > staticbox.MinEdge.Z))
return true;
}
return false;
}
collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f)
f32 pos_max_d, const aabb3f &box_0,
f32 stepheight, f32 dtime,
v3f &pos_f, v3f &speed_f, v3f &accel_f)
{
//TimeTaker tt("collisionMoveSimple");
ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG);
collisionMoveResult result;
// If there is no speed, there are no collisions
/*
Calculate new velocity
*/
speed_f += accel_f * dtime;
// If there is no speed, there are no collisions
if(speed_f.getLength() == 0)
return result;
v3f oldpos_f = pos_f;
v3s16 oldpos_i = floatToInt(oldpos_f, BS);
/*
Calculate new position
Collect node boxes in movement range
*/
pos_f += speed_f * dtime;
std::vector<aabb3f> cboxes;
std::vector<bool> is_unloaded;
std::vector<bool> is_step_up;
{
//TimeTaker tt2("collisionMoveSimple collect boxes");
ScopeProfiler sp(g_profiler, "collisionMoveSimple collect boxes avg", SPT_AVG);
v3s16 oldpos_i = floatToInt(pos_f, BS);
v3s16 newpos_i = floatToInt(pos_f + speed_f * dtime, BS);
s16 min_x = MYMIN(oldpos_i.X, newpos_i.X) + (box_0.MinEdge.X / BS) - 1;
s16 min_y = MYMIN(oldpos_i.Y, newpos_i.Y) + (box_0.MinEdge.Y / BS) - 1;
s16 min_z = MYMIN(oldpos_i.Z, newpos_i.Z) + (box_0.MinEdge.Z / BS) - 1;
s16 max_x = MYMAX(oldpos_i.X, newpos_i.X) + (box_0.MaxEdge.X / BS) + 1;
s16 max_y = MYMAX(oldpos_i.Y, newpos_i.Y) + (box_0.MaxEdge.Y / BS) + 1;
s16 max_z = MYMAX(oldpos_i.Z, newpos_i.Z) + (box_0.MaxEdge.Z / BS) + 1;
for(s16 x = min_x; x <= max_x; x++)
for(s16 y = min_y; y <= max_y; y++)
for(s16 z = min_z; z <= max_z; z++)
{
try{
// Object collides into walkable nodes
MapNode n = map->getNode(v3s16(x,y,z));
if(gamedef->getNodeDefManager()->get(n).walkable == false)
continue;
std::vector<aabb3f> nodeboxes = n.getNodeBoxes(gamedef->ndef());
for(std::vector<aabb3f>::iterator
i = nodeboxes.begin();
i != nodeboxes.end(); i++)
{
aabb3f box = *i;
box.MinEdge += v3f(x, y, z)*BS;
box.MaxEdge += v3f(x, y, z)*BS;
cboxes.push_back(box);
is_unloaded.push_back(false);
is_step_up.push_back(false);
}
}
catch(InvalidPositionException &e)
{
// Collide with unloaded nodes
aabb3f box = getNodeBox(v3s16(x,y,z), BS);
cboxes.push_back(box);
is_unloaded.push_back(true);
is_step_up.push_back(false);
}
}
} // tt2
assert(cboxes.size() == is_unloaded.size());
assert(cboxes.size() == is_step_up.size());
/*
Collision detection
*/
// position in nodes
v3s16 pos_i = floatToInt(pos_f, BS);
/*
Collision uncertainty radius
Make it a bit larger than the maximum distance of movement
@@ -58,49 +275,129 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
// This should always apply, otherwise there are glitches
assert(d > pos_max_d);
/*
Calculate collision box
*/
core::aabbox3d<f32> box = box_0;
box.MaxEdge += pos_f;
box.MinEdge += pos_f;
core::aabbox3d<f32> oldbox = box_0;
oldbox.MaxEdge += oldpos_f;
oldbox.MinEdge += oldpos_f;
/*
If the object lies on a walkable node, this is set to true.
*/
result.touching_ground = false;
/*
Go through every node around the object
*/
s16 min_x = (box_0.MinEdge.X / BS) - 2;
s16 min_y = (box_0.MinEdge.Y / BS) - 2;
s16 min_z = (box_0.MinEdge.Z / BS) - 2;
s16 max_x = (box_0.MaxEdge.X / BS) + 1;
s16 max_y = (box_0.MaxEdge.Y / BS) + 1;
s16 max_z = (box_0.MaxEdge.Z / BS) + 1;
for(s16 y = oldpos_i.Y + min_y; y <= oldpos_i.Y + max_y; y++)
for(s16 z = oldpos_i.Z + min_z; z <= oldpos_i.Z + max_z; z++)
for(s16 x = oldpos_i.X + min_x; x <= oldpos_i.X + max_x; x++)
int loopcount = 0;
while(dtime > BS*1e-10)
{
try{
// Object collides into walkable nodes
MapNode n = map->getNode(v3s16(x,y,z));
if(gamedef->getNodeDefManager()->get(n).walkable == false)
continue;
}
catch(InvalidPositionException &e)
//TimeTaker tt3("collisionMoveSimple dtime loop");
ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG);
// Avoid infinite loop
loopcount++;
if(loopcount >= 100)
{
// Doing nothing here will block the object from
// walking over map borders
infostream<<"collisionMoveSimple: WARNING: Loop count exceeded, aborting to avoid infiniite loop"<<std::endl;
dtime = 0;
break;
}
core::aabbox3d<f32> nodebox = getNodeBox(v3s16(x,y,z), BS);
aabb3f movingbox = box_0;
movingbox.MinEdge += pos_f;
movingbox.MaxEdge += pos_f;
int nearest_collided = -1;
f32 nearest_dtime = dtime;
u32 nearest_boxindex = -1;
/*
Go through every nodebox, find nearest collision
*/
for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
{
// Ignore if already stepped up this nodebox.
if(is_step_up[boxindex])
continue;
// Find nearest collision of the two boxes (raytracing-like)
f32 dtime_tmp;
int collided = axisAlignedCollision(
cboxes[boxindex], movingbox, speed_f, d, dtime_tmp);
if(collided == -1 || dtime_tmp >= nearest_dtime)
continue;
nearest_dtime = dtime_tmp;
nearest_collided = collided;
nearest_boxindex = boxindex;
}
if(nearest_collided == -1)
{
// No collision with any collision box.
pos_f += speed_f * dtime;
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
}
else
{
// Otherwise, a collision occurred.
const aabb3f& cbox = cboxes[nearest_boxindex];
// Check for stairs.
bool step_up = (nearest_collided != 1) && // must not be Y direction
(movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
(!wouldCollideWithCeiling(cboxes, movingbox,
cbox.MaxEdge.Y - movingbox.MinEdge.Y,
d));
// Move to the point of collision and reduce dtime by nearest_dtime
if(nearest_dtime < 0)
{
// Handle negative nearest_dtime (can be caused by the d allowance)
if(!step_up)
{
if(nearest_collided == 0)
pos_f.X += speed_f.X * nearest_dtime;
if(nearest_collided == 1)
pos_f.Y += speed_f.Y * nearest_dtime;
if(nearest_collided == 2)
pos_f.Z += speed_f.Z * nearest_dtime;
}
}
else
{
pos_f += speed_f * nearest_dtime;
dtime -= nearest_dtime;
}
// Set the speed component that caused the collision to zero
if(step_up)
{
// Special case: Handle stairs
is_step_up[nearest_boxindex] = true;
}
else if(nearest_collided == 0) // X
{
speed_f.X = 0;
result.collides = true;
result.collides_xz = true;
}
else if(nearest_collided == 1) // Y
{
speed_f.Y = 0;
result.collides = true;
}
else if(nearest_collided == 2) // Z
{
speed_f.Z = 0;
result.collides = true;
result.collides_xz = true;
}
}
}
/*
Final touches: Check if standing on ground, step up stairs.
*/
aabb3f box = box_0;
box.MinEdge += pos_f;
box.MaxEdge += pos_f;
for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
{
const aabb3f& cbox = cboxes[boxindex];
/*
See if the object is touching ground.
@@ -111,112 +408,50 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
Use 0.15*BS so that it is easier to get on a node.
*/
if(
//fabs(nodebox.MaxEdge.Y-box.MinEdge.Y) < d
fabs(nodebox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS
&& nodebox.MaxEdge.X-d > box.MinEdge.X
&& nodebox.MinEdge.X+d < box.MaxEdge.X
&& nodebox.MaxEdge.Z-d > box.MinEdge.Z
&& nodebox.MinEdge.Z+d < box.MaxEdge.Z
cbox.MaxEdge.X-d > box.MinEdge.X &&
cbox.MinEdge.X+d < box.MaxEdge.X &&
cbox.MaxEdge.Z-d > box.MinEdge.Z &&
cbox.MinEdge.Z+d < box.MaxEdge.Z
){
result.touching_ground = true;
}
// If object doesn't intersect with node, ignore node.
if(box.intersectsWithBox(nodebox) == false)
continue;
/*
Go through every axis
*/
v3f dirs[3] = {
v3f(0,0,1), // back-front
v3f(0,1,0), // top-bottom
v3f(1,0,0), // right-left
};
for(u16 i=0; i<3; i++)
{
/*
Calculate values along the axis
*/
f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[i]);
f32 nodemin = nodebox.MinEdge.dotProduct(dirs[i]);
f32 objectmax = box.MaxEdge.dotProduct(dirs[i]);
f32 objectmin = box.MinEdge.dotProduct(dirs[i]);
f32 objectmax_old = oldbox.MaxEdge.dotProduct(dirs[i]);
f32 objectmin_old = oldbox.MinEdge.dotProduct(dirs[i]);
/*
Check collision for the axis.
Collision happens when object is going through a surface.
*/
bool negative_axis_collides =
(nodemax > objectmin && nodemax <= objectmin_old + d
&& speed_f.dotProduct(dirs[i]) < 0);
bool positive_axis_collides =
(nodemin < objectmax && nodemin >= objectmax_old - d
&& speed_f.dotProduct(dirs[i]) > 0);
bool main_axis_collides =
negative_axis_collides || positive_axis_collides;
/*
Check overlap of object and node in other axes
*/
bool other_axes_overlap = true;
for(u16 j=0; j<3; j++)
if(is_step_up[boxindex])
{
if(j == i)
continue;
f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[j]);
f32 nodemin = nodebox.MinEdge.dotProduct(dirs[j]);
f32 objectmax = box.MaxEdge.dotProduct(dirs[j]);
f32 objectmin = box.MinEdge.dotProduct(dirs[j]);
if(!(nodemax - d > objectmin && nodemin + d < objectmax))
{
other_axes_overlap = false;
break;
}
pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
box = box_0;
box.MinEdge += pos_f;
box.MaxEdge += pos_f;
}
/*
If this is a collision, revert the pos_f in the main
direction.
*/
if(other_axes_overlap && main_axis_collides)
if(fabs(cbox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS)
{
speed_f -= speed_f.dotProduct(dirs[i]) * dirs[i];
pos_f -= pos_f.dotProduct(dirs[i]) * dirs[i];
pos_f += oldpos_f.dotProduct(dirs[i]) * dirs[i];
result.collides = true;
result.touching_ground = true;
if(is_unloaded[boxindex])
result.standing_on_unloaded = true;
}
}
} // xyz
}
return result;
}
#if 0
// This doesn't seem to work and isn't used
collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f)
f32 pos_max_d, const aabb3f &box_0,
f32 stepheight, f32 dtime,
v3f &pos_f, v3f &speed_f, v3f &accel_f)
{
collisionMoveResult final_result;
//TimeTaker tt("collisionMovePrecise");
ScopeProfiler sp(g_profiler, "collisionMovePrecise avg", SPT_AVG);
collisionMoveResult final_result;
// If there is no speed, there are no collisions
if(speed_f.getLength() == 0)
return final_result;
// Maximum time increment (for collision detection etc)
// time = distance / speed
f32 dtime_max_increment = pos_max_d / speed_f.getLength();
// Maximum time increment is 10ms or lower
if(dtime_max_increment > 0.01)
dtime_max_increment = 0.01;
// Don't allow overly huge dtime
if(dtime > 2.0)
dtime = 2.0;
f32 dtime_downcount = dtime;
u32 loopcount = 0;
@@ -224,6 +459,16 @@ collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
{
loopcount++;
// Maximum time increment (for collision detection etc)
// time = distance / speed
f32 dtime_max_increment = 1.0;
if(speed_f.getLength() != 0)
dtime_max_increment = pos_max_d / speed_f.getLength();
// Maximum time increment is 10ms or lower
if(dtime_max_increment > 0.01)
dtime_max_increment = 0.01;
f32 dtime_part;
if(dtime_downcount > dtime_max_increment)
{
@@ -242,17 +487,20 @@ collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
}
collisionMoveResult result = collisionMoveSimple(map, gamedef,
pos_max_d, box_0, dtime_part, pos_f, speed_f);
pos_max_d, box_0, stepheight, dtime_part,
pos_f, speed_f, accel_f);
if(result.touching_ground)
final_result.touching_ground = true;
if(result.collides)
final_result.collides = true;
if(result.collides_xz)
final_result.collides_xz = true;
if(result.standing_on_unloaded)
final_result.standing_on_unloaded = true;
}
while(dtime_downcount > 0.001);
return final_result;
}
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef COLLISION_HEADER
#define COLLISION_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_bloated.h"
#include <vector>
class Map;
class IGameDef;
@@ -29,22 +30,47 @@ struct collisionMoveResult
{
bool touching_ground;
bool collides;
bool collides_xz;
bool standing_on_unloaded;
collisionMoveResult():
touching_ground(false),
collides(false)
collides(false),
collides_xz(false),
standing_on_unloaded(false)
{}
};
// Moves using a single iteration; speed should not exceed pos_max_d/dtime
collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f);
f32 pos_max_d, const aabb3f &box_0,
f32 stepheight, f32 dtime,
v3f &pos_f, v3f &speed_f, v3f &accel_f);
#if 0
// This doesn't seem to work and isn't used
// Moves using as many iterations as needed
collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f);
f32 pos_max_d, const aabb3f &box_0,
f32 stepheight, f32 dtime,
v3f &pos_f, v3f &speed_f, v3f &accel_f);
#endif
// Helper function:
// 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
// dtime receives time until first collision, invalid if -1 is returned
int axisAlignedCollision(
const aabb3f &staticbox, const aabb3f &movingbox,
const v3f &speed, f32 d, f32 &dtime);
// Helper function:
// Checks if moving the movingbox up by the given distance would hit a ceiling.
bool wouldCollideWithCeiling(
const std::vector<aabb3f> &staticboxes,
const aabb3f &movingbox,
f32 y_increase, f32 d);
enum CollisionType
{

View File

@@ -8,9 +8,10 @@
#define PROJECT_NAME "Minetest"
#define VERSION_STRING "unknown"
#define BUILD_TYPE "unknown"
#define RUN_IN_PLACE 0
#define USE_GETTEXT 0
#define USE_SOUND 0
#define STATIC_SHAREDIR ""
#define BUILD_INFO "non-cmake"
#ifdef USE_CMAKE_CONFIG_H
@@ -19,12 +20,14 @@
#define PROJECT_NAME CMAKE_PROJECT_NAME
#undef VERSION_STRING
#define VERSION_STRING CMAKE_VERSION_STRING
#undef BUILD_INFO
#define BUILD_INFO CMAKE_BUILD_INFO
#undef RUN_IN_PLACE
#define RUN_IN_PLACE CMAKE_RUN_IN_PLACE
#undef USE_GETTEXT
#define USE_GETTEXT CMAKE_USE_GETTEXT
#undef USE_SOUND
#define USE_SOUND CMAKE_USE_SOUND
#undef STATIC_SHAREDIR
#define STATIC_SHAREDIR CMAKE_STATIC_SHAREDIR
#undef BUILD_INFO
#define BUILD_INFO CMAKE_BUILD_INFO
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -22,10 +22,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serialization.h"
#include "log.h"
#include "porting.h"
#include "util/serialize.h"
#include "util/numeric.h"
#include "util/string.h"
namespace con
{
static u16 readPeerId(u8 *packetdata)
{
return readU16(&packetdata[4]);
}
static u8 readChannel(u8 *packetdata)
{
return readU8(&packetdata[6]);
}
BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
u32 protocol_id, u16 sender_peer_id, u8 channel)
{
@@ -353,9 +365,11 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(BufferedPacket &p, bool reliable)
<<" != sp->reliable="<<sp->reliable
<<std::endl;
// If chunk already exists, cancel
// If chunk already exists, ignore it.
// Sometimes two identical packets may arrive when there is network
// lag and the server re-sends stuff.
if(sp->chunks.find(chunk_num) != NULL)
throw AlreadyExistsException("Chunk already in buffer");
return SharedBuffer<u8>();
// Cut chunk data out of packet
u32 chunkdatasize = p.data.getSize() - headersize;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,14 +20,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CONNECTION_HEADER
#define CONNECTION_HEADER
#include <iostream>
#include <fstream>
#include "debug.h"
#include "common_irrlicht.h"
#include "irrlichttypes_bloated.h"
#include "socket.h"
#include "utility.h"
#include "exceptions.h"
#include "constants.h"
#include "util/pointer.h"
#include "util/container.h"
#include "util/thread.h"
#include <iostream>
#include <fstream>
namespace con
{
@@ -107,15 +108,6 @@ class ProcessedSilentlyException : public BaseException
{}
};
inline u16 readPeerId(u8 *packetdata)
{
return readU16(&packetdata[4]);
}
inline u8 readChannel(u8 *packetdata)
{
return readU8(&packetdata[6]);
}
#define SEQNUM_MAX 65535
inline bool seqnum_higher(u16 higher, u16 lower)
{

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -24,11 +24,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
All kinds of constants.
Cross-platform compatibility crap should go in porting.h.
Some things here are legacy crap.
*/
//#define HAXMODE 0
#define DEBUGFILE "debug.txt"
/*
Connection
*/
// Define for simulating the quirks of sending through internet.
// Causes the socket class to deliberately drop random packets.
@@ -42,63 +44,50 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// resend_timeout = avg_rtt * this
#define RESEND_TIMEOUT_FACTOR 4
#define PI 3.14159
// The absolute working limit is (2^15 - viewing_range).
// I really don't want to make every algorithm to check if it's
// going near the limit or not, so this is lower.
#define MAP_GENERATION_LIMIT (31000)
// Size of node in rendering units
#define BS (10.0)
#define MAP_BLOCKSIZE 16
/*
This makes mesh updates too slow, as many meshes are updated during
the main loop (related to TempMods and day/night)
Server
*/
//#define MAP_BLOCKSIZE 32
// Sectors are split to SECTOR_HEIGHTMAP_SPLIT^2 heightmaps
#define SECTOR_HEIGHTMAP_SPLIT (MAP_BLOCKSIZE/8)
// Time after building, during which the following limit
// is in use
//#define FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING 2.0
// This many blocks are sent when player is building
#define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 0
// Override for the previous one when distance of block
// is very low
// Override for the previous one when distance of block is very low
#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1
/*
Map-related things
*/
// The absolute working limit is (2^15 - viewing_range).
// I really don't want to make every algorithm to check if it's going near
// the limit or not, so this is lower.
#define MAP_GENERATION_LIMIT (31000)
// Size of node in floating-point units
// The original idea behind this is to disallow plain casts between
// floating-point and integer positions, which potentially give wrong
// results. (negative coordinates, values between nodes, ...)
// Use floatToInt(p, BS) and intToFloat(p, BS).
#define BS (10.0)
// Dimension of a MapBlock
#define MAP_BLOCKSIZE 16
// This makes mesh updates too slow, as many meshes are updated during
// the main loop (related to TempMods and day/night)
//#define MAP_BLOCKSIZE 32
/*
Old stuff that shouldn't be hardcoded
*/
// Size of player's main inventory
#define PLAYER_INVENTORY_SIZE (8*4)
#define SIGN_TEXT_MAX_LENGTH 50
// Whether to catch all std::exceptions.
// Assert will be called on such an event.
// In debug mode, leave these for the debugger and don't catch them.
#ifdef NDEBUG
#define CATCH_UNHANDLED_EXCEPTIONS 1
#else
#define CATCH_UNHANDLED_EXCEPTIONS 0
#endif
/*
Collecting active blocks is stopped after object data
size reaches this
*/
#define MAX_OBJECTDATA_SIZE 450
/*
This is good to be a bit different than 0 so that water level
is not between two MapBlocks
This is good to be a bit different than 0 so that water level is not
between two MapBlocks
*/
#define WATER_LEVEL 1
// Length of cracking animation in count of images
#define CRACK_ANIMATION_LENGTH 5
// Maximum hit points of a player
#define PLAYER_MAX_HP 20

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "mapblock.h" // For getNodeBlockPos
#include "mapgen.h" // For mapgen::make_tree
#include "map.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -30,13 +30,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientobject.h"
#include "content_object.h"
#include "mesh.h"
#include "utility.h" // For IntervalLimiter
#include "itemdef.h"
#include "tool.h"
#include "content_cso.h"
#include "sound.h"
#include "nodedef.h"
#include "localplayer.h"
#include "util/numeric.h" // For IntervalLimiter
#include "util/serialize.h"
#include "util/mathconstants.h"
#include "map.h"
class Settings;
struct ToolCapabilities;
@@ -879,22 +883,24 @@ class GenericCAO : public ClientActiveObject
box.MinEdge *= BS;
box.MaxEdge *= BS;
collisionMoveResult moveresult;
f32 pos_max_d = BS*0.25; // Distance per iteration
f32 pos_max_d = BS*0.125; // Distance per iteration
f32 stepheight = 0;
v3f p_pos = m_position;
v3f p_velocity = m_velocity;
v3f p_acceleration = m_acceleration;
IGameDef *gamedef = env->getGameDef();
moveresult = collisionMovePrecise(&env->getMap(), gamedef,
pos_max_d, box, dtime, p_pos, p_velocity);
moveresult = collisionMoveSimple(&env->getMap(), gamedef,
pos_max_d, box, stepheight, dtime,
p_pos, p_velocity, p_acceleration);
// Apply results
m_position = p_pos;
m_velocity = p_velocity;
m_acceleration = p_acceleration;
bool is_end_position = moveresult.collides;
pos_translator.update(m_position, is_end_position, dtime);
pos_translator.translate(dtime);
updateNodePos();
m_velocity += dtime * m_acceleration;
} else {
m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
m_velocity += dtime * m_acceleration;
@@ -935,7 +941,7 @@ class GenericCAO : public ClientActiveObject
}
}
if(fabs(m_prop.automatic_rotate) > 0.001){
m_yaw += dtime * m_prop.automatic_rotate * 180 / PI;
m_yaw += dtime * m_prop.automatic_rotate * 180 / M_PI;
updateNodePos();
}
}
@@ -961,7 +967,7 @@ class GenericCAO : public ClientActiveObject
else if(cam_to_entity.Y < -0.75)
col += 4;
else{
float mob_dir = atan2(cam_to_entity.Z, cam_to_entity.X) / PI * 180.;
float mob_dir = atan2(cam_to_entity.Z, cam_to_entity.X) / M_PI * 180.;
float dir = mob_dir - m_yaw;
dir = wrapDegrees_180(dir);
//infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "environment.h"
#include "gamedef.h"
#include "log.h"
#include "map.h"
static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill,
float txs, float tys, int col, int row)

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CONTENT_CSO_HEADER
#define CONTENT_CSO_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "clientsimpleobject.h"
ClientSimpleObject* createSmokePuff(scene::ISceneManager *smgr,

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -25,6 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h"
#include "tile.h"
#include "gamedef.h"
#include "util/numeric.h"
#include "util/serialize.h"
#include "util/directiontables.h"
// Create a cuboid.
// collector - the MeshCollector for the resulting polygons
@@ -471,7 +474,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
pa_liquid.x0(), pa_liquid.y0()),
};
// This fixes a strange bug
// To get backface culling right, the vertices need to go
// clockwise around the front of the face. And we happened to
// calculate corner levels in exact reverse order.
s32 corner_resolve[4] = {3,2,1,0};
for(s32 i=0; i<4; i++)
@@ -482,6 +487,52 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
vertices[i].Pos.Y += corner_levels[j];
vertices[i].Pos += intToFloat(p, BS);
}
// Default downwards-flowing texture animation goes from
// -Z towards +Z, thus the direction is +Z.
// Rotate texture to make animation go in flow direction
// Positive if liquid moves towards +Z
int dz = (corner_levels[side_corners[2][0]] +
corner_levels[side_corners[2][1]] <
corner_levels[side_corners[3][0]] +
corner_levels[side_corners[3][1]]);
// Positive if liquid moves towards +X
int dx = (corner_levels[side_corners[0][0]] +
corner_levels[side_corners[0][1]] <
corner_levels[side_corners[1][0]] +
corner_levels[side_corners[1][1]]);
// -X
if(-dx >= abs(dz))
{
v2f t = vertices[0].TCoords;
vertices[0].TCoords = vertices[1].TCoords;
vertices[1].TCoords = vertices[2].TCoords;
vertices[2].TCoords = vertices[3].TCoords;
vertices[3].TCoords = t;
}
// +X
if(dx >= abs(dz))
{
v2f t = vertices[0].TCoords;
vertices[0].TCoords = vertices[3].TCoords;
vertices[3].TCoords = vertices[2].TCoords;
vertices[2].TCoords = vertices[1].TCoords;
vertices[1].TCoords = t;
}
// -Z
if(-dz >= abs(dx))
{
v2f t = vertices[0].TCoords;
vertices[0].TCoords = vertices[3].TCoords;
vertices[3].TCoords = vertices[2].TCoords;
vertices[2].TCoords = vertices[1].TCoords;
vertices[1].TCoords = t;
t = vertices[0].TCoords;
vertices[0].TCoords = vertices[3].TCoords;
vertices[3].TCoords = vertices[2].TCoords;
vertices[2].TCoords = vertices[1].TCoords;
vertices[1].TCoords = t;
}
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
@@ -868,7 +919,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
if(n_plus_z_plus_y.getContent() == thiscontent)
is_rail_z_plus_y[1] = true;
bool is_rail_x_all[] = {false, false};
bool is_rail_z_all[] = {false, false};
is_rail_x_all[0]=is_rail_x[0] || is_rail_x_minus_y[0] || is_rail_x_plus_y[0];
@@ -876,30 +926,69 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
is_rail_z_all[0]=is_rail_z[0] || is_rail_z_minus_y[0] || is_rail_z_plus_y[0];
is_rail_z_all[1]=is_rail_z[1] || is_rail_z_minus_y[1] || is_rail_z_plus_y[1];
bool is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);//is really straight, rails on both sides
int adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
// reasonable default, flat straight unrotated rail
bool is_straight = true;
int adjacencies = 0;
int angle = 0;
u8 tileindex = 0;
if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1]) //is straight because sloped
// check for sloped rail
if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1])
{
adjacencies = 5; //5 means sloped
is_straight = true;
is_straight = true; // sloped is always straight
}
else
{
// is really straight, rails on both sides
is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);
adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
}
// Assign textures
u8 tileindex = 0; // straight
if(adjacencies < 2)
tileindex = 0; // straight
else if(adjacencies == 2)
{
if(is_straight)
tileindex = 0; // straight
else
switch (adjacencies) {
case 1:
if(is_rail_x_all[0] || is_rail_x_all[1])
angle = 90;
break;
case 2:
if(!is_straight)
tileindex = 1; // curved
}
else if(adjacencies == 3)
if(is_rail_x_all[0] && is_rail_x_all[1])
angle = 90;
if(is_rail_z_all[0] && is_rail_z_all[1]){
if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
}
else if(is_rail_x_all[0] && is_rail_z_all[0])
angle = 270;
else if(is_rail_x_all[0] && is_rail_z_all[1])
angle = 180;
else if(is_rail_x_all[1] && is_rail_z_all[1])
angle = 90;
break;
case 3:
// here is where the potential to 'switch' a junction is, but not implemented at present
tileindex = 2; // t-junction
else if(adjacencies == 4)
if(!is_rail_x_all[1])
angle=180;
if(!is_rail_z_all[0])
angle=90;
if(!is_rail_z_all[1])
angle=270;
break;
case 4:
tileindex = 3; // crossing
break;
case 5: //sloped
if(is_rail_z_plus_y[0])
angle = 180;
if(is_rail_x_plus_y[0])
angle = 90;
if(is_rail_x_plus_y[1])
angle = -90;
break;
default:
break;
}
TileSpec tile = getNodeTileN(n, p, tileindex, data);
tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
@@ -928,67 +1017,73 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
ap.x0(), ap.y0()),
};
// Rotate textures
int angle = 0;
if(adjacencies == 1)
{
if(is_rail_x_all[0] || is_rail_x_all[1])
angle = 90;
}
if(adjacencies == 2)
{
if(is_rail_x_all[0] && is_rail_x_all[1])
{
angle = 90;
}
if(is_rail_z_all[0] && is_rail_z_all[1])
{
if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
}
else if(is_rail_x_all[0] && is_rail_z_all[0])
angle = 270;
else if(is_rail_x_all[0] && is_rail_z_all[1])
angle = 180;
else if(is_rail_x_all[1] && is_rail_z_all[1])
angle = 90;
}
if(adjacencies == 3)
{
if(!is_rail_x_all[0])
angle=0;
if(!is_rail_x_all[1])
angle=180;
if(!is_rail_z_all[0])
angle=90;
if(!is_rail_z_all[1])
angle=270;
}
//adjacencies 4: Crossing
if(adjacencies == 5) //sloped
{
if(is_rail_z_plus_y[0])
angle = 180;
if(is_rail_x_plus_y[0])
angle = 90;
if(is_rail_x_plus_y[1])
angle = -90;
}
if(angle != 0) {
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(angle);
}
for(s32 i=0; i<4; i++)
{
if(angle != 0)
vertices[i].Pos.rotateXZBy(angle);
vertices[i].Pos += intToFloat(p, BS);
}
u16 indices[] = {0,1,2,2,3,0};
collector.append(tile, vertices, 4, indices, 6);
break;}
case NDT_NODEBOX:
{
static const v3s16 tile_dirs[6] = {
v3s16(0, 1, 0),
v3s16(0, -1, 0),
v3s16(1, 0, 0),
v3s16(-1, 0, 0),
v3s16(0, 0, 1),
v3s16(0, 0, -1)
};
TileSpec tiles[6];
for(int i = 0; i < 6; i++)
{
// Handles facedir rotation for textures
tiles[i] = getNodeTile(n, p, tile_dirs[i], data);
}
u16 l = getInteriorLight(n, 0, data);
video::SColor c = MapBlock_LightColor(255, l);
v3f pos = intToFloat(p, BS);
std::vector<aabb3f> boxes = n.getNodeBoxes(nodedef);
for(std::vector<aabb3f>::iterator
i = boxes.begin();
i != boxes.end(); i++)
{
aabb3f box = *i;
box.MinEdge += pos;
box.MaxEdge += pos;
// Compute texture coords
f32 tx1 = (i->MinEdge.X/BS)+0.5;
f32 ty1 = (i->MinEdge.Y/BS)+0.5;
f32 tz1 = (i->MinEdge.Z/BS)+0.5;
f32 tx2 = (i->MaxEdge.X/BS)+0.5;
f32 ty2 = (i->MaxEdge.Y/BS)+0.5;
f32 tz2 = (i->MaxEdge.Z/BS)+0.5;
f32 txc[24] = {
// up
tx1, 1-tz2, tx2, 1-tz1,
// down
tx1, tz1, tx2, tz2,
// right
tz1, 1-ty2, tz2, 1-ty1,
// left
1-tz2, 1-ty2, 1-tz1, 1-ty1,
// back
1-tx2, 1-ty2, 1-tx1, 1-ty1,
// front
tx1, 1-ty2, tx2, 1-ty1,
};
makeCuboid(&collector, box, tiles, 6, c, txc);
}
break;}
}
}
}

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,26 +3,25 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "content_mapnode.h"
#include "irrlichttypes.h"
#include "irrlichttypes_bloated.h"
#include "mapnode.h"
#include "nodedef.h"
#include "utility.h"
#include "nameidmapping.h"
#include <map>
@@ -103,23 +102,6 @@ content_t trans_table_19[21][2] = {
{CONTENT_BOOKSHELF, 29},
};
MapNode mapnode_translate_from_internal(MapNode n_from, u8 version)
{
MapNode result = n_from;
if(version <= 19)
{
content_t c_from = n_from.getContent();
for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++)
{
if(trans_table_19[i][0] == c_from)
{
result.setContent(trans_table_19[i][1]);
break;
}
}
}
return result;
}
MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
{
MapNode result = n_from;

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -28,7 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// Backwards compatibility for non-extended content types in v19
extern content_t trans_table_19[21][2];
MapNode mapnode_translate_from_internal(MapNode n_from, u8 version);
MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
// Get legacy node name mapping for loading old blocks

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_nodemeta.h"
#include "inventory.h"
#include "log.h"
#include "utility.h"
#include "util/serialize.h"
#include "util/string.h"
#include "constants.h" // MAP_BLOCKSIZE
#include <sstream>
#define NODEMETA_GENERIC 1
@@ -57,7 +59,7 @@ static bool content_nodemeta_deserialize_legacy_body(
}
else if(id == NODEMETA_SIGN) // SignNodeMetadata
{
meta->setString("text", deSerializeLongString(is));
meta->setString("text", deSerializeString(is));
//meta->setString("infotext","\"${text}\"");
meta->setString("infotext",
std::string("\"") + meta->getString("text") + "\"");
@@ -75,7 +77,7 @@ static bool content_nodemeta_deserialize_legacy_body(
}
assert(inv->getList("main") && !inv->getList("0"));
meta->setString("formspec","invsize[8,9;]"
meta->setString("formspec","size[8,9]"
"list[current_name;main;0,0;8,4;]"
"list[current_player;main;0,5;8,4;]");
return false;
@@ -92,7 +94,7 @@ static bool content_nodemeta_deserialize_legacy_body(
}
assert(inv->getList("main") && !inv->getList("0"));
meta->setString("formspec","invsize[8,9;]"
meta->setString("formspec","size[8,9]"
"list[current_name;main;0,0;8,4;]"
"list[current_player;main;0,5;8,4;]");
return false;
@@ -113,7 +115,7 @@ static bool content_nodemeta_deserialize_legacy_body(
is>>temp;
meta->setString("src_time", ftos((float)temp/10));
meta->setString("formspec","invsize[8,9;]"
meta->setString("formspec","size[8,9]"
"list[current_name;fuel;2,3;1,1;]"
"list[current_name;src;2,1;1,1;]"
"list[current_name;dst;5,1;2,2;]"

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "player.h"
#include "scriptapi.h"
#include "genericobject.h"
#include "util/serialize.h"
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
@@ -141,6 +142,9 @@ TestSAO proto_TestSAO(NULL, v3f(0,0,0));
/*
ItemSAO
DEPRECATED: New dropped items are implemented in Lua; see
builtin/item_entity.lua.
*/
class ItemSAO : public ServerActiveObject
@@ -202,9 +206,12 @@ class ItemSAO : public ServerActiveObject
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
v3f accel_f = v3f(0,0,0);
f32 stepheight = 0;
IGameDef *gamedef = m_env->getGameDef();
moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
pos_max_d, box, dtime, pos_f, m_speed_f);
pos_max_d, box, stepheight, dtime,
pos_f, m_speed_f, accel_f);
if(send_recommended == false)
return;
@@ -285,13 +292,6 @@ class ItemSAO : public ServerActiveObject
ServerActiveObject *puncher,
float time_from_last_punch)
{
// Directly delete item in creative mode
if(g_settings->getBool("creative_mode") == true)
{
m_removed = true;
return 0;
}
// Take item into inventory
ItemStack item = createItemStack();
Inventory *inv = puncher->getInventory();
@@ -448,16 +448,18 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
box.MaxEdge *= BS;
collisionMoveResult moveresult;
f32 pos_max_d = BS*0.25; // Distance per iteration
v3f p_pos = getBasePosition();
f32 stepheight = 0; // Maximum climbable step height
v3f p_pos = m_base_position;
v3f p_velocity = m_velocity;
v3f p_acceleration = m_acceleration;
IGameDef *gamedef = m_env->getGameDef();
moveresult = collisionMovePrecise(&m_env->getMap(), gamedef,
pos_max_d, box, dtime, p_pos, p_velocity);
moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
pos_max_d, box, stepheight, dtime,
p_pos, p_velocity, p_acceleration);
// Apply results
setBasePosition(p_pos);
m_base_position = p_pos;
m_velocity = p_velocity;
m_velocity += dtime * m_acceleration;
m_acceleration = p_acceleration;
} else {
m_base_position += dtime * m_velocity + 0.5 * dtime
* dtime * m_acceleration;
@@ -755,6 +757,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
m_last_good_position(0,0,0),
m_last_good_position_age(0),
m_time_from_last_punch(0),
m_nocheat_dig_pos(32767, 32767, 32767),
m_nocheat_dig_time(0),
m_wield_index(0),
m_position_not_sent(false),
m_armor_groups_sent(false),
@@ -865,8 +869,9 @@ void PlayerSAO::step(float dtime, bool send_recommended)
}
m_time_from_last_punch += dtime;
m_nocheat_dig_time += dtime;
if(m_is_singleplayer)
if(m_is_singleplayer || g_settings->getBool("disable_anticheat"))
{
m_last_good_position = m_player->getPosition();
m_last_good_position_age = 0;
@@ -879,7 +884,8 @@ void PlayerSAO::step(float dtime, bool send_recommended)
NOTE: Actually the server should handle player physics like the
client does and compare player's position to what is calculated
on our side. This is required when eg. players fly due to an
explosion.
explosion. Altough a node-based alternative might be possible
too, and much more lightweight.
*/
float player_max_speed = 0;
@@ -1130,16 +1136,6 @@ void PlayerSAO::disconnected()
}
}
void PlayerSAO::createCreativeInventory()
{
if(m_inventory != &m_player->inventory)
delete m_inventory;
m_inventory = new Inventory(m_player->inventory);
m_inventory->clearContents();
scriptapi_get_creative_inventory(m_env->getLua(), this);
}
std::string PlayerSAO::getPropertyPacket()
{
m_prop.is_visible = (getHP() != 0);

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -163,8 +163,6 @@ class PlayerSAO : public ServerActiveObject
void disconnected();
void createCreativeInventory();
Player* getPlayer()
{
return m_player;
@@ -173,6 +171,9 @@ class PlayerSAO : public ServerActiveObject
{
return m_peer_id;
}
// Cheat prevention
v3f getLastGoodPosition() const
{
return m_last_good_position;
@@ -183,6 +184,26 @@ class PlayerSAO : public ServerActiveObject
m_time_from_last_punch = 0.0;
return r;
}
void noCheatDigStart(v3s16 p)
{
m_nocheat_dig_pos = p;
m_nocheat_dig_time = 0;
}
v3s16 getNoCheatDigPos()
{
return m_nocheat_dig_pos;
}
float getNoCheatDigTime()
{
return m_nocheat_dig_time;
}
void noCheatDigEnd()
{
m_nocheat_dig_pos = v3s16(32767, 32767, 32767);
}
// Other
void updatePrivileges(const std::set<std::string> &privs,
bool is_singleplayer)
{
@@ -196,9 +217,14 @@ class PlayerSAO : public ServerActiveObject
Player *m_player;
u16 m_peer_id;
Inventory *m_inventory;
// Cheat prevention
v3f m_last_good_position;
float m_last_good_position_age;
float m_time_from_last_punch;
v3s16 m_nocheat_dig_pos;
float m_nocheat_dig_time;
int m_wield_index;
bool m_position_not_sent;
ItemGroupList m_armor_groups;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -23,10 +23,40 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h"
#include <sstream>
#include <set>
#include "utility.h"
#include <algorithm>
#include "gamedef.h"
#include "inventory.h"
#include "util/serialize.h"
#include "strfnd.h"
// Check if input matches recipe
// Takes recipe groups into account
static bool inputItemMatchesRecipe(const std::string &inp_name,
const std::string &rec_name, IItemDefManager *idef)
{
// Exact name
if(inp_name == rec_name)
return true;
// Group
if(rec_name.substr(0,6) == "group:" && idef->isKnown(inp_name)){
const struct ItemDefinition &def = idef->get(inp_name);
Strfnd f(rec_name.substr(6));
bool all_groups_match = true;
do{
std::string check_group = f.next(",");
if(itemgroup_get(def.groups, check_group) == 0){
all_groups_match = false;
break;
}
}while(!f.atend());
if(all_groups_match)
return true;
}
// Didn't match
return false;
}
// Deserialize an itemstring then return the name of the item
static std::string craftGetItemName(const std::string &itemstring, IGameDef *gamedef)
@@ -64,6 +94,20 @@ static std::vector<std::string> craftGetItemNames(
return result;
}
// convert a list of item names, to ItemStacks.
static std::vector<ItemStack> craftGetItems(
const std::vector<std::string> &items, IGameDef *gamedef)
{
std::vector<ItemStack> result;
for(std::vector<std::string>::const_iterator
i = items.begin();
i != items.end(); i++)
{
result.push_back(ItemStack(std::string(*i),(u16)1,(u16)0,"",gamedef->getItemDefManager()));
}
return result;
}
// Compute bounding rectangle given a matrix of items
// Returns false if every item is ""
static bool craftGetBounds(const std::vector<std::string> &items, unsigned int width,
@@ -106,6 +150,8 @@ static bool craftGetBounds(const std::vector<std::string> &items, unsigned int w
return success;
}
#if 0
// This became useless when group support was added to shapeless recipes
// Convert a list of item names to a multiset
static std::multiset<std::string> craftMakeMultiset(const std::vector<std::string> &names)
{
@@ -119,6 +165,7 @@ static std::multiset<std::string> craftMakeMultiset(const std::vector<std::strin
}
return set;
}
#endif
// Removes 1 from each item stack
static void craftDecrementInput(CraftInput &input, IGameDef *gamedef)
@@ -260,6 +307,7 @@ std::string CraftOutput::dump() const
/*
CraftReplacements
*/
std::string CraftReplacements::dump() const
{
std::ostringstream os(std::ios::binary);
@@ -276,6 +324,27 @@ std::string CraftReplacements::dump() const
return os.str();
}
void CraftReplacements::serialize(std::ostream &os) const
{
writeU16(os, pairs.size());
for(u32 i=0; i<pairs.size(); i++)
{
os<<serializeString(pairs[i].first);
os<<serializeString(pairs[i].second);
}
}
void CraftReplacements::deSerialize(std::istream &is)
{
pairs.clear();
u32 count = readU16(is);
for(u32 i=0; i<count; i++)
{
std::string first = deSerializeString(is);
std::string second = deSerializeString(is);
pairs.push_back(std::make_pair(first, second));
}
}
/*
CraftDefinition
@@ -381,9 +450,9 @@ bool CraftDefinitionShaped::check(const CraftInput &input, IGameDef *gamedef) co
unsigned int rec_x = rec_min_x + x;
unsigned int rec_y = rec_min_y + y;
if(
inp_names[inp_y * inp_width + inp_x] !=
rec_names[rec_y * rec_width + rec_x]
if(!inputItemMatchesRecipe(
inp_names[inp_y * inp_width + inp_x],
rec_names[rec_y * rec_width + rec_x], gamedef->idef())
){
return false;
}
@@ -397,6 +466,11 @@ CraftOutput CraftDefinitionShaped::getOutput(const CraftInput &input, IGameDef *
return CraftOutput(output, 0);
}
CraftInput CraftDefinitionShaped::getInput(const CraftOutput &output, IGameDef *gamedef) const
{
return CraftInput(CRAFT_METHOD_NORMAL,width,craftGetItems(recipe,gamedef));
}
void CraftDefinitionShaped::decrementInput(CraftInput &input, IGameDef *gamedef) const
{
craftDecrementOrReplaceInput(input, replacements, gamedef);
@@ -418,12 +492,7 @@ void CraftDefinitionShaped::serializeBody(std::ostream &os) const
writeU16(os, recipe.size());
for(u32 i=0; i<recipe.size(); i++)
os<<serializeString(recipe[i]);
writeU16(os, replacements.pairs.size());
for(u32 i=0; i<replacements.pairs.size(); i++)
{
os<<serializeString(replacements.pairs[i].first);
os<<serializeString(replacements.pairs[i].second);
}
replacements.serialize(os);
}
void CraftDefinitionShaped::deSerializeBody(std::istream &is, int version)
@@ -436,14 +505,7 @@ void CraftDefinitionShaped::deSerializeBody(std::istream &is, int version)
u32 count = readU16(is);
for(u32 i=0; i<count; i++)
recipe.push_back(deSerializeString(is));
replacements.pairs.clear();
count = readU16(is);
for(u32 i=0; i<count; i++)
{
std::string first = deSerializeString(is);
std::string second = deSerializeString(is);
replacements.pairs.push_back(std::make_pair(first, second));
}
replacements.deSerialize(is);
}
/*
@@ -459,17 +521,48 @@ bool CraftDefinitionShapeless::check(const CraftInput &input, IGameDef *gamedef)
{
if(input.method != CRAFT_METHOD_NORMAL)
return false;
// Filter empty items out of input
std::vector<std::string> input_filtered;
for(std::vector<ItemStack>::const_iterator
i = input.items.begin();
i != input.items.end(); i++)
{
if(i->name != "")
input_filtered.push_back(i->name);
}
// Get input item multiset
std::vector<std::string> inp_names = craftGetItemNames(input.items, gamedef);
std::multiset<std::string> inp_names_multiset = craftMakeMultiset(inp_names);
// If there is a wrong number of items in input, no match
if(input_filtered.size() != recipe.size()){
/*dstream<<"Number of input items ("<<input_filtered.size()
<<") does not match recipe size ("<<recipe.size()<<") "
<<"of recipe with output="<<output<<std::endl;*/
return false;
}
// Get recipe item multiset
std::vector<std::string> rec_names = craftGetItemNames(recipe, gamedef);
std::multiset<std::string> rec_names_multiset = craftMakeMultiset(rec_names);
// Try with all permutations of the recipe
std::vector<std::string> recipe_copy = recipe;
// Start from the lexicographically first permutation (=sorted)
std::sort(recipe_copy.begin(), recipe_copy.end());
//while(std::prev_permutation(recipe_copy.begin(), recipe_copy.end())){}
do{
// If all items match, the recipe matches
bool all_match = true;
//dstream<<"Testing recipe (output="<<output<<"):";
for(size_t i=0; i<recipe.size(); i++){
//dstream<<" ("<<input_filtered[i]<<" == "<<recipe_copy[i]<<")";
if(!inputItemMatchesRecipe(input_filtered[i], recipe_copy[i],
gamedef->idef())){
all_match = false;
break;
}
}
//dstream<<" -> match="<<all_match<<std::endl;
if(all_match)
return true;
}while(std::next_permutation(recipe_copy.begin(), recipe_copy.end()));
// Recipe is matched when the multisets coincide
return inp_names_multiset == rec_names_multiset;
return false;
}
CraftOutput CraftDefinitionShapeless::getOutput(const CraftInput &input, IGameDef *gamedef) const
@@ -477,6 +570,11 @@ CraftOutput CraftDefinitionShapeless::getOutput(const CraftInput &input, IGameDe
return CraftOutput(output, 0);
}
CraftInput CraftDefinitionShapeless::getInput(const CraftOutput &output, IGameDef *gamedef) const
{
return CraftInput(CRAFT_METHOD_NORMAL,0,craftGetItems(recipe,gamedef));
}
void CraftDefinitionShapeless::decrementInput(CraftInput &input, IGameDef *gamedef) const
{
craftDecrementOrReplaceInput(input, replacements, gamedef);
@@ -497,12 +595,7 @@ void CraftDefinitionShapeless::serializeBody(std::ostream &os) const
writeU16(os, recipe.size());
for(u32 i=0; i<recipe.size(); i++)
os<<serializeString(recipe[i]);
writeU16(os, replacements.pairs.size());
for(u32 i=0; i<replacements.pairs.size(); i++)
{
os<<serializeString(replacements.pairs[i].first);
os<<serializeString(replacements.pairs[i].second);
}
replacements.serialize(os);
}
void CraftDefinitionShapeless::deSerializeBody(std::istream &is, int version)
@@ -514,14 +607,7 @@ void CraftDefinitionShapeless::deSerializeBody(std::istream &is, int version)
u32 count = readU16(is);
for(u32 i=0; i<count; i++)
recipe.push_back(deSerializeString(is));
replacements.pairs.clear();
count = readU16(is);
for(u32 i=0; i<count; i++)
{
std::string first = deSerializeString(is);
std::string second = deSerializeString(is);
replacements.pairs.push_back(std::make_pair(first, second));
}
replacements.deSerialize(is);
}
/*
@@ -607,6 +693,13 @@ CraftOutput CraftDefinitionToolRepair::getOutput(const CraftInput &input, IGameD
return CraftOutput(repaired.getItemString(), 0);
}
CraftInput CraftDefinitionToolRepair::getInput(const CraftOutput &output, IGameDef *gamedef) const
{
std::vector<ItemStack> stack;
stack.push_back(ItemStack());
return CraftInput(CRAFT_METHOD_COOKING,additional_wear,stack);
}
void CraftDefinitionToolRepair::decrementInput(CraftInput &input, IGameDef *gamedef) const
{
craftDecrementInput(input, gamedef);
@@ -645,16 +738,26 @@ bool CraftDefinitionCooking::check(const CraftInput &input, IGameDef *gamedef) c
if(input.method != CRAFT_METHOD_COOKING)
return false;
// Get input item multiset
std::vector<std::string> inp_names = craftGetItemNames(input.items, gamedef);
std::multiset<std::string> inp_names_multiset = craftMakeMultiset(inp_names);
// Filter empty items out of input
std::vector<std::string> input_filtered;
for(std::vector<ItemStack>::const_iterator
i = input.items.begin();
i != input.items.end(); i++)
{
if(i->name != "")
input_filtered.push_back(i->name);
}
// Get recipe item multiset
std::multiset<std::string> rec_names_multiset;
rec_names_multiset.insert(craftGetItemName(recipe, gamedef));
// Recipe is matched when the multisets coincide
return inp_names_multiset == rec_names_multiset;
// If there is a wrong number of items in input, no match
if(input_filtered.size() != 1){
/*dstream<<"Number of input items ("<<input_filtered.size()
<<") does not match recipe size (1) "
<<"of cooking recipe with output="<<output<<std::endl;*/
return false;
}
// Check the single input item
return inputItemMatchesRecipe(input_filtered[0], recipe, gamedef->idef());
}
CraftOutput CraftDefinitionCooking::getOutput(const CraftInput &input, IGameDef *gamedef) const
@@ -662,9 +765,16 @@ CraftOutput CraftDefinitionCooking::getOutput(const CraftInput &input, IGameDef
return CraftOutput(output, cooktime);
}
CraftInput CraftDefinitionCooking::getInput(const CraftOutput &output, IGameDef *gamedef) const
{
std::vector<std::string> rec;
rec.push_back(recipe);
return CraftInput(CRAFT_METHOD_COOKING,cooktime,craftGetItems(rec,gamedef));
}
void CraftDefinitionCooking::decrementInput(CraftInput &input, IGameDef *gamedef) const
{
craftDecrementInput(input, gamedef);
craftDecrementOrReplaceInput(input, replacements, gamedef);
}
std::string CraftDefinitionCooking::dump() const
@@ -672,7 +782,8 @@ std::string CraftDefinitionCooking::dump() const
std::ostringstream os(std::ios::binary);
os<<"(cooking, output=\""<<output
<<"\", recipe=\""<<recipe
<<"\", cooktime="<<cooktime<<")";
<<"\", cooktime="<<cooktime<<")"
<<", replacements="<<replacements.dump()<<")";
return os.str();
}
@@ -681,6 +792,7 @@ void CraftDefinitionCooking::serializeBody(std::ostream &os) const
os<<serializeString(output);
os<<serializeString(recipe);
writeF1000(os, cooktime);
replacements.serialize(os);
}
void CraftDefinitionCooking::deSerializeBody(std::istream &is, int version)
@@ -690,6 +802,7 @@ void CraftDefinitionCooking::deSerializeBody(std::istream &is, int version)
output = deSerializeString(is);
recipe = deSerializeString(is);
cooktime = readF1000(is);
replacements.deSerialize(is);
}
/*
@@ -706,16 +819,26 @@ bool CraftDefinitionFuel::check(const CraftInput &input, IGameDef *gamedef) cons
if(input.method != CRAFT_METHOD_FUEL)
return false;
// Get input item multiset
std::vector<std::string> inp_names = craftGetItemNames(input.items, gamedef);
std::multiset<std::string> inp_names_multiset = craftMakeMultiset(inp_names);
// Filter empty items out of input
std::vector<std::string> input_filtered;
for(std::vector<ItemStack>::const_iterator
i = input.items.begin();
i != input.items.end(); i++)
{
if(i->name != "")
input_filtered.push_back(i->name);
}
// Get recipe item multiset
std::multiset<std::string> rec_names_multiset;
rec_names_multiset.insert(craftGetItemName(recipe, gamedef));
// Recipe is matched when the multisets coincide
return inp_names_multiset == rec_names_multiset;
// If there is a wrong number of items in input, no match
if(input_filtered.size() != 1){
/*dstream<<"Number of input items ("<<input_filtered.size()
<<") does not match recipe size (1) "
<<"of fuel recipe with burntime="<<burntime<<std::endl;*/
return false;
}
// Check the single input item
return inputItemMatchesRecipe(input_filtered[0], recipe, gamedef->idef());
}
CraftOutput CraftDefinitionFuel::getOutput(const CraftInput &input, IGameDef *gamedef) const
@@ -723,16 +846,24 @@ CraftOutput CraftDefinitionFuel::getOutput(const CraftInput &input, IGameDef *ga
return CraftOutput("", burntime);
}
CraftInput CraftDefinitionFuel::getInput(const CraftOutput &output, IGameDef *gamedef) const
{
std::vector<std::string> rec;
rec.push_back(recipe);
return CraftInput(CRAFT_METHOD_COOKING,(int)burntime,craftGetItems(rec,gamedef));
}
void CraftDefinitionFuel::decrementInput(CraftInput &input, IGameDef *gamedef) const
{
craftDecrementInput(input, gamedef);
craftDecrementOrReplaceInput(input, replacements, gamedef);
}
std::string CraftDefinitionFuel::dump() const
{
std::ostringstream os(std::ios::binary);
os<<"(fuel, recipe=\""<<recipe
<<"\", burntime="<<burntime<<")";
<<"\", burntime="<<burntime<<")"
<<", replacements="<<replacements.dump()<<")";
return os.str();
}
@@ -740,6 +871,7 @@ void CraftDefinitionFuel::serializeBody(std::ostream &os) const
{
os<<serializeString(recipe);
writeF1000(os, burntime);
replacements.serialize(os);
}
void CraftDefinitionFuel::deSerializeBody(std::istream &is, int version)
@@ -748,6 +880,7 @@ void CraftDefinitionFuel::deSerializeBody(std::istream &is, int version)
"unsupported CraftDefinitionFuel version");
recipe = deSerializeString(is);
burntime = readF1000(is);
replacements.deSerialize(is);
}
/*
@@ -813,6 +946,47 @@ class CCraftDefManager: public IWritableCraftDefManager
}
return false;
}
virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
IGameDef *gamedef) const
{
CraftOutput tmpout;
tmpout.item = "";
tmpout.time = 0;
// If output item is empty, abort.
if(output.item.empty())
return false;
// Walk crafting definitions from back to front, so that later
// definitions can override earlier ones.
for(std::vector<CraftDefinition*>::const_reverse_iterator
i = m_craft_definitions.rbegin();
i != m_craft_definitions.rend(); i++)
{
CraftDefinition *def = *i;
/*infostream<<"Checking "<<input.dump()<<std::endl
<<" against "<<def->dump()<<std::endl;*/
try {
tmpout = def->getOutput(input, gamedef);
if(tmpout.item.substr(0,output.item.length()) == output.item)
{
// Get output, then decrement input (if requested)
input = def->getInput(output, gamedef);
return true;
}
}
catch(SerializationError &e)
{
errorstream<<"getCraftResult: ERROR: "
<<"Serialization error in recipe "
<<def->dump()<<std::endl;
// then go on with the next craft definition
}
}
return false;
}
virtual std::string dump() const
{
std::ostringstream os(std::ios::binary);

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -106,6 +106,8 @@ struct CraftReplacements
pairs(pairs_)
{}
std::string dump() const;
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);
};
/*
@@ -128,6 +130,8 @@ class CraftDefinition
// Returns the output structure, meaning depends on crafting method
// The implementation can assume that check(input) returns true
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0;
// the inverse of the above
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
// Decreases count of every input item
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const=0;
@@ -162,6 +166,7 @@ class CraftDefinitionShaped: public CraftDefinition
virtual std::string getName() const;
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
virtual std::string dump() const;
@@ -203,6 +208,7 @@ class CraftDefinitionShapeless: public CraftDefinition
virtual std::string getName() const;
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
virtual std::string dump() const;
@@ -240,6 +246,7 @@ class CraftDefinitionToolRepair: public CraftDefinition
virtual std::string getName() const;
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
virtual std::string dump() const;
@@ -270,14 +277,16 @@ class CraftDefinitionCooking: public CraftDefinition
CraftDefinitionCooking(
const std::string &output_,
const std::string &recipe_,
float cooktime_):
output(output_), recipe(recipe_), cooktime(cooktime_)
float cooktime_,
const CraftReplacements &replacements_):
output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_)
{}
virtual ~CraftDefinitionCooking(){}
virtual std::string getName() const;
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
virtual std::string dump() const;
@@ -293,6 +302,8 @@ class CraftDefinitionCooking: public CraftDefinition
std::string recipe;
// Time in seconds
float cooktime;
// Replacement items for decrementInput()
CraftReplacements replacements;
};
/*
@@ -305,14 +316,17 @@ class CraftDefinitionFuel: public CraftDefinition
CraftDefinitionFuel():
recipe(""), burntime()
{}
CraftDefinitionFuel(std::string recipe_, float burntime_):
recipe(recipe_), burntime(burntime_)
CraftDefinitionFuel(std::string recipe_,
float burntime_,
const CraftReplacements &replacements_):
recipe(recipe_), burntime(burntime_), replacements(replacements_)
{}
virtual ~CraftDefinitionFuel(){}
virtual std::string getName() const;
virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
virtual std::string dump() const;
@@ -326,6 +340,8 @@ class CraftDefinitionFuel: public CraftDefinition
std::string recipe;
// Time in seconds
float burntime;
// Replacement items for decrementInput()
CraftReplacements replacements;
};
/*
@@ -340,6 +356,8 @@ class ICraftDefManager
// The main crafting function
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
bool decrementInput, IGameDef *gamedef) const=0;
virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
IGameDef *gamedef) const=0;
// Print crafting recipes for debugging
virtual std::string dump() const=0;
@@ -356,6 +374,8 @@ class IWritableCraftDefManager : public ICraftDefManager
// The main crafting function
virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
bool decrementInput, IGameDef *gamedef) const=0;
virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
IGameDef *gamedef) const=0;
// Print crafting recipes for debugging
virtual std::string dump() const=0;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h"
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
/*
Debug output

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -24,10 +24,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <jmutex.h>
#include <jmutexautolock.h>
#include <iostream>
#include "common_irrlicht.h"
#include "irrlichttypes.h"
#include <irrMap.h>
#include "threads.h"
#include "gettime.h"
#include "constants.h"
#include "exceptions.h"
#ifdef _WIN32
@@ -39,6 +39,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#else
#endif
// Whether to catch all std::exceptions.
// Assert will be called on such an event.
// In debug mode, leave these for the debugger and don't catch them.
#ifdef NDEBUG
#define CATCH_UNHANDLED_EXCEPTIONS 1
#else
#define CATCH_UNHANDLED_EXCEPTIONS 0
#endif
/*
Debug output
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -25,7 +25,6 @@ void set_default_settings(Settings *settings)
settings->setDefault("port", "");
settings->setDefault("name", "");
settings->setDefault("footprints", "false");
// Client stuff
@@ -104,6 +103,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("console_alpha", "200");
settings->setDefault("enable_sound", "true");
settings->setDefault("sound_volume", "0.8");
settings->setDefault("desynchronize_mapblock_texture_animation", "true");
// Server stuff
// "map-dir" doesn't exist by default.
@@ -120,6 +120,9 @@ void set_default_settings(Settings *settings)
settings->setDefault("default_privs", "interact, shout");
settings->setDefault("unlimited_player_transfer_distance", "true");
settings->setDefault("enable_pvp", "true");
settings->setDefault("disallow_empty_password", "false");
settings->setDefault("disable_anticheat", "false");
settings->setDefault("enable_rollback_recording", "false");
settings->setDefault("profiler_print_interval", "0");
settings->setDefault("enable_mapgen_debug_info", "false");
@@ -137,5 +140,6 @@ void set_default_settings(Settings *settings)
settings->setDefault("server_map_save_interval", "5.3");
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
settings->setDefault("dedicated_server_step", "0.05");
settings->setDefault("ignore_world_load_errors", "false");
}

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -42,6 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "localplayer.h"
#endif
#include "daynightratio.h"
#include "map.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -325,6 +326,7 @@ ServerEnvironment::ServerEnvironment(ServerMap *map, lua_State *L,
m_emerger(emerger),
m_random_spawn_timer(3),
m_send_recommended_timer(0),
m_active_block_interval_overload_skip(0),
m_game_time(0),
m_game_time_fraction_counter(0)
{
@@ -349,6 +351,17 @@ ServerEnvironment::~ServerEnvironment()
}
}
Map & ServerEnvironment::getMap()
{
return *m_map;
}
ServerMap & ServerEnvironment::getServerMap()
{
return *m_map;
}
void ServerEnvironment::serializePlayers(const std::string &savedir)
{
std::string players_path = savedir + "/players";
@@ -774,10 +787,18 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
activateObjects(block);
// Run node timers
std::map<v3s16, f32> elapsed_timers =
std::map<v3s16, NodeTimer> elapsed_timers =
block->m_node_timers.step((float)dtime_s);
if(!elapsed_timers.empty())
errorstream<<"Node timers don't work yet!"<<std::endl;
if(!elapsed_timers.empty()){
MapNode n;
for(std::map<v3s16, NodeTimer>::iterator
i = elapsed_timers.begin();
i != elapsed_timers.end(); i++){
n = block->getNodeNoEx(i->first);
if(scriptapi_node_on_timer(m_lua,i->first,n,i->second.elapsed))
block->setNodeTimer(i->first,NodeTimer(i->second.timeout,0));
}
}
/* Handle ActiveBlockModifiers */
ABMHandler abmhandler(m_abms, dtime_s, this, false);
@@ -1058,16 +1079,29 @@ void ServerEnvironment::step(float dtime)
"Timestamp older than 60s (step)");
// Run node timers
std::map<v3s16, f32> elapsed_timers =
block->m_node_timers.step(dtime);
if(!elapsed_timers.empty())
errorstream<<"Node timers don't work yet!"<<std::endl;
std::map<v3s16, NodeTimer> elapsed_timers =
block->m_node_timers.step((float)dtime);
if(!elapsed_timers.empty()){
MapNode n;
for(std::map<v3s16, NodeTimer>::iterator
i = elapsed_timers.begin();
i != elapsed_timers.end(); i++){
n = block->getNodeNoEx(i->first);
if(scriptapi_node_on_timer(m_lua,i->first,n,i->second.elapsed))
block->setNodeTimer(i->first,NodeTimer(i->second.timeout,0));
}
}
}
}
const float abm_interval = 1.0;
if(m_active_block_modifier_interval.step(dtime, abm_interval))
{
do{ // breakable
if(m_active_block_interval_overload_skip > 0){
ScopeProfiler sp(g_profiler, "SEnv: ABM overload skips");
m_active_block_interval_overload_skip--;
break;
}
ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg /1s", SPT_AVG);
TimeTaker timer("modify in active blocks");
@@ -1100,8 +1134,9 @@ void ServerEnvironment::step(float dtime)
infostream<<"WARNING: active block modifiers took "
<<time_ms<<"ms (longer than "
<<max_time_ms<<"ms)"<<std::endl;
m_active_block_interval_overload_skip = (time_ms / max_time_ms) + 1;
}
}
}while(0);
/*
Step script environment (run global on_step())

View File

@@ -3,16 +3,16 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -31,12 +31,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include <set>
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "player.h"
#include "map.h"
#include <ostream>
#include "utility.h"
#include "activeobject.h"
#include "util/container.h"
#include "util/numeric.h"
#include "mapnode.h"
#include "mapblock.h"
class Server;
class ServerEnvironment;
@@ -45,6 +47,8 @@ class ServerActiveObject;
typedef struct lua_State lua_State;
class ITextureSource;
class IGameDef;
class Map;
class ServerMap;
class ClientMap;
class Environment
@@ -190,11 +194,9 @@ class ServerEnvironment : public Environment
IBackgroundBlockEmerger *emerger);
~ServerEnvironment();
Map & getMap()
{ return *m_map; }
Map & getMap();
ServerMap & getServerMap()
{ return *m_map; }
ServerMap & getServerMap();
lua_State* getLua()
{ return m_lua; }
@@ -358,6 +360,7 @@ class ServerEnvironment : public Environment
IntervalLimiter m_active_blocks_management_interval;
IntervalLimiter m_active_block_modifier_interval;
IntervalLimiter m_active_blocks_nodemetadata_interval;
int m_active_block_interval_overload_skip;
// Time from the beginning of the game in seconds.
// Incremented in step().
u32 m_game_time;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Part of Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Part of 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
distance according to map seed
*/
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#define FARMESH_MATERIAL_COUNT 2

View File

@@ -4,30 +4,31 @@ Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2012 Jonathan Neuschäfer <j.neuschaefer@gmx.net>
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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "filecache.h"
#include "clientserver.h"
#include "log.h"
#include "filesys.h"
#include "utility.h"
#include "hex.h"
#include "sha1.h"
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
bool FileCache::loadByPath(const std::string &path, std::ostream &os)
{

View File

@@ -4,16 +4,16 @@ Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2012 Jonathan Neuschäfer <j.neuschaefer@gmx.net>
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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,22 +3,22 @@ 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "game.h"
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
@@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server.h"
#include "guiPauseMenu.h"
#include "guiPasswordChange.h"
#include "guiInventoryMenu.h"
#include "guiFormSpecMenu.h"
#include "guiTextInputMenu.h"
#include "guiDeathScreen.h"
#include "tool.h"
@@ -61,17 +61,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif
#include "event_manager.h"
#include <list>
/*
Setting this to 1 enables a special camera mode that forces
the renderers to think that the camera statically points from
the starting place to a static direction.
This allows one to move around with the player and see what
is actually drawn behind solid things and behind the player.
*/
#define FIELD_OF_VIEW_TEST 0
#include "util/directiontables.h"
/*
Text input system
@@ -87,6 +77,10 @@ struct TextDestChat : public TextDest
{
m_client->typeChatMessage(text);
}
void gotText(std::map<std::string, std::string> fields)
{
m_client->typeChatMessage(narrow_to_wide(fields["text"]));
}
Client *m_client;
};
@@ -98,20 +92,39 @@ struct TextDestNodeMetadata : public TextDest
m_p = p;
m_client = client;
}
// This is deprecated I guess? -celeron55
void gotText(std::wstring text)
{
std::string ntext = wide_to_narrow(text);
infostream<<"Changing text of a sign node: "
<<ntext<<std::endl;
infostream<<"Submitting 'text' field of node at ("<<m_p.X<<","
<<m_p.Y<<","<<m_p.Z<<"): "<<ntext<<std::endl;
std::map<std::string, std::string> fields;
fields["text"] = ntext;
m_client->sendNodemetaFields(m_p, "", fields);
}
void gotText(std::map<std::string, std::string> fields)
{
m_client->sendNodemetaFields(m_p, "", fields);
}
v3s16 m_p;
Client *m_client;
};
struct TextDestPlayerInventory : public TextDest
{
TextDestPlayerInventory(Client *client)
{
m_client = client;
}
void gotText(std::map<std::string, std::string> fields)
{
m_client->sendInventoryFields("", fields);
}
Client *m_client;
};
/* Respawn menu callback */
class MainRespawnInitiator: public IRespawnInitiator
@@ -149,11 +162,34 @@ class NodeMetadataFormSource: public IFormSource
return "";
return meta->getString("formspec");
}
std::string resolveText(std::string str)
{
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
if(!meta)
return str;
return meta->resolveString(str);
}
ClientMap *m_map;
v3s16 m_p;
};
class PlayerInventoryFormSource: public IFormSource
{
public:
PlayerInventoryFormSource(Client *client):
m_client(client)
{
}
std::string getForm()
{
LocalPlayer* player = m_client->getEnv().getLocalPlayer();
return player->inventory_formspec;
}
Client *m_client;
};
/*
Hotbar draw routine
*/
@@ -305,14 +341,12 @@ PointedThing getPointedThing(Client *client, v3f player_position,
core::line3d<f32> shootline, f32 d,
bool liquids_pointable,
bool look_for_object,
core::aabbox3d<f32> &hilightbox,
bool &should_show_hilightbox,
std::vector<aabb3f> &hilightboxes,
ClientActiveObject *&selected_object)
{
PointedThing result;
hilightbox = core::aabbox3d<f32>(0,0,0,0,0,0);
should_show_hilightbox = false;
hilightboxes.clear();
selected_object = NULL;
INodeDefManager *nodedef = client->getNodeDefManager();
@@ -323,27 +357,27 @@ PointedThing getPointedThing(Client *client, v3f player_position,
{
selected_object = client->getSelectedActiveObject(d*BS,
camera_position, shootline);
}
if(selected_object != NULL)
{
core::aabbox3d<f32> *selection_box
= selected_object->getSelectionBox();
// Box should exist because object was returned in the
// first place
assert(selection_box);
v3f pos = selected_object->getPosition();
if(selected_object != NULL)
{
if(selected_object->doShowSelectionBox())
{
aabb3f *selection_box = selected_object->getSelectionBox();
// Box should exist because object was
// returned in the first place
assert(selection_box);
hilightbox = core::aabbox3d<f32>(
selection_box->MinEdge + pos,
selection_box->MaxEdge + pos
);
v3f pos = selected_object->getPosition();
hilightboxes.push_back(aabb3f(
selection_box->MinEdge + pos,
selection_box->MaxEdge + pos));
}
should_show_hilightbox = selected_object->doShowSelectionBox();
result.type = POINTEDTHING_OBJECT;
result.object_id = selected_object->getId();
return result;
result.type = POINTEDTHING_OBJECT;
result.object_id = selected_object->getId();
return result;
}
}
// That didn't work, try to find a pointed at node
@@ -363,6 +397,14 @@ PointedThing getPointedThing(Client *client, v3f player_position,
s16 zend = pos_i.Z + (camera_direction.Z>0 ? a : 1);
s16 xend = pos_i.X + (camera_direction.X>0 ? a : 1);
// Prevent signed number overflow
if(yend==32767)
yend=32766;
if(zend==32767)
zend=32766;
if(xend==32767)
xend=32766;
for(s16 y = ystart; y <= yend; y++)
for(s16 z = zstart; z <= zend; z++)
for(s16 x = xstart; x <= xend; x++)
@@ -379,196 +421,64 @@ PointedThing getPointedThing(Client *client, v3f player_position,
if(!isPointableNode(n, client, liquids_pointable))
continue;
std::vector<aabb3f> boxes = n.getSelectionBoxes(nodedef);
v3s16 np(x,y,z);
v3f npf = intToFloat(np, BS);
f32 d = 0.01;
v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
v3s16(1,0,0), // right
v3s16(0,0,-1), // front
v3s16(0,-1,0), // bottom
v3s16(-1,0,0), // left
};
const ContentFeatures &f = nodedef->get(n);
if(f.selection_box.type == NODEBOX_FIXED)
for(std::vector<aabb3f>::const_iterator
i = boxes.begin();
i != boxes.end(); i++)
{
core::aabbox3d<f32> box = f.selection_box.fixed;
aabb3f box = *i;
box.MinEdge += npf;
box.MaxEdge += npf;
v3s16 facedirs[6] = {
v3s16(-1,0,0),
v3s16(1,0,0),
v3s16(0,-1,0),
v3s16(0,1,0),
v3s16(0,0,-1),
v3s16(0,0,1),
};
core::aabbox3d<f32> faceboxes[6] = {
// X-
core::aabbox3d<f32>(
box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z,
box.MinEdge.X+d, box.MaxEdge.Y, box.MaxEdge.Z
),
// X+
core::aabbox3d<f32>(
box.MaxEdge.X-d, box.MinEdge.Y, box.MinEdge.Z,
box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z
),
// Y-
core::aabbox3d<f32>(
box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z,
box.MaxEdge.X, box.MinEdge.Y+d, box.MaxEdge.Z
),
// Y+
core::aabbox3d<f32>(
box.MinEdge.X, box.MaxEdge.Y-d, box.MinEdge.Z,
box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z
),
// Z-
core::aabbox3d<f32>(
box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z,
box.MaxEdge.X, box.MaxEdge.Y, box.MinEdge.Z+d
),
// Z+
core::aabbox3d<f32>(
box.MinEdge.X, box.MinEdge.Y, box.MaxEdge.Z-d,
box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z
),
};
for(u16 i=0; i<6; i++)
for(u16 j=0; j<6; j++)
{
v3f facedir_f(facedirs[i].X, facedirs[i].Y, facedirs[i].Z);
v3f centerpoint = npf + facedir_f * BS/2;
v3s16 facedir = g_6dirs[j];
aabb3f facebox = box;
f32 d = 0.001*BS;
if(facedir.X > 0)
facebox.MinEdge.X = facebox.MaxEdge.X-d;
else if(facedir.X < 0)
facebox.MaxEdge.X = facebox.MinEdge.X+d;
else if(facedir.Y > 0)
facebox.MinEdge.Y = facebox.MaxEdge.Y-d;
else if(facedir.Y < 0)
facebox.MaxEdge.Y = facebox.MinEdge.Y+d;
else if(facedir.Z > 0)
facebox.MinEdge.Z = facebox.MaxEdge.Z-d;
else if(facedir.Z < 0)
facebox.MaxEdge.Z = facebox.MinEdge.Z+d;
v3f centerpoint = facebox.getCenter();
f32 distance = (centerpoint - camera_position).getLength();
if(distance >= mindistance)
continue;
if(!faceboxes[i].intersectsWithLine(shootline))
if(!facebox.intersectsWithLine(shootline))
continue;
v3s16 np_above = np + facedir;
result.type = POINTEDTHING_NODE;
result.node_undersurface = np;
result.node_abovesurface = np+facedirs[i];
result.node_abovesurface = np_above;
mindistance = distance;
hilightbox = box;
should_show_hilightbox = true;
}
}
else if(f.selection_box.type == NODEBOX_WALLMOUNTED)
{
v3s16 dir = n.getWallMountedDir(nodedef);
v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
dir_f *= BS/2 - BS/6 - BS/20;
v3f cpf = npf + dir_f;
f32 distance = (cpf - camera_position).getLength();
core::aabbox3d<f32> box;
// top
if(dir == v3s16(0,1,0)){
box = f.selection_box.wall_top;
}
// bottom
else if(dir == v3s16(0,-1,0)){
box = f.selection_box.wall_bottom;
}
// side
else{
v3f vertices[2] =
hilightboxes.clear();
for(std::vector<aabb3f>::const_iterator
i2 = boxes.begin();
i2 != boxes.end(); i2++)
{
f.selection_box.wall_side.MinEdge,
f.selection_box.wall_side.MaxEdge
};
for(s32 i=0; i<2; i++)
{
if(dir == v3s16(-1,0,0))
vertices[i].rotateXZBy(0);
if(dir == v3s16(1,0,0))
vertices[i].rotateXZBy(180);
if(dir == v3s16(0,0,-1))
vertices[i].rotateXZBy(90);
if(dir == v3s16(0,0,1))
vertices[i].rotateXZBy(-90);
}
box = core::aabbox3d<f32>(vertices[0]);
box.addInternalPoint(vertices[1]);
}
box.MinEdge += npf;
box.MaxEdge += npf;
if(distance < mindistance)
{
if(box.intersectsWithLine(shootline))
{
result.type = POINTEDTHING_NODE;
result.node_undersurface = np;
result.node_abovesurface = np;
mindistance = distance;
hilightbox = box;
should_show_hilightbox = true;
aabb3f box = *i2;
box.MinEdge += npf + v3f(-d,-d,-d);
box.MaxEdge += npf + v3f(d,d,d);
hilightboxes.push_back(box);
}
}
}
else // NODEBOX_REGULAR
{
for(u16 i=0; i<6; i++)
{
v3f dir_f = v3f(dirs[i].X,
dirs[i].Y, dirs[i].Z);
v3f centerpoint = npf + dir_f * BS/2;
f32 distance =
(centerpoint - camera_position).getLength();
if(distance < mindistance)
{
core::CMatrix4<f32> m;
m.buildRotateFromTo(v3f(0,0,1), dir_f);
// This is the back face
v3f corners[2] = {
v3f(BS/2, BS/2, BS/2),
v3f(-BS/2, -BS/2, BS/2+d)
};
for(u16 j=0; j<2; j++)
{
m.rotateVect(corners[j]);
corners[j] += npf;
}
core::aabbox3d<f32> facebox(corners[0]);
facebox.addInternalPoint(corners[1]);
if(facebox.intersectsWithLine(shootline))
{
result.type = POINTEDTHING_NODE;
result.node_undersurface = np;
result.node_abovesurface = np + dirs[i];
mindistance = distance;
//hilightbox = facebox;
const float d = 0.502;
core::aabbox3d<f32> nodebox
(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
v3f nodepos_f = intToFloat(np, BS);
nodebox.MinEdge += nodepos_f;
nodebox.MaxEdge += nodepos_f;
hilightbox = nodebox;
should_show_hilightbox = true;
}
} // if distance < mindistance
} // for dirs
} // regular block
} // for coords
return result;
@@ -1236,6 +1146,16 @@ void the_game(
*/
Inventory local_inventory(itemdef);
/*
Find out size of crack animation
*/
int crack_animation_length = 5;
{
video::ITexture *t = tsrc->getTextureRaw("crack_anylength.png");
v2u32 size = t->getOriginalSize();
crack_animation_length = size.Y / size.X;
}
/*
Add some gui stuff
*/
@@ -1515,7 +1435,7 @@ void the_game(
hotbar_imagesize = 64;
// Hilight boxes collected during the loop and displayed
core::list< core::aabbox3d<f32> > hilightboxes;
std::vector<aabb3f> hilightboxes;
// Info text
std::wstring infotext;
@@ -1589,22 +1509,19 @@ void the_game(
infostream<<"the_game: "
<<"Launching inventory"<<std::endl;
GUIInventoryMenu *menu =
new GUIInventoryMenu(guienv, guiroot, -1,
GUIFormSpecMenu *menu =
new GUIFormSpecMenu(guienv, guiroot, -1,
&g_menumgr,
&client, gamedef);
InventoryLocation inventoryloc;
inventoryloc.setCurrentPlayer();
menu->setFormSpec(
"invsize[8,7.5;]"
//"image[1,0.6;1,2;player.png]"
"list[current_player;main;0,3.5;8,4;]"
"list[current_player;craft;3,0;3,3;]"
"list[current_player;craftpreview;7,1;1,1;]"
, inventoryloc);
PlayerInventoryFormSource *src = new PlayerInventoryFormSource(&client);
assert(src);
menu->setFormSpec(src->getForm(), inventoryloc);
menu->setFormSource(src);
menu->setTextDest(new TextDestPlayerInventory(&client));
menu->drop();
}
else if(input->wasKeyDown(EscapeKey))
@@ -2128,8 +2045,6 @@ void the_game(
core::line3d<f32> shootline(camera_position,
camera_position + camera_direction * BS * (d+1));
core::aabbox3d<f32> hilightbox;
bool should_show_hilightbox = false;
ClientActiveObject *selected_object = NULL;
PointedThing pointed = getPointedThing(
@@ -2138,7 +2053,7 @@ void the_game(
camera_position, shootline, d,
playeritem_liquids_pointable, !ldown_for_dig,
// output
hilightbox, should_show_hilightbox,
hilightboxes,
selected_object);
if(pointed != pointed_old)
@@ -2147,12 +2062,6 @@ void the_game(
//dstream<<"Pointing at "<<pointed.dump()<<std::endl;
}
/*
Visualize selection
*/
if(should_show_hilightbox)
hilightboxes.push_back(hilightbox);
/*
Stop digging when
- releasing left mouse button
@@ -2217,7 +2126,7 @@ void the_game(
infotext = narrow_to_wide(meta->getString("infotext"));
} else {
MapNode n = map.getNode(nodepos);
if(nodedef->get(n).tname_tiles[0] == "unknown_block.png"){
if(nodedef->get(n).tiledef[0].name == "unknown_block.png"){
infotext = L"Unknown node: ";
infotext += narrow_to_wide(nodedef->get(n).name);
}
@@ -2242,7 +2151,9 @@ void the_game(
ldown_for_dig = true;
}
MapNode n = client.getEnv().getClientMap().getNode(nodepos);
// NOTE: Similar piece of code exists on the server side for
// cheat detection.
// Get digging parameters
DigParams params = getDigParams(nodedef->get(n).groups,
&playeritem_toolcap);
@@ -2282,20 +2193,20 @@ void the_game(
if(dig_time_complete >= 0.001)
{
dig_index = (u16)((float)CRACK_ANIMATION_LENGTH
dig_index = (u16)((float)crack_animation_length
* dig_time/dig_time_complete);
}
// This is for torches
else
{
dig_index = CRACK_ANIMATION_LENGTH;
dig_index = crack_animation_length;
}
// Don't show cracks if not diggable
if(dig_time_complete >= 100000.0)
{
}
else if(dig_index < CRACK_ANIMATION_LENGTH)
else if(dig_index < crack_animation_length)
{
//TimeTaker timer("client.setTempMod");
//infostream<<"dig_index="<<dig_index<<std::endl;
@@ -2313,7 +2224,7 @@ void the_game(
digging = false;
nodig_delay_timer = dig_time_complete
/ (float)CRACK_ANIMATION_LENGTH;
/ (float)crack_animation_length;
// We don't want a corresponding delay to
// very time consuming nodes
@@ -2339,7 +2250,8 @@ void the_game(
{
infostream<<"Ground right-clicked"<<std::endl;
// sign special case, at least until formspec is properly implemented
// Sign special case, at least until formspec is properly implemented.
// Deprecated?
if(meta && meta->getString("formspec") == "hack:sign_text_input" && !random_input)
{
infostream<<"Launching metadata text input"<<std::endl;
@@ -2364,21 +2276,62 @@ void the_game(
/* Create menu */
GUIInventoryMenu *menu =
new GUIInventoryMenu(guienv, guiroot, -1,
GUIFormSpecMenu *menu =
new GUIFormSpecMenu(guienv, guiroot, -1,
&g_menumgr,
&client, gamedef);
menu->setFormSpec(meta->getString("formspec"),
inventoryloc);
menu->setFormSource(new NodeMetadataFormSource(
&client.getEnv().getClientMap(), nodepos));
menu->setTextDest(new TextDestNodeMetadata(nodepos, &client));
menu->drop();
}
// Otherwise report right click to server
else
{
// Report to server
client.interact(3, pointed);
camera.setDigging(1); // right click animation
// If the wielded item has node placement prediction,
// make that happen
const ItemDefinition &def =
playeritem.getDefinition(itemdef);
if(def.node_placement_prediction != "")
do{ // breakable
verbosestream<<"Node placement prediction for "
<<playeritem.name<<" is "
<<def.node_placement_prediction<<std::endl;
v3s16 p = neighbourpos;
// Place inside node itself if buildable_to
try{
MapNode n_under = map.getNode(nodepos);
if(nodedef->get(n_under).buildable_to)
p = nodepos;
}catch(InvalidPositionException &e){}
// Find id of predicted node
content_t id;
bool found =
nodedef->getId(def.node_placement_prediction, id);
if(!found){
errorstream<<"Node placement prediction failed for "
<<playeritem.name<<" (places "
<<def.node_placement_prediction
<<") - Name not known"<<std::endl;
break;
}
MapNode n(id);
try{
// This triggers the required mesh update too
client.addNode(p, n);
}catch(InvalidPositionException &e){
errorstream<<"Node placement prediction failed for "
<<playeritem.name<<" (places "
<<def.node_placement_prediction
<<") - Position not loaded"<<std::endl;
}
}while(0);
}
}
}
@@ -2786,9 +2739,10 @@ void the_game(
if(show_hud)
{
for(core::list<aabb3f>::Iterator i=hilightboxes.begin();
i != hilightboxes.end(); i++)
{
for(std::vector<aabb3f>::const_iterator
i = hilightboxes.begin();
i != hilightboxes.end(); i++)
{
/*infostream<<"hilightbox min="
<<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
<<" max="

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef GAME_HEADER
#define GAME_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include <string>
#include "keycode.h"

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -29,6 +29,7 @@ class ICraftDefManager;
class ITextureSource;
class ISoundManager;
class MtEventManager;
class IRollbackReportSink;
/*
An interface for fetching game-global definitions like tool and
@@ -54,6 +55,10 @@ class IGameDef
// Only usable on the client
virtual ISoundManager* getSoundManager()=0;
virtual MtEventManager* getEventManager()=0;
// Only usable on the server, and NOT thread-safe. It is usable from the
// environment thread.
virtual IRollbackReportSink* getRollbackReportSink(){return NULL;}
// Used on the client
virtual bool checkLocalPrivilege(const std::string &priv)
@@ -66,6 +71,7 @@ class IGameDef
ITextureSource* tsrc(){return getTextureSource();}
ISoundManager* sound(){return getSoundManager();}
MtEventManager* event(){return getEventManager();}
IRollbackReportSink* rollback(){return getRollbackReportSink();}
};
#endif

View File

@@ -3,23 +3,23 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "genericobject.h"
#include "utility.h"
#include <sstream>
#include "util/serialize.h"
std::string gob_cmd_set_properties(const ObjectProperties &prop)
{

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define GENERICOBJECT_HEADER
#include <string>
#include "irrlichttypes.h"
#include "irrlichttypes_bloated.h"
#include <iostream>
#define GENERIC_CMD_SET_PROPERTIES 0

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef GETTIME_HEADER
#define GETTIME_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes.h"
/*
Get a millisecond counter value.

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef GUICHATCONSOLE_HEADER
#define GUICHATCONSOLE_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "chat.h"
class Client;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,9 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef GUICONFIRMMENU_HEADER
#define GUICONFIRMMENU_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "modalMenu.h"
#include "utility.h"
#include <string>
struct ConfirmDest

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -27,8 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include <IGUIListBox.h>
#include "gettext.h"
#include "util/string.h"
enum
{

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,9 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef GUICREATEWORLD_HEADER
#define GUICREATEWORLD_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "modalMenu.h"
#include "utility.h"
#include <string>
#include "subgame.h"

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,9 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef GUIMESSAGEMENU_HEADER
#define GUIMESSAGEMENU_HEADER
#include "common_irrlicht.h"
#include "irrlichttypes_extrabloated.h"
#include "modalMenu.h"
#include "utility.h"
#include <string>
class IRespawnInitiator

View File

@@ -3,22 +3,22 @@ Minetest-c55
Copyright (C) 2010 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
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "guiInventoryMenu.h"
#include "guiFormSpecMenu.h"
#include "constants.h"
#include "gamedef.h"
#include "keycode.h"
@@ -30,6 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUIFont.h>
#include "log.h"
#include "tile.h" // ITextureSource
#include "util/string.h"
#include "util/numeric.h"
#include "gettext.h"
void drawItemStack(video::IVideoDriver *driver,
gui::IGUIFont *font,
@@ -118,10 +122,10 @@ void drawItemStack(video::IVideoDriver *driver,
}
/*
GUIInventoryMenu
GUIFormSpecMenu
*/
GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
GUIFormSpecMenu::GUIFormSpecMenu(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr,
InventoryManager *invmgr,
@@ -131,6 +135,7 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
m_invmgr(invmgr),
m_gamedef(gamedef),
m_form_src(NULL),
m_text_dst(NULL),
m_selected_item(NULL),
m_selected_amount(0),
m_selected_dragging(false),
@@ -138,15 +143,16 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
{
}
GUIInventoryMenu::~GUIInventoryMenu()
GUIFormSpecMenu::~GUIFormSpecMenu()
{
removeChildren();
delete m_selected_item;
delete m_form_src;
delete m_text_dst;
}
void GUIInventoryMenu::removeChildren()
void GUIFormSpecMenu::removeChildren()
{
const core::list<gui::IGUIElement*> &children = getChildren();
core::list<gui::IGUIElement*> children_copy;
@@ -173,7 +179,7 @@ void GUIInventoryMenu::removeChildren()
}
}
void GUIInventoryMenu::regenerateGui(v2u32 screensize)
void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
{
// Remove children
removeChildren();
@@ -181,24 +187,37 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
v2s32 size(100,100);
s32 helptext_h = 15;
core::rect<s32> rect;
// Base position of contents of form
v2s32 basepos = getBasePos();
// State of basepos, 0 = not set, 1= set by formspec, 2 = set by size[] element
// Used to adjust form size automatically if needed
// A proceed button is added if there is no size[] element
int bp_set = 0;
/* Convert m_init_draw_spec to m_inventorylists */
m_inventorylists.clear();
m_images.clear();
m_fields.clear();
Strfnd f(m_formspec_string);
while(f.atend() == false)
{
std::string type = trim(f.next("["));
if(type == "invsize")
if(type == "invsize" || type == "size")
{
v2f invsize;
invsize.X = stof(f.next(","));
invsize.Y = stof(f.next(";"));
infostream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
f.next("]");
if(type == "size")
{
invsize.Y = stof(f.next("]"));
}
else{
invsize.Y = stof(f.next(";"));
f.next("]");
}
infostream<<"Form size ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
padding = v2s32(screensize.Y/40, screensize.Y/40);
spacing = v2s32(screensize.Y/12, screensize.Y/13);
@@ -216,6 +235,7 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
DesiredRect = rect;
recalculateAbsolutePosition(false);
basepos = getBasePos();
bp_set = 2;
}
else if(type == "list")
{
@@ -236,8 +256,13 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
<<", pos=("<<pos.X<<","<<pos.Y<<")"
<<", geom=("<<geom.X<<","<<geom.Y<<")"
<<std::endl;
f.next("]");
m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom));
std::string start_i_s = f.next("]");
s32 start_i = 0;
if(start_i_s != "")
start_i = stoi(start_i_s);
if(bp_set != 2)
errorstream<<"WARNING: invalid use of list without a size[] element"<<std::endl;
m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom, start_i));
}
else if(type == "image")
{
@@ -252,8 +277,193 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
<<", pos=("<<pos.X<<","<<pos.Y<<")"
<<", geom=("<<geom.X<<","<<geom.Y<<")"
<<std::endl;
if(bp_set != 2)
errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
m_images.push_back(ImageDrawSpec(name, pos, geom));
}
else if(type == "field")
{
std::string fname = f.next(";");
std::string flabel = f.next(";");
if(fname.find(",") == std::string::npos && flabel.find(",") == std::string::npos)
{
if(!bp_set)
{
rect = core::rect<s32>(
screensize.X/2 - 580/2,
screensize.Y/2 - 300/2,
screensize.X/2 + 580/2,
screensize.Y/2 + 300/2
);
DesiredRect = rect;
recalculateAbsolutePosition(false);
basepos = getBasePos();
bp_set = 1;
}
else if(bp_set == 2)
errorstream<<"WARNING: invalid use of unpositioned field in inventory"<<std::endl;
v2s32 pos = basepos;
pos.Y = ((m_fields.size()+2)*60);
v2s32 size = DesiredRect.getSize();
rect = core::rect<s32>(size.X/2-150, pos.Y, (size.X/2-150)+300, pos.Y+30);
}
else
{
v2s32 pos;
pos.X = stof(fname.substr(0,fname.find(","))) * (float)spacing.X;
pos.Y = stof(fname.substr(fname.find(",")+1)) * (float)spacing.Y;
v2s32 geom;
geom.X = (stof(flabel.substr(0,flabel.find(","))) * (float)spacing.X)-(spacing.X-imgsize.X);
pos.Y += (stof(flabel.substr(flabel.find(",")+1)) * (float)imgsize.Y)/2;
rect = core::rect<s32>(pos.X, pos.Y-15, pos.X+geom.X, pos.Y+15);
fname = f.next(";");
flabel = f.next(";");
if(bp_set != 2)
errorstream<<"WARNING: invalid use of positioned field without a size[] element"<<std::endl;
}
std::string odefault = f.next("]");
std::string fdefault;
// fdefault may contain a variable reference, which
// needs to be resolved from the node metadata
if(m_form_src)
fdefault = m_form_src->resolveText(odefault);
else
fdefault = odefault;
FieldSpec spec = FieldSpec(
narrow_to_wide(fname.c_str()),
narrow_to_wide(flabel.c_str()),
narrow_to_wide(fdefault.c_str()),
258+m_fields.size()
);
// three cases: field and no label, label and no field, label and field
if (flabel == "")
{
spec.send = true;
gui::IGUIElement *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid);
Environment->setFocus(e);
irr::SEvent evt;
evt.EventType = EET_KEY_INPUT_EVENT;
evt.KeyInput.Key = KEY_END;
evt.KeyInput.PressedDown = true;
e->OnEvent(evt);
}
else if (fname == "")
{
// set spec field id to 0, this stops submit searching for a value that isn't there
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, spec.fid);
}
else
{
spec.send = true;
gui::IGUIElement *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid);
Environment->setFocus(e);
rect.UpperLeftCorner.Y -= 15;
rect.LowerRightCorner.Y -= 15;
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
irr::SEvent evt;
evt.EventType = EET_KEY_INPUT_EVENT;
evt.KeyInput.Key = KEY_END;
evt.KeyInput.PressedDown = true;
e->OnEvent(evt);
}
m_fields.push_back(spec);
}
else if(type == "label")
{
v2s32 pos = padding;
pos.X += stof(f.next(",")) * (float)spacing.X;
pos.Y += stof(f.next(";")) * (float)spacing.Y;
rect = core::rect<s32>(pos.X, pos.Y+((imgsize.Y/2)-15), pos.X+300, pos.Y+((imgsize.Y/2)+15));
std::string flabel = f.next("]");
if(bp_set != 2)
errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl;
FieldSpec spec = FieldSpec(
narrow_to_wide(""),
narrow_to_wide(flabel.c_str()),
narrow_to_wide(""),
258+m_fields.size()
);
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, spec.fid);
m_fields.push_back(spec);
}
else if(type == "button" || type == "button_exit")
{
v2s32 pos = padding;
pos.X += stof(f.next(",")) * (float)spacing.X;
pos.Y += stof(f.next(";")) * (float)spacing.Y;
v2s32 geom;
geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X);
pos.Y += (stof(f.next(";")) * (float)imgsize.Y)/2;
rect = core::rect<s32>(pos.X, pos.Y-15, pos.X+geom.X, pos.Y+15);
std::string fname = f.next(";");
std::string flabel = f.next("]");
if(bp_set != 2)
errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
FieldSpec spec = FieldSpec(
narrow_to_wide(fname.c_str()),
narrow_to_wide(flabel.c_str()),
narrow_to_wide(""),
258+m_fields.size()
);
spec.is_button = true;
if(type == "button_exit")
spec.is_exit = true;
Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
m_fields.push_back(spec);
}
else if(type == "image_button" || type == "image_button_exit")
{
v2s32 pos = padding;
pos.X += stof(f.next(",")) * (float)spacing.X;
pos.Y += stof(f.next(";")) * (float)spacing.Y;
v2s32 geom;
geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X);
geom.Y = (stof(f.next(";")) * (float)spacing.Y)-(spacing.Y-imgsize.Y);
rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
std::string fimage = f.next(";");
std::string fname = f.next(";");
std::string flabel = f.next("]");
if(bp_set != 2)
errorstream<<"WARNING: invalid use of image_button without a size[] element"<<std::endl;
FieldSpec spec = FieldSpec(
narrow_to_wide(fname.c_str()),
narrow_to_wide(flabel.c_str()),
narrow_to_wide(fimage.c_str()),
258+m_fields.size()
);
spec.is_button = true;
if(type == "image_button_exit")
spec.is_exit = true;
video::ITexture *texture = m_gamedef->tsrc()->getTextureRaw(fimage);
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
e->setImage(texture);
e->setPressedImage(texture);
e->setScaleImage(true);
m_fields.push_back(spec);
}
else
{
// Ignore others
@@ -263,16 +473,44 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
}
}
// Add children
// If there's inventory, put the usage string at the bottom
if (m_inventorylists.size())
{
changeCtype("");
core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h);
rect = rect + v2s32(size.X/2 - rect.getWidth()/2,
size.Y-rect.getHeight()-5);
const wchar_t *text =
L"Left click: Move all items, Right click: Move single item";
const wchar_t *text = wgettext("Left click: Move all items, Right click: Move single item");
Environment->addStaticText(text, rect, false, true, this, 256);
changeCtype("C");
}
// If there's fields, add a Proceed button
if (m_fields.size() && bp_set != 2)
{
// if the size wasn't set by an invsize[] or size[] adjust it now to fit all the fields
rect = core::rect<s32>(
screensize.X/2 - 580/2,
screensize.Y/2 - 300/2,
screensize.X/2 + 580/2,
screensize.Y/2 + 240/2+(m_fields.size()*60)
);
DesiredRect = rect;
recalculateAbsolutePosition(false);
basepos = getBasePos();
// Add tooltip
changeCtype("");
{
v2s32 pos = basepos;
pos.Y = ((m_fields.size()+2)*60);
v2s32 size = DesiredRect.getSize();
rect = core::rect<s32>(size.X/2-70, pos.Y, (size.X/2-70)+140, pos.Y+30);
Environment->addButton(rect, this, 257, wgettext("Proceed"));
}
changeCtype("C");
}
// Add tooltip
{
// Note: parent != this so that the tooltip isn't clipped by the menu rectangle
m_tooltip_element = Environment->addStaticText(L"",core::rect<s32>(0,0,110,18));
m_tooltip_element->enableOverrideColor(true);
@@ -285,7 +523,7 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
}
}
GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
{
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
@@ -295,13 +533,14 @@ GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
for(s32 i=0; i<s.geom.X*s.geom.Y; i++)
{
s32 item_i = i + s.start_item_i;
s32 x = (i%s.geom.X) * spacing.X;
s32 y = (i/s.geom.X) * spacing.Y;
v2s32 p0(x,y);
core::rect<s32> rect = imgrect + s.pos + p0;
if(rect.isPointInside(p))
{
return ItemSpec(s.inventoryloc, s.listname, i);
return ItemSpec(s.inventoryloc, s.listname, item_i);
}
}
}
@@ -309,7 +548,7 @@ GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
return ItemSpec(InventoryLocation(), "", -1);
}
void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
{
video::IVideoDriver* driver = Environment->getVideoDriver();
@@ -321,7 +560,7 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
Inventory *inv = m_invmgr->getInventory(s.inventoryloc);
if(!inv){
infostream<<"GUIInventoryMenu::drawList(): WARNING: "
infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
<<"The inventory location "
<<"\""<<s.inventoryloc.dump()<<"\" doesn't exist"
<<std::endl;
@@ -329,7 +568,7 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
}
InventoryList *ilist = inv->getList(s.listname);
if(!ilist){
infostream<<"GUIInventoryMenu::drawList(): WARNING: "
infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
<<"The inventory list \""<<s.listname<<"\" @ \""
<<s.inventoryloc.dump()<<"\" doesn't exist"
<<std::endl;
@@ -340,13 +579,16 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
for(s32 i=0; i<s.geom.X*s.geom.Y; i++)
{
u32 item_i = i + s.start_item_i;
if(item_i >= ilist->getSize())
break;
s32 x = (i%s.geom.X) * spacing.X;
s32 y = (i/s.geom.X) * spacing.Y;
v2s32 p(x,y);
core::rect<s32> rect = imgrect + s.pos + p;
ItemStack item;
if(ilist)
item = ilist->getItem(i);
item = ilist->getItem(item_i);
bool selected = m_selected_item
&& m_invmgr->getInventory(m_selected_item->inventoryloc) == inv
@@ -402,7 +644,7 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
}
}
void GUIInventoryMenu::drawSelectedItem()
void GUIFormSpecMenu::drawSelectedItem()
{
if(!m_selected_item)
return;
@@ -427,7 +669,7 @@ void GUIInventoryMenu::drawSelectedItem()
drawItemStack(driver, font, stack, rect, NULL, m_gamedef);
}
void GUIInventoryMenu::drawMenu()
void GUIFormSpecMenu::drawMenu()
{
if(m_form_src){
std::string newform = m_form_src->getForm();
@@ -489,7 +731,7 @@ void GUIInventoryMenu::drawMenu()
gui::IGUIElement::draw();
}
void GUIInventoryMenu::updateSelectedItem()
void GUIFormSpecMenu::updateSelectedItem()
{
// If the selected stack has become empty for some reason, deselect it.
// If the selected stack has become smaller, adjust m_selected_amount.
@@ -556,7 +798,36 @@ void GUIInventoryMenu::updateSelectedItem()
}
}
bool GUIInventoryMenu::OnEvent(const SEvent& event)
void GUIFormSpecMenu::acceptInput()
{
if(m_text_dst)
{
std::map<std::string, std::string> fields;
gui::IGUIElement *e;
for(u32 i=0; i<m_fields.size(); i++)
{
const FieldSpec &s = m_fields[i];
if(s.send)
{
if(s.is_button)
{
fields[wide_to_narrow(s.fname.c_str())] = wide_to_narrow(s.flabel.c_str());
}
else
{
e = getElementFromId(s.fid);
if(e != NULL)
{
fields[wide_to_narrow(s.fname.c_str())] = wide_to_narrow(e->getText());
}
}
}
}
m_text_dst->gotText(fields);
}
}
bool GUIFormSpecMenu::OnEvent(const SEvent& event)
{
if(event.EventType==EET_KEY_INPUT_EVENT)
{
@@ -567,6 +838,12 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
quitMenu();
return true;
}
if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
{
acceptInput();
quitMenu();
return true;
}
}
if(event.EventType==EET_MOUSE_INPUT_EVENT
&& event.MouseInput.Event == EMIE_MOUSE_MOVED)
@@ -613,14 +890,14 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
InventoryList *list = inv_s->getList(s.listname);
if(list == NULL){
errorstream<<"InventoryMenu: The selected inventory list \""
verbosestream<<"InventoryMenu: The selected inventory list \""
<<s.listname<<"\" does not exist"<<std::endl;
s.i = -1; // make it invalid again
break;
}
if((u32)s.i >= list->getSize()){
errorstream<<"InventoryMenu: The selected inventory list \""
infostream<<"InventoryMenu: The selected inventory list \""
<<s.listname<<"\" is too small (i="<<s.i<<", size="
<<list->getSize()<<")"<<std::endl;
s.i = -1; // make it invalid again
@@ -858,7 +1135,7 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
{
if(!canTakeFocus(event.GUIEvent.Element))
{
infostream<<"GUIInventoryMenu: Not allowing focus change."
infostream<<"GUIFormSpecMenu: Not allowing focus change."
<<std::endl;
// Returning true disables focus change
return true;
@@ -866,15 +1143,45 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
}
if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
{
/*switch(event.GUIEvent.Caller->getID())
switch(event.GUIEvent.Caller->getID())
{
case 256: // continue
setVisible(false);
break;
case 257: // exit
dev->closeDevice();
break;
}*/
case 257:
acceptInput();
quitMenu();
// quitMenu deallocates menu
return true;
}
// find the element that was clicked
for(u32 i=0; i<m_fields.size(); i++)
{
FieldSpec &s = m_fields[i];
// if its a button, set the send field so
// lua knows which button was pressed
if (s.is_button && s.fid == event.GUIEvent.Caller->getID())
{
s.send = true;
acceptInput();
if(s.is_exit){
quitMenu();
return true;
}else{
s.send = false;
// Restore focus to the full form
Environment->setFocus(this);
return true;
}
}
}
}
if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
{
if(event.GUIEvent.Caller->getID() > 257)
{
acceptInput();
quitMenu();
// quitMenu deallocates menu
return true;
}
}
}

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