Compare commits
209 Commits
0.4.dev-20
...
0.4.dev-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8eb68142e | ||
|
|
81554fbf72 | ||
|
|
a435cfcd82 | ||
|
|
7631918a12 | ||
|
|
e070f1e525 | ||
|
|
430d6e1cca | ||
|
|
3a0562bebc | ||
|
|
c3658e7c79 | ||
|
|
b0f81c3253 | ||
|
|
31c171fc1e | ||
|
|
e9c123b1b9 | ||
|
|
037b259197 | ||
|
|
a569961e0f | ||
|
|
7eabde6aee | ||
|
|
ed772da0cc | ||
|
|
f48882213e | ||
|
|
1cd2076d42 | ||
|
|
816b9c8d71 | ||
|
|
3bea1a944e | ||
|
|
3e419ffb38 | ||
|
|
a149c6ecde | ||
|
|
3f18e9a2da | ||
|
|
4b0494062e | ||
|
|
a09d86dd3c | ||
|
|
3ccb0f691b | ||
|
|
1709fd854a | ||
|
|
7bf446f671 | ||
|
|
e4bc76f55c | ||
|
|
81c5e5200b | ||
|
|
9c3830dd35 | ||
|
|
bf8cfce50e | ||
|
|
b235e4d290 | ||
|
|
b8cf6dee3e | ||
|
|
35df1ee253 | ||
|
|
353f9fd43c | ||
|
|
3899f83da8 | ||
|
|
5f3c70061d | ||
|
|
aba7134301 | ||
|
|
d7447cdf9e | ||
|
|
ff8d2bbc36 | ||
|
|
70c98c9972 | ||
|
|
45f32838b9 | ||
|
|
7d6e80a423 | ||
|
|
f3ec1452cd | ||
|
|
29f03756bd | ||
|
|
fe8c5546f0 | ||
|
|
c4315a7afa | ||
|
|
704782c95b | ||
|
|
67059e1932 | ||
|
|
e2ea711136 | ||
|
|
74aa598769 | ||
|
|
747ff7daf8 | ||
|
|
1f670fc688 | ||
|
|
388906ac70 | ||
|
|
49d9745dc4 | ||
|
|
7c15d793ac | ||
|
|
d90cb3511c | ||
|
|
5100272dc3 | ||
|
|
afda9810f1 | ||
|
|
22df8b81b3 | ||
|
|
7a427c9070 | ||
|
|
a35e4bdbda | ||
|
|
0aeb5adb8f | ||
|
|
9c5cc217bf | ||
|
|
24603d7ad3 | ||
|
|
1eac6ff8ff | ||
|
|
8742b3dab2 | ||
|
|
93cdc9b9dc | ||
|
|
8ed74a3429 | ||
|
|
07a5e59ae7 | ||
|
|
f8c2f1cf54 | ||
|
|
b1f043d010 | ||
|
|
251c0c8508 | ||
|
|
3214daca4c | ||
|
|
e4485f5412 | ||
|
|
4eaaa0ec53 | ||
|
|
42323014ea | ||
|
|
c59d139eeb | ||
|
|
2b4d21160f | ||
|
|
e29a5b11e4 | ||
|
|
b58ee690a3 | ||
|
|
d8edd3d0c8 | ||
|
|
1b078efd5f | ||
|
|
e8e73d37fb | ||
|
|
2eec788544 | ||
|
|
dca28b9e12 | ||
|
|
e879c92596 | ||
|
|
7281c68b27 | ||
|
|
d228f1b658 | ||
|
|
2e60593c5b | ||
|
|
531fe10f51 | ||
|
|
454b07455a | ||
|
|
a4dc6f2c76 | ||
|
|
5608f12f9b | ||
|
|
18d8e3acec | ||
|
|
578fc5bb44 | ||
|
|
e8660cfd8e | ||
|
|
6a57eabb14 | ||
|
|
a67540807a | ||
|
|
20c377ca65 | ||
|
|
5436f1c7d5 | ||
|
|
4107390337 | ||
|
|
e74da72b82 | ||
|
|
24953ba974 | ||
|
|
22a5a1fa43 | ||
|
|
7bac62ee7f | ||
|
|
fcda11c6b0 | ||
|
|
66e1cb324c | ||
|
|
a869d23451 | ||
|
|
41f4941b74 | ||
|
|
b22168d3da | ||
|
|
b9b56bac6b | ||
|
|
fa670fa4b5 | ||
|
|
b131a0cf0c | ||
|
|
d7cef8d762 | ||
|
|
4483fc7df3 | ||
|
|
2cd5addc0c | ||
|
|
5bf06efb2a | ||
|
|
5196e309b8 | ||
|
|
bee1adc651 | ||
|
|
f0e7da8a63 | ||
|
|
5bd32eca0f | ||
|
|
491287c0af | ||
|
|
8ecfd88d92 | ||
|
|
b54178bbbd | ||
|
|
67547f74fc | ||
|
|
56ba193c77 | ||
|
|
d5594e431c | ||
|
|
7bfa2d4da6 | ||
|
|
4cf00f5698 | ||
|
|
a18326e97a | ||
|
|
36c9463467 | ||
|
|
13159c1a48 | ||
|
|
0fbef74f31 | ||
|
|
52122c342d | ||
|
|
96ee73f790 | ||
|
|
dc70f50b59 | ||
|
|
e297c73913 | ||
|
|
280e1a2512 | ||
|
|
1518b8f753 | ||
|
|
5403b1cf6d | ||
|
|
29110d5428 | ||
|
|
462003363f | ||
|
|
b494324ec3 | ||
|
|
4cee9a86ac | ||
|
|
7cad0a2dcd | ||
|
|
ed1ff06867 | ||
|
|
80a64341f0 | ||
|
|
bbf3eebb1a | ||
|
|
6b20ea0752 | ||
|
|
3241ad3ae8 | ||
|
|
9e7ccedba4 | ||
|
|
b9ffb5f30d | ||
|
|
9d456ca87a | ||
|
|
18350ad37f | ||
|
|
0983f65da7 | ||
|
|
42bbd5c9ae | ||
|
|
92ae11bd3b | ||
|
|
443f45eca1 | ||
|
|
a9ddbb4beb | ||
|
|
f8c3743991 | ||
|
|
072c265c30 | ||
|
|
440e9cdbef | ||
|
|
ace005bf7c | ||
|
|
75821c6889 | ||
|
|
d376148ca1 | ||
|
|
582ca33507 | ||
|
|
a6ca7eb29d | ||
|
|
02c035c548 | ||
|
|
418041d906 | ||
|
|
a3a400992e | ||
|
|
68625b047f | ||
|
|
9a1df7bf38 | ||
|
|
81b9cfdfa4 | ||
|
|
ae7aa65069 | ||
|
|
9e0f969b8b | ||
|
|
14a8fa4d68 | ||
|
|
07e5c9bd5f | ||
|
|
49c2ca0216 | ||
|
|
04172e3dd0 | ||
|
|
2c56a9f588 | ||
|
|
20e025b3d8 | ||
|
|
10591d2080 | ||
|
|
af29c0ade5 | ||
|
|
4c876ac62e | ||
|
|
66bf7b0b01 | ||
|
|
17d51a1609 | ||
|
|
0a59605e05 | ||
|
|
202658678d | ||
|
|
4f01db256f | ||
|
|
c04f4a7d73 | ||
|
|
f5e46ba7fc | ||
|
|
8609af54fc | ||
|
|
9a4ef87859 | ||
|
|
a57f4c23d8 | ||
|
|
d629f4d2fb | ||
|
|
6f20a73782 | ||
|
|
8cb7badd63 | ||
|
|
0f3c2f6541 | ||
|
|
56496ad5d8 | ||
|
|
e15dca2a9f | ||
|
|
a32706bc26 | ||
|
|
bdcca4767c | ||
|
|
38f4dbfb51 | ||
|
|
a374b1a6a3 | ||
|
|
0ff94978f5 | ||
|
|
fa24e6b995 | ||
|
|
37b64ff616 | ||
|
|
a2fd8d1db1 |
@@ -7,10 +7,15 @@ endif(${CMAKE_VERSION} STREQUAL "2.8.2")
|
||||
# This can be read from ${PROJECT_NAME} after project() is called
|
||||
project(minetest)
|
||||
|
||||
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||
|
||||
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
||||
set(VERSION_MAJOR 0)
|
||||
set(VERSION_MINOR 4)
|
||||
set(VERSION_PATCH dev-20120326)
|
||||
set(VERSION_PATCH dev-20120606)
|
||||
if(VERSION_EXTRA)
|
||||
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
|
||||
endif()
|
||||
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||
|
||||
MESSAGE(STATUS "*** Will build version ${VERSION_STRING} ***")
|
||||
@@ -85,13 +90,20 @@ elseif(UNIX) # Linux, BSD etc
|
||||
endif()
|
||||
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest" DESTINATION "${SHAREDIR}/games")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games")
|
||||
set(MINETEST_GAME_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game")
|
||||
if(EXISTS ${MINETEST_GAME_SOURCE} AND IS_DIRECTORY ${MINETEST_GAME_SOURCE})
|
||||
install(FILES ${MINETEST_GAME_SOURCE}/game.conf DESTINATION "${SHAREDIR}/games/minetest_game/")
|
||||
install(FILES ${MINETEST_GAME_SOURCE}/README.txt DESTINATION "${SHAREDIR}/games/minetest_game/")
|
||||
install(DIRECTORY ${MINETEST_GAME_SOURCE}/mods DESTINATION "${SHAREDIR}/games/minetest_game")
|
||||
endif()
|
||||
if(BUILD_CLIENT)
|
||||
#install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/sounds/base/pack" DESTINATION "${SHAREDIR}/sounds/base")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base")
|
||||
endif()
|
||||
if(RUN_IN_PLACE)
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/mods/minetest/mods_here.txt" DESTINATION "${SHAREDIR}/mods/minetest")
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/textures/all/textures_here.txt" DESTINATION "${SHAREDIR}/textures/all")
|
||||
endif()
|
||||
|
||||
install(FILES "README.txt" DESTINATION "${DOCDIR}")
|
||||
|
||||
46
README.txt
46
README.txt
@@ -79,13 +79,20 @@ Compiling on GNU/Linux:
|
||||
-----------------------
|
||||
|
||||
Install dependencies. Here's an example for Debian/Ubuntu:
|
||||
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev
|
||||
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev
|
||||
|
||||
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
|
||||
$ wget https://github.com/celeron55/minetest/tarball/master -O master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ cd celeron55-minetest-286edd4 (or similar)
|
||||
|
||||
Download minetest_game (otherwise only the "Minimal development test" game is available)
|
||||
$ cd games/
|
||||
$ wget https://github.com/celeron55/minetest_game/tarball/master -O master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ mv celeron55-minetest_game-* minetest_game
|
||||
$ cd ..
|
||||
|
||||
Build a version that runs directly from the source directory:
|
||||
$ cmake . -DRUN_IN_PLACE=1
|
||||
$ make -j2
|
||||
@@ -102,6 +109,9 @@ $ ./minetest
|
||||
|
||||
Compiling on Windows:
|
||||
---------------------
|
||||
- This section is outdated. In addition to what is described here:
|
||||
- In addition to minetest, you need to download minetest_game.
|
||||
- If you wish to have sound support, you need libogg, libvorbis and libopenal
|
||||
|
||||
- You need:
|
||||
* CMake:
|
||||
@@ -250,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,
|
||||
@@ -259,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.
|
||||
|
||||
@@ -315,6 +325,34 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
|
||||
Lua
|
||||
---------------
|
||||
|
||||
Lua is licensed under the terms of the MIT license reproduced below.
|
||||
This means that Lua is free software and can be used for both academic
|
||||
and commercial purposes at absolutely no cost.
|
||||
|
||||
For details and rationale, see http://www.lua.org/license.html .
|
||||
|
||||
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Fonts
|
||||
---------------
|
||||
|
||||
188
builtin/auth.lua
Normal file
188
builtin/auth.lua
Normal file
@@ -0,0 +1,188 @@
|
||||
-- Minetest: builtin/auth.lua
|
||||
|
||||
--
|
||||
-- Authentication handler
|
||||
--
|
||||
|
||||
function minetest.string_to_privs(str, delim)
|
||||
assert(type(str) == "string")
|
||||
delim = delim or ','
|
||||
privs = {}
|
||||
for _, priv in pairs(string.split(str, delim)) do
|
||||
privs[priv:trim()] = true
|
||||
end
|
||||
return privs
|
||||
end
|
||||
|
||||
function minetest.privs_to_string(privs, delim)
|
||||
assert(type(privs) == "table")
|
||||
delim = delim or ','
|
||||
list = {}
|
||||
for priv, bool in pairs(privs) do
|
||||
if bool then
|
||||
table.insert(list, priv)
|
||||
end
|
||||
end
|
||||
return table.concat(list, delim)
|
||||
end
|
||||
|
||||
assert(minetest.string_to_privs("a,b").b == true)
|
||||
assert(minetest.privs_to_string({a=true,b=true}) == "a,b")
|
||||
|
||||
minetest.auth_file_path = minetest.get_worldpath().."/auth.txt"
|
||||
minetest.auth_table = {}
|
||||
|
||||
local function read_auth_file()
|
||||
local newtable = {}
|
||||
local file, errmsg = io.open(minetest.auth_file_path, 'rb')
|
||||
if not file then
|
||||
minetest.log("info", minetest.auth_file_path.." could not be opened for reading ("..errmsg.."); assuming new world")
|
||||
return
|
||||
end
|
||||
for line in file:lines() do
|
||||
if line ~= "" then
|
||||
local name, password, privilegestring = string.match(line, "([^:]*):([^:]*):([^:]*)")
|
||||
if not name or not password or not privilegestring then
|
||||
error("Invalid line in auth.txt: "..dump(line))
|
||||
end
|
||||
local privileges = minetest.string_to_privs(privilegestring)
|
||||
newtable[name] = {password=password, privileges=privileges}
|
||||
end
|
||||
end
|
||||
io.close(file)
|
||||
minetest.auth_table = newtable
|
||||
minetest.notify_authentication_modified()
|
||||
end
|
||||
|
||||
local function save_auth_file()
|
||||
local newtable = {}
|
||||
-- Check table for validness before attempting to save
|
||||
for name, stuff in pairs(minetest.auth_table) do
|
||||
assert(type(name) == "string")
|
||||
assert(name ~= "")
|
||||
assert(type(stuff) == "table")
|
||||
assert(type(stuff.password) == "string")
|
||||
assert(type(stuff.privileges) == "table")
|
||||
end
|
||||
local file, errmsg = io.open(minetest.auth_file_path, 'w+b')
|
||||
if not file then
|
||||
error(minetest.auth_file_path.." could not be opened for writing: "..errmsg)
|
||||
end
|
||||
for name, stuff in pairs(minetest.auth_table) do
|
||||
local privstring = minetest.privs_to_string(stuff.privileges)
|
||||
file:write(name..":"..stuff.password..":"..privstring..'\n')
|
||||
end
|
||||
io.close(file)
|
||||
end
|
||||
|
||||
read_auth_file()
|
||||
|
||||
minetest.builtin_auth_handler = {
|
||||
get_auth = function(name)
|
||||
assert(type(name) == "string")
|
||||
-- Figure out what password to use for a new player (singleplayer
|
||||
-- always has an empty password, otherwise use default, which is
|
||||
-- usually empty too)
|
||||
local new_password_hash = ""
|
||||
-- If not in authentication table, return nil
|
||||
if not minetest.auth_table[name] then
|
||||
return nil
|
||||
end
|
||||
-- Figure out what privileges the player should have.
|
||||
-- Take a copy of the privilege table
|
||||
local privileges = {}
|
||||
for priv, _ in pairs(minetest.auth_table[name].privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
-- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
|
||||
if minetest.is_singleplayer() then
|
||||
for priv, def in pairs(minetest.registered_privileges) do
|
||||
if def.give_to_singleplayer then
|
||||
privileges[priv] = true
|
||||
end
|
||||
end
|
||||
-- For the admin, give everything
|
||||
elseif name == minetest.setting_get("name") then
|
||||
for priv, def in pairs(minetest.registered_privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
end
|
||||
-- All done
|
||||
return {
|
||||
password = minetest.auth_table[name].password,
|
||||
privileges = privileges,
|
||||
}
|
||||
end,
|
||||
create_auth = function(name, password)
|
||||
assert(type(name) == "string")
|
||||
assert(type(password) == "string")
|
||||
minetest.log('info', "Built-in authentication handler adding player '"..name.."'")
|
||||
minetest.auth_table[name] = {
|
||||
password = password,
|
||||
privileges = minetest.string_to_privs(minetest.setting_get("default_privs")),
|
||||
}
|
||||
save_auth_file()
|
||||
end,
|
||||
set_password = function(name, password)
|
||||
assert(type(name) == "string")
|
||||
assert(type(password) == "string")
|
||||
if not minetest.auth_table[name] then
|
||||
minetest.builtin_auth_handler.create_auth(name, password)
|
||||
else
|
||||
minetest.log('info', "Built-in authentication handler setting password of player '"..name.."'")
|
||||
minetest.auth_table[name].password = password
|
||||
save_auth_file()
|
||||
end
|
||||
return true
|
||||
end,
|
||||
set_privileges = function(name, privileges)
|
||||
assert(type(name) == "string")
|
||||
assert(type(privileges) == "table")
|
||||
if not minetest.auth_table[name] then
|
||||
minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password")))
|
||||
end
|
||||
minetest.auth_table[name].privileges = privileges
|
||||
minetest.notify_authentication_modified(name)
|
||||
save_auth_file()
|
||||
end,
|
||||
reload = function()
|
||||
read_auth_file()
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
||||
function minetest.register_authentication_handler(handler)
|
||||
if minetest.registered_auth_handler then
|
||||
error("Add-on authentication handler already registered by "..minetest.registered_auth_handler_modname)
|
||||
end
|
||||
minetest.registered_auth_handler = handler
|
||||
minetest.registered_auth_handler_modname = minetest.get_current_modname()
|
||||
end
|
||||
|
||||
function minetest.get_auth_handler()
|
||||
if minetest.registered_auth_handler then
|
||||
return minetest.registered_auth_handler
|
||||
end
|
||||
return minetest.builtin_auth_handler
|
||||
end
|
||||
|
||||
function minetest.set_player_password(name, password)
|
||||
if minetest.get_auth_handler().set_password then
|
||||
minetest.get_auth_handler().set_password(name, password)
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.set_player_privs(name, privs)
|
||||
if minetest.get_auth_handler().set_privileges then
|
||||
minetest.get_auth_handler().set_privileges(name, privs)
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.auth_reload()
|
||||
if minetest.get_auth_handler().reload then
|
||||
return minetest.get_auth_handler().reload()
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
@@ -5,800 +5,20 @@
|
||||
-- before loading and running any mods.
|
||||
--
|
||||
|
||||
--
|
||||
-- Override some Lua library functions
|
||||
--
|
||||
|
||||
-- Initialize some very basic things
|
||||
print = minetest.debug
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
function basic_dump2(o)
|
||||
if type(o) == "number" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "string" then
|
||||
return string.format("%q", o)
|
||||
elseif type(o) == "boolean" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "function" then
|
||||
return "<function>"
|
||||
elseif type(o) == "userdata" then
|
||||
return "<userdata>"
|
||||
elseif type(o) == "nil" then
|
||||
return "nil"
|
||||
else
|
||||
error("cannot dump a " .. type(o))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function dump2(o, name, dumped)
|
||||
name = name or "_"
|
||||
dumped = dumped or {}
|
||||
io.write(name, " = ")
|
||||
if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
|
||||
or type(o) == "function" or type(o) == "nil"
|
||||
or type(o) == "userdata" then
|
||||
io.write(basic_dump2(o), "\n")
|
||||
elseif type(o) == "table" then
|
||||
if dumped[o] then
|
||||
io.write(dumped[o], "\n")
|
||||
else
|
||||
dumped[o] = name
|
||||
io.write("{}\n") -- new table
|
||||
for k,v in pairs(o) do
|
||||
local fieldname = string.format("%s[%s]", name, basic_dump2(k))
|
||||
dump2(v, fieldname, dumped)
|
||||
end
|
||||
end
|
||||
else
|
||||
error("cannot dump a " .. type(o))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function dump(o, dumped)
|
||||
dumped = dumped or {}
|
||||
if type(o) == "number" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "string" then
|
||||
return string.format("%q", o)
|
||||
elseif type(o) == "table" then
|
||||
if dumped[o] then
|
||||
return "<circular reference>"
|
||||
end
|
||||
dumped[o] = true
|
||||
local t = {}
|
||||
for k,v in pairs(o) do
|
||||
t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
|
||||
end
|
||||
return "{" .. table.concat(t, ", ") .. "}"
|
||||
elseif type(o) == "boolean" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "function" then
|
||||
return "<function>"
|
||||
elseif type(o) == "userdata" then
|
||||
return "<userdata>"
|
||||
elseif type(o) == "nil" then
|
||||
return "nil"
|
||||
else
|
||||
error("cannot dump a " .. type(o))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Item definition helpers
|
||||
--
|
||||
|
||||
function minetest.inventorycube(img1, img2, img3)
|
||||
img2 = img2 or img1
|
||||
img3 = img3 or img1
|
||||
return "[inventorycube"
|
||||
.. "{" .. img1:gsub("%^", "&")
|
||||
.. "{" .. img2:gsub("%^", "&")
|
||||
.. "{" .. img3:gsub("%^", "&")
|
||||
end
|
||||
|
||||
function minetest.pos_to_string(pos)
|
||||
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
|
||||
end
|
||||
|
||||
function minetest.get_pointed_thing_position(pointed_thing, above)
|
||||
if pointed_thing.type == "node" then
|
||||
if above then
|
||||
-- The position where a node would be placed
|
||||
return pointed_thing.above
|
||||
else
|
||||
-- The position where a node would be dug
|
||||
return pointed_thing.under
|
||||
end
|
||||
elseif pointed_thing.type == "object" then
|
||||
obj = pointed_thing.ref
|
||||
if obj ~= nil then
|
||||
return obj:getpos()
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.dir_to_facedir(dir)
|
||||
if math.abs(dir.x) > math.abs(dir.z) then
|
||||
if dir.x < 0 then
|
||||
return 3
|
||||
else
|
||||
return 1
|
||||
end
|
||||
else
|
||||
if dir.z < 0 then
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.dir_to_wallmounted(dir)
|
||||
if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
|
||||
if dir.y < 0 then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif math.abs(dir.x) > math.abs(dir.z) then
|
||||
if dir.x < 0 then
|
||||
return 3
|
||||
else
|
||||
return 2
|
||||
end
|
||||
else
|
||||
if dir.z < 0 then
|
||||
return 5
|
||||
else
|
||||
return 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.get_node_drops(nodename, toolname)
|
||||
local drop = ItemStack({name=nodename}):get_definition().drop
|
||||
if drop == nil then
|
||||
-- default drop
|
||||
return {ItemStack({name=nodename})}
|
||||
elseif type(drop) == "string" then
|
||||
-- itemstring drop
|
||||
return {ItemStack(drop)}
|
||||
elseif drop.items == nil then
|
||||
-- drop = {} to disable default drop
|
||||
return {}
|
||||
end
|
||||
|
||||
-- Extended drop table
|
||||
local got_items = {}
|
||||
local got_count = 0
|
||||
local _, item, tool
|
||||
for _, item in ipairs(drop.items) do
|
||||
local good_rarity = true
|
||||
local good_tool = true
|
||||
if item.rarity ~= nil then
|
||||
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
|
||||
end
|
||||
if item.tools ~= nil then
|
||||
good_tool = false
|
||||
for _, tool in ipairs(item.tools) do
|
||||
if tool:sub(1, 1) == '~' then
|
||||
good_tool = toolname:find(tool:sub(2)) ~= nil
|
||||
else
|
||||
good_tool = toolname == tool
|
||||
end
|
||||
if good_tool then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if good_rarity and good_tool then
|
||||
got_count = got_count + 1
|
||||
for _, add_item in ipairs(item.items) do
|
||||
got_items[#got_items+1] = add_item
|
||||
end
|
||||
if drop.max_items ~= nil and got_count == drop.max_items then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return got_items
|
||||
end
|
||||
|
||||
function minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||
local item = itemstack:peek_item()
|
||||
local def = itemstack:get_definition()
|
||||
if def.type == "node" and pointed_thing.type == "node" then
|
||||
local pos = pointed_thing.above
|
||||
local oldnode = minetest.env:get_node(pos)
|
||||
local olddef = ItemStack({name=oldnode.name}):get_definition()
|
||||
|
||||
if not olddef.buildable_to then
|
||||
minetest.log("info", placer:get_player_name() .. " tried to place"
|
||||
.. " node in invalid position " .. minetest.pos_to_string(pos)
|
||||
.. ", replacing " .. oldnode.name)
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log("action", placer:get_player_name() .. " places node "
|
||||
.. def.name .. " at " .. minetest.pos_to_string(pos))
|
||||
|
||||
local newnode = {name = def.name, param1 = 0, param2 = 0}
|
||||
|
||||
-- Calculate direction for wall mounted stuff like torches and signs
|
||||
if def.paramtype2 == 'wallmounted' then
|
||||
local under = pointed_thing.under
|
||||
local above = pointed_thing.above
|
||||
local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
|
||||
newnode.param2 = minetest.dir_to_wallmounted(dir)
|
||||
-- Calculate the direction for furnaces and chests and stuff
|
||||
elseif def.paramtype2 == 'facedir' then
|
||||
local playerpos = placer:getpos()
|
||||
local dir = {x = pos.x - playerpos.x, y = pos.y - playerpos.y, z = pos.z - playerpos.z}
|
||||
newnode.param2 = minetest.dir_to_facedir(dir)
|
||||
minetest.log("action", "facedir: " .. newnode.param2)
|
||||
end
|
||||
|
||||
-- Add node and update
|
||||
minetest.env:add_node(pos, newnode)
|
||||
|
||||
-- Set metadata owner
|
||||
if def.metadata_name ~= "" then
|
||||
minetest.env:get_meta(pos):set_owner(placer:get_player_name())
|
||||
end
|
||||
|
||||
-- Run script hook
|
||||
local _, callback
|
||||
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
||||
callback(pos, newnode, placer)
|
||||
end
|
||||
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function minetest.item_place_object(itemstack, placer, pointed_thing)
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
|
||||
if pos ~= nil then
|
||||
local item = itemstack:take_item()
|
||||
minetest.env:add_item(pos, item)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function minetest.item_place(itemstack, placer, pointed_thing)
|
||||
if itemstack:get_definition().type == "node" then
|
||||
return minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||
else
|
||||
return minetest.item_place_object(itemstack, placer, pointed_thing)
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.item_drop(itemstack, dropper, pos)
|
||||
minetest.env:add_item(pos, itemstack)
|
||||
return ""
|
||||
end
|
||||
|
||||
function minetest.item_eat(hp_change, replace_with_item)
|
||||
return function(itemstack, user, pointed_thing) -- closure
|
||||
if itemstack:take_item() ~= nil then
|
||||
user:set_hp(user:get_hp() + hp_change)
|
||||
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.node_punch(pos, node, puncher)
|
||||
-- Run script hook
|
||||
local _, callback
|
||||
for _, callback in ipairs(minetest.registered_on_punchnodes) do
|
||||
callback(pos, node, puncher)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function minetest.node_dig(pos, node, digger)
|
||||
minetest.debug("node_dig")
|
||||
|
||||
local def = ItemStack({name=node.name}):get_definition()
|
||||
if not def.diggable then
|
||||
minetest.debug("not diggable")
|
||||
minetest.log("info", digger:get_player_name() .. " tried to dig "
|
||||
.. node.name .. " which is not diggable "
|
||||
.. minetest.pos_to_string(pos))
|
||||
return
|
||||
end
|
||||
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
if meta ~= nil and not meta:get_allow_removal() then
|
||||
minetest.debug("dig prevented by metadata")
|
||||
minetest.log("info", digger:get_player_name() .. " tried to dig "
|
||||
.. node.name .. ", but removal is disabled by metadata "
|
||||
.. minetest.pos_to_string(pos))
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log('action', digger:get_player_name() .. " digs "
|
||||
.. node.name .. " at " .. minetest.pos_to_string(pos))
|
||||
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
local wielded = digger:get_wielded_item()
|
||||
local drops = minetest.get_node_drops(node.name, wielded:get_name())
|
||||
|
||||
-- Wear out tool
|
||||
tp = wielded:get_tool_capabilities()
|
||||
dp = minetest.get_dig_params(def.groups, tp)
|
||||
wielded:add_wear(dp.wear)
|
||||
digger:set_wielded_item(wielded)
|
||||
|
||||
-- Add dropped items
|
||||
local _, dropped_item
|
||||
for _, dropped_item in ipairs(drops) do
|
||||
digger:get_inventory():add_item("main", dropped_item)
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove node and update
|
||||
minetest.env:remove_node(pos)
|
||||
|
||||
-- Run script hook
|
||||
local _, callback
|
||||
for _, callback in ipairs(minetest.registered_on_dignodes) do
|
||||
callback(pos, node, digger)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Item definition defaults
|
||||
--
|
||||
|
||||
minetest.nodedef_default = {
|
||||
-- Item properties
|
||||
type="node",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 99,
|
||||
usable = false,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = minetest.item_place,
|
||||
on_drop = minetest.item_drop,
|
||||
on_use = nil,
|
||||
|
||||
on_punch = minetest.node_punch,
|
||||
on_dig = minetest.node_dig,
|
||||
|
||||
-- Node properties
|
||||
drawtype = "normal",
|
||||
visual_scale = 1.0,
|
||||
tile_images = {""},
|
||||
special_materials = {
|
||||
{image="", backface_culling=true},
|
||||
{image="", backface_culling=true},
|
||||
},
|
||||
alpha = 255,
|
||||
post_effect_color = {a=0, r=0, g=0, b=0},
|
||||
paramtype = "none",
|
||||
paramtype2 = "none",
|
||||
is_ground_content = false,
|
||||
sunlight_propagates = false,
|
||||
walkable = true,
|
||||
pointable = true,
|
||||
diggable = true,
|
||||
climbable = false,
|
||||
buildable_to = false,
|
||||
metadata_name = "",
|
||||
liquidtype = "none",
|
||||
liquid_alternative_flowing = "",
|
||||
liquid_alternative_source = "",
|
||||
liquid_viscosity = 0,
|
||||
light_source = 0,
|
||||
damage_per_second = 0,
|
||||
selection_box = {type="regular"},
|
||||
legacy_facedir_simple = false,
|
||||
legacy_wallmounted = false,
|
||||
}
|
||||
|
||||
minetest.craftitemdef_default = {
|
||||
type="craft",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 99,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = minetest.item_place,
|
||||
on_drop = minetest.item_drop,
|
||||
on_use = nil,
|
||||
}
|
||||
|
||||
minetest.tooldef_default = {
|
||||
type="tool",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 1,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = minetest.item_place,
|
||||
on_drop = minetest.item_drop,
|
||||
on_use = nil,
|
||||
}
|
||||
|
||||
minetest.noneitemdef_default = { -- This is used for the hand and unknown items
|
||||
type="none",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 99,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = nil,
|
||||
on_drop = nil,
|
||||
on_use = nil,
|
||||
}
|
||||
|
||||
--
|
||||
-- Make raw registration functions inaccessible to anyone except builtin.lua
|
||||
--
|
||||
|
||||
local register_item_raw = minetest.register_item_raw
|
||||
minetest.register_item_raw = nil
|
||||
|
||||
local register_alias_raw = minetest.register_alias_raw
|
||||
minetest.register_item_raw = nil
|
||||
|
||||
--
|
||||
-- Item / entity / ABM registration functions
|
||||
--
|
||||
|
||||
minetest.registered_abms = {}
|
||||
minetest.registered_entities = {}
|
||||
minetest.registered_items = {}
|
||||
minetest.registered_nodes = {}
|
||||
minetest.registered_craftitems = {}
|
||||
minetest.registered_tools = {}
|
||||
minetest.registered_aliases = {}
|
||||
|
||||
-- For tables that are indexed by item name:
|
||||
-- If table[X] does not exist, default to table[minetest.registered_aliases[X]]
|
||||
local function set_alias_metatable(table)
|
||||
setmetatable(table, {
|
||||
__index = function(name)
|
||||
return rawget(table, minetest.registered_aliases[name])
|
||||
end
|
||||
})
|
||||
end
|
||||
set_alias_metatable(minetest.registered_items)
|
||||
set_alias_metatable(minetest.registered_nodes)
|
||||
set_alias_metatable(minetest.registered_craftitems)
|
||||
set_alias_metatable(minetest.registered_tools)
|
||||
|
||||
-- These item names may not be used because they would interfere
|
||||
-- with legacy itemstrings
|
||||
local forbidden_item_names = {
|
||||
MaterialItem = true,
|
||||
MaterialItem2 = true,
|
||||
MaterialItem3 = true,
|
||||
NodeItem = true,
|
||||
node = true,
|
||||
CraftItem = true,
|
||||
craft = true,
|
||||
MBOItem = true,
|
||||
ToolItem = true,
|
||||
tool = true,
|
||||
}
|
||||
|
||||
local function check_modname_prefix(name)
|
||||
if name:sub(1,1) == ":" then
|
||||
-- Escape the modname prefix enforcement mechanism
|
||||
return name:sub(2)
|
||||
else
|
||||
-- Modname prefix enforcement
|
||||
local expected_prefix = minetest.get_current_modname() .. ":"
|
||||
if name:sub(1, #expected_prefix) ~= expected_prefix then
|
||||
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||
"\"modname:\" or \":\" prefix required")
|
||||
end
|
||||
local subname = name:sub(#expected_prefix+1)
|
||||
if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
|
||||
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||
"contains unallowed characters")
|
||||
end
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.register_abm(spec)
|
||||
-- Add to minetest.registered_abms
|
||||
minetest.registered_abms[#minetest.registered_abms+1] = spec
|
||||
end
|
||||
|
||||
function minetest.register_entity(name, prototype)
|
||||
-- Check name
|
||||
if name == nil then
|
||||
error("Unable to register entity: Name is nil")
|
||||
end
|
||||
name = check_modname_prefix(tostring(name))
|
||||
|
||||
prototype.name = name
|
||||
prototype.__index = prototype -- so that it can be used as a metatable
|
||||
|
||||
-- Add to minetest.registered_entities
|
||||
minetest.registered_entities[name] = prototype
|
||||
end
|
||||
|
||||
function minetest.register_item(name, itemdef)
|
||||
-- Check name
|
||||
if name == nil then
|
||||
error("Unable to register item: Name is nil")
|
||||
end
|
||||
name = check_modname_prefix(tostring(name))
|
||||
if forbidden_item_names[name] then
|
||||
error("Unable to register item: Name is forbidden: " .. name)
|
||||
end
|
||||
itemdef.name = name
|
||||
|
||||
-- Apply defaults and add to registered_* table
|
||||
if itemdef.type == "node" then
|
||||
setmetatable(itemdef, {__index = minetest.nodedef_default})
|
||||
minetest.registered_nodes[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "craft" then
|
||||
setmetatable(itemdef, {__index = minetest.craftitemdef_default})
|
||||
minetest.registered_craftitems[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "tool" then
|
||||
setmetatable(itemdef, {__index = minetest.tooldef_default})
|
||||
minetest.registered_tools[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "none" then
|
||||
setmetatable(itemdef, {__index = minetest.noneitemdef_default})
|
||||
else
|
||||
error("Unable to register item: Type is invalid: " .. dump(itemdef))
|
||||
end
|
||||
|
||||
-- Flowing liquid uses param2
|
||||
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
|
||||
itemdef.paramtype2 = "flowingliquid"
|
||||
end
|
||||
|
||||
-- BEGIN Legacy stuff
|
||||
if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then
|
||||
minetest.register_craft({
|
||||
type="cooking",
|
||||
output=itemdef.cookresult_itemstring,
|
||||
recipe=itemdef.name,
|
||||
cooktime=itemdef.furnace_cooktime
|
||||
})
|
||||
end
|
||||
if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then
|
||||
minetest.register_craft({
|
||||
type="fuel",
|
||||
recipe=itemdef.name,
|
||||
burntime=itemdef.furnace_burntime
|
||||
})
|
||||
end
|
||||
-- END Legacy stuff
|
||||
|
||||
-- Disable all further modifications
|
||||
getmetatable(itemdef).__newindex = {}
|
||||
|
||||
--minetest.log("Registering item: " .. itemdef.name)
|
||||
minetest.registered_items[itemdef.name] = itemdef
|
||||
minetest.registered_aliases[itemdef.name] = nil
|
||||
register_item_raw(itemdef)
|
||||
end
|
||||
|
||||
function minetest.register_node(name, nodedef)
|
||||
nodedef.type = "node"
|
||||
minetest.register_item(name, nodedef)
|
||||
end
|
||||
|
||||
function minetest.register_craftitem(name, craftitemdef)
|
||||
craftitemdef.type = "craft"
|
||||
|
||||
-- BEGIN Legacy stuff
|
||||
if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then
|
||||
craftitemdef.inventory_image = craftitemdef.image
|
||||
end
|
||||
-- END Legacy stuff
|
||||
|
||||
minetest.register_item(name, craftitemdef)
|
||||
end
|
||||
|
||||
function minetest.register_tool(name, tooldef)
|
||||
tooldef.type = "tool"
|
||||
tooldef.stack_max = 1
|
||||
|
||||
-- BEGIN Legacy stuff
|
||||
if tooldef.inventory_image == nil and tooldef.image ~= nil then
|
||||
tooldef.inventory_image = tooldef.image
|
||||
end
|
||||
if tooldef.tool_capabilities == nil and
|
||||
(tooldef.full_punch_interval ~= nil or
|
||||
tooldef.basetime ~= nil or
|
||||
tooldef.dt_weight ~= nil or
|
||||
tooldef.dt_crackiness ~= nil or
|
||||
tooldef.dt_crumbliness ~= nil or
|
||||
tooldef.dt_cuttability ~= nil or
|
||||
tooldef.basedurability ~= nil or
|
||||
tooldef.dd_weight ~= nil or
|
||||
tooldef.dd_crackiness ~= nil or
|
||||
tooldef.dd_crumbliness ~= nil or
|
||||
tooldef.dd_cuttability ~= nil) then
|
||||
tooldef.tool_capabilities = {
|
||||
full_punch_interval = tooldef.full_punch_interval,
|
||||
basetime = tooldef.basetime,
|
||||
dt_weight = tooldef.dt_weight,
|
||||
dt_crackiness = tooldef.dt_crackiness,
|
||||
dt_crumbliness = tooldef.dt_crumbliness,
|
||||
dt_cuttability = tooldef.dt_cuttability,
|
||||
basedurability = tooldef.basedurability,
|
||||
dd_weight = tooldef.dd_weight,
|
||||
dd_crackiness = tooldef.dd_crackiness,
|
||||
dd_crumbliness = tooldef.dd_crumbliness,
|
||||
dd_cuttability = tooldef.dd_cuttability,
|
||||
}
|
||||
end
|
||||
-- END Legacy stuff
|
||||
|
||||
minetest.register_item(name, tooldef)
|
||||
end
|
||||
|
||||
function minetest.register_alias(name, convert_to)
|
||||
if forbidden_item_names[name] then
|
||||
error("Unable to register alias: Name is forbidden: " .. name)
|
||||
end
|
||||
if minetest.registered_items[name] ~= nil then
|
||||
minetest.log("WARNING: Not registering alias, item with same name" ..
|
||||
" is already defined: " .. name .. " -> " .. convert_to)
|
||||
else
|
||||
--minetest.log("Registering alias: " .. name .. " -> " .. convert_to)
|
||||
minetest.registered_aliases[name] = convert_to
|
||||
register_alias_raw(name, convert_to)
|
||||
end
|
||||
end
|
||||
|
||||
-- Alias the forbidden item names to "" so they can't be
|
||||
-- created via itemstrings (e.g. /give)
|
||||
local name
|
||||
for name in pairs(forbidden_item_names) do
|
||||
minetest.registered_aliases[name] = ""
|
||||
register_alias_raw(name, "")
|
||||
end
|
||||
|
||||
|
||||
-- Deprecated:
|
||||
-- Aliases for minetest.register_alias (how ironic...)
|
||||
--minetest.alias_node = minetest.register_alias
|
||||
--minetest.alias_tool = minetest.register_alias
|
||||
--minetest.alias_craftitem = minetest.register_alias
|
||||
|
||||
--
|
||||
-- Built-in node definitions. Also defined in C.
|
||||
--
|
||||
|
||||
minetest.register_item(":unknown", {
|
||||
type = "none",
|
||||
description = "Unknown Item",
|
||||
inventory_image = "unknown_item.png",
|
||||
on_place = minetest.item_place,
|
||||
on_drop = minetest.item_drop,
|
||||
})
|
||||
|
||||
minetest.register_node(":air", {
|
||||
description = "Air (you hacker you!)",
|
||||
inventory_image = "unknown_block.png",
|
||||
wield_image = "unknown_block.png",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
air_equivalent = true,
|
||||
})
|
||||
|
||||
minetest.register_node(":ignore", {
|
||||
description = "Ignore (you hacker you!)",
|
||||
inventory_image = "unknown_block.png",
|
||||
wield_image = "unknown_block.png",
|
||||
drawtype = "airlike",
|
||||
paramtype = "none",
|
||||
sunlight_propagates = false,
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true, -- A way to remove accidentally placed ignores
|
||||
air_equivalent = true,
|
||||
})
|
||||
|
||||
-- The hand (bare definition)
|
||||
minetest.register_item(":", {
|
||||
type = "none",
|
||||
})
|
||||
|
||||
--
|
||||
-- Default material types
|
||||
--
|
||||
function digprop_err()
|
||||
minetest.log("info", debug.traceback())
|
||||
minetest.log("info", "WARNING: The minetest.digprop_* functions are obsolete and need to be replaced by item groups.")
|
||||
end
|
||||
|
||||
minetest.digprop_constanttime = digprop_err
|
||||
minetest.digprop_stonelike = digprop_err
|
||||
minetest.digprop_dirtlike = digprop_err
|
||||
minetest.digprop_gravellike = digprop_err
|
||||
minetest.digprop_woodlike = digprop_err
|
||||
minetest.digprop_leaveslike = digprop_err
|
||||
minetest.digprop_glasslike = digprop_err
|
||||
|
||||
--
|
||||
-- Creative inventory
|
||||
--
|
||||
|
||||
minetest.creative_inventory = {}
|
||||
|
||||
minetest.add_to_creative_inventory = function(itemstring)
|
||||
table.insert(minetest.creative_inventory, itemstring)
|
||||
end
|
||||
|
||||
--
|
||||
-- Callback registration
|
||||
--
|
||||
|
||||
local function make_registration()
|
||||
local t = {}
|
||||
local registerfunc = function(func) table.insert(t, func) end
|
||||
return t, registerfunc
|
||||
end
|
||||
|
||||
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
|
||||
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
|
||||
minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
|
||||
minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
|
||||
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
|
||||
minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
|
||||
minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
|
||||
minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registration()
|
||||
minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
|
||||
|
||||
--
|
||||
-- Set random seed
|
||||
--
|
||||
|
||||
math.randomseed(os.time())
|
||||
|
||||
-- END
|
||||
-- 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")
|
||||
dofile(minetest.get_modpath("__builtin").."/item_entity.lua")
|
||||
dofile(minetest.get_modpath("__builtin").."/deprecated.lua")
|
||||
dofile(minetest.get_modpath("__builtin").."/misc.lua")
|
||||
dofile(minetest.get_modpath("__builtin").."/privileges.lua")
|
||||
dofile(minetest.get_modpath("__builtin").."/auth.lua")
|
||||
dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
|
||||
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")
|
||||
|
||||
|
||||
353
builtin/chatcommands.lua
Normal file
353
builtin/chatcommands.lua
Normal file
@@ -0,0 +1,353 @@
|
||||
-- Minetest: builtin/chatcommands.lua
|
||||
|
||||
--
|
||||
-- Chat command handler
|
||||
--
|
||||
|
||||
minetest.chatcommands = {}
|
||||
function minetest.register_chatcommand(cmd, def)
|
||||
def = def or {}
|
||||
def.params = def.params or ""
|
||||
def.description = def.description or ""
|
||||
def.privs = def.privs or {}
|
||||
minetest.chatcommands[cmd] = def
|
||||
end
|
||||
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
|
||||
if not param then
|
||||
param = ""
|
||||
end
|
||||
local cmd_def = minetest.chatcommands[cmd]
|
||||
if cmd_def then
|
||||
if not cmd_def.func then
|
||||
-- This is a C++ command
|
||||
return false
|
||||
else
|
||||
local has_privs, missing_privs = minetest.check_player_privs(name, cmd_def.privs)
|
||||
if has_privs then
|
||||
cmd_def.func(name, param)
|
||||
else
|
||||
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
|
||||
end
|
||||
return true -- handled chat message
|
||||
end
|
||||
end
|
||||
return false
|
||||
end)
|
||||
|
||||
--
|
||||
-- Chat commands
|
||||
--
|
||||
|
||||
-- Register C++ commands without functions
|
||||
minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)"})
|
||||
minetest.register_chatcommand("status", {description = "print server status line"})
|
||||
minetest.register_chatcommand("shutdown", {params = "", description = "shutdown server", privs = {server=true}})
|
||||
minetest.register_chatcommand("clearobjects", {params = "", description = "clear all objects in world", privs = {server=true}})
|
||||
minetest.register_chatcommand("time", {params = "<0...24000>", description = "set time of day", privs = {settime=true}})
|
||||
minetest.register_chatcommand("ban", {params = "<name>", description = "ban IP of player", privs = {ban=true}})
|
||||
minetest.register_chatcommand("unban", {params = "<name/ip>", description = "remove IP ban", privs = {ban=true}})
|
||||
|
||||
-- Register other commands
|
||||
minetest.register_chatcommand("help", {
|
||||
privs = {},
|
||||
params = "(nothing)/all/privs/<cmd>",
|
||||
description = "Get help for commands or list privileges",
|
||||
func = function(name, param)
|
||||
local format_help_line = function(cmd, def)
|
||||
local msg = "/"..cmd
|
||||
if def.params and def.params ~= "" then msg = msg .. " " .. def.params end
|
||||
if def.description and def.description ~= "" then msg = msg .. ": " .. def.description end
|
||||
return msg
|
||||
end
|
||||
if param == "" then
|
||||
local msg = ""
|
||||
cmds = {}
|
||||
for cmd, def in pairs(minetest.chatcommands) do
|
||||
if minetest.check_player_privs(name, def.privs) then
|
||||
table.insert(cmds, cmd)
|
||||
end
|
||||
end
|
||||
minetest.chat_send_player(name, "Available commands: "..table.concat(cmds, " "))
|
||||
minetest.chat_send_player(name, "Use '/help <cmd>' to get more information, or '/help all' to list everything.")
|
||||
elseif param == "all" then
|
||||
minetest.chat_send_player(name, "Available commands:")
|
||||
for cmd, def in pairs(minetest.chatcommands) do
|
||||
if minetest.check_player_privs(name, def.privs) then
|
||||
minetest.chat_send_player(name, format_help_line(cmd, def))
|
||||
end
|
||||
end
|
||||
elseif param == "privs" then
|
||||
minetest.chat_send_player(name, "Available privileges:")
|
||||
for priv, def in pairs(minetest.registered_privileges) do
|
||||
minetest.chat_send_player(name, priv..": "..def.description)
|
||||
end
|
||||
else
|
||||
local cmd = param
|
||||
def = minetest.chatcommands[cmd]
|
||||
if not def then
|
||||
minetest.chat_send_player(name, "Command not available: "..cmd)
|
||||
else
|
||||
minetest.chat_send_player(name, format_help_line(cmd, def))
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
minetest.register_chatcommand("privs", {
|
||||
params = "<name>",
|
||||
description = "print out privileges of player",
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
param = name
|
||||
else
|
||||
--[[if not minetest.check_player_privs(name, {privs=true}) then
|
||||
minetest.chat_send_player(name, "Privileges of "..param.." are hidden from you.")
|
||||
return
|
||||
end]]
|
||||
end
|
||||
minetest.chat_send_player(name, "Privileges of "..param..": "..minetest.privs_to_string(minetest.get_player_privs(param), ' '))
|
||||
end,
|
||||
})
|
||||
minetest.register_chatcommand("grant", {
|
||||
params = "<name> <privilege>|all",
|
||||
description = "Give privilege to player",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
if not minetest.check_player_privs(name, {privs=true}) and
|
||||
not minetest.check_player_privs(name, {basic_privs=true}) then
|
||||
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||
return
|
||||
end
|
||||
local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
|
||||
if not grantname or not grantprivstr then
|
||||
minetest.chat_send_player(name, "Invalid parameters (see /help grant)")
|
||||
return
|
||||
end
|
||||
local grantprivs = minetest.string_to_privs(grantprivstr)
|
||||
if grantprivstr == "all" then
|
||||
grantprivs = minetest.registered_privileges
|
||||
end
|
||||
local privs = minetest.get_player_privs(grantname)
|
||||
local privs_known = true
|
||||
for priv, _ in pairs(grantprivs) do
|
||||
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
|
||||
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||
return
|
||||
end
|
||||
if not minetest.registered_privileges[priv] then
|
||||
minetest.chat_send_player(name, "Unknown privilege: "..priv)
|
||||
privs_known = false
|
||||
end
|
||||
privs[priv] = true
|
||||
end
|
||||
if not privs_known then
|
||||
return
|
||||
end
|
||||
minetest.set_player_privs(grantname, privs)
|
||||
minetest.chat_send_player(name, "Privileges of "..grantname..": "..minetest.privs_to_string(minetest.get_player_privs(grantname), ' '))
|
||||
if grantname ~= name then
|
||||
minetest.chat_send_player(grantname, name.." granted you privileges: "..minetest.privs_to_string(grantprivs, ' '))
|
||||
end
|
||||
end,
|
||||
})
|
||||
minetest.register_chatcommand("revoke", {
|
||||
params = "<name> <privilege>|all",
|
||||
description = "Remove privilege from player",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
if not minetest.check_player_privs(name, {privs=true}) and
|
||||
not minetest.check_player_privs(name, {basic_privs=true}) then
|
||||
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||
return
|
||||
end
|
||||
local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)")
|
||||
if not revokename or not revokeprivstr then
|
||||
minetest.chat_send_player(name, "Invalid parameters (see /help revoke)")
|
||||
return
|
||||
end
|
||||
local revokeprivs = minetest.string_to_privs(revokeprivstr)
|
||||
local privs = minetest.get_player_privs(revokename)
|
||||
for priv, _ in pairs(revokeprivs) do
|
||||
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
|
||||
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||
return
|
||||
end
|
||||
end
|
||||
if revokeprivstr == "all" then
|
||||
privs = {}
|
||||
else
|
||||
for priv, _ in pairs(revokeprivs) do
|
||||
privs[priv] = nil
|
||||
end
|
||||
end
|
||||
minetest.set_player_privs(revokename, privs)
|
||||
minetest.chat_send_player(name, "Privileges of "..revokename..": "..minetest.privs_to_string(minetest.get_player_privs(revokename), ' '))
|
||||
if revokename ~= name then
|
||||
minetest.chat_send_player(revokename, name.." revoked privileges from you: "..minetest.privs_to_string(revokeprivs, ' '))
|
||||
end
|
||||
end,
|
||||
})
|
||||
minetest.register_chatcommand("setpassword", {
|
||||
params = "<name> <password>",
|
||||
description = "set given password",
|
||||
privs = {password=true},
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
minetest.chat_send_player(name, "Password field required")
|
||||
return
|
||||
end
|
||||
minetest.set_player_password(name, param)
|
||||
minetest.chat_send_player(name, "Password set")
|
||||
end,
|
||||
})
|
||||
minetest.register_chatcommand("clearpassword", {
|
||||
params = "<name>",
|
||||
description = "set empty password",
|
||||
privs = {password=true},
|
||||
func = function(name, param)
|
||||
minetest.set_player_password(name, '')
|
||||
minetest.chat_send_player(name, "Password cleared")
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("auth_reload", {
|
||||
params = "",
|
||||
description = "reload authentication data",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local done = minetest.auth_reload()
|
||||
if done then
|
||||
minetest.chat_send_player(name, "Done.")
|
||||
else
|
||||
minetest.chat_send_player(name, "Failed.")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("teleport", {
|
||||
params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
|
||||
description = "teleport to given position",
|
||||
privs = {teleport=true},
|
||||
func = function(name, param)
|
||||
-- Returns (pos, true) if found, otherwise (pos, false)
|
||||
local function find_free_position_near(pos)
|
||||
local tries = {
|
||||
{x=1,y=0,z=0},
|
||||
{x=-1,y=0,z=0},
|
||||
{x=0,y=0,z=1},
|
||||
{x=0,y=0,z=-1},
|
||||
}
|
||||
for _, d in ipairs(tries) do
|
||||
local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z}
|
||||
local n = minetest.env:get_node(p)
|
||||
if not minetest.registered_nodes[n.name].walkable then
|
||||
return p, true
|
||||
end
|
||||
end
|
||||
return pos, false
|
||||
end
|
||||
|
||||
local teleportee = nil
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||
teleportee = minetest.env:get_player_by_name(name)
|
||||
if teleportee and p.x and p.y and p.z then
|
||||
minetest.chat_send_player(name, "Teleporting to ("..p.x..", "..p.y..", "..p.z..")")
|
||||
teleportee:setpos(p)
|
||||
return
|
||||
end
|
||||
|
||||
local teleportee = nil
|
||||
local p = nil
|
||||
local target_name = nil
|
||||
target_name = string.match(param, "^([^ ]+)$")
|
||||
teleportee = minetest.env:get_player_by_name(name)
|
||||
if target_name then
|
||||
local target = minetest.env:get_player_by_name(target_name)
|
||||
if target then
|
||||
p = target:getpos()
|
||||
end
|
||||
end
|
||||
if teleportee and p then
|
||||
p = find_free_position_near(p)
|
||||
minetest.chat_send_player(name, "Teleporting to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
|
||||
teleportee:setpos(p)
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.check_player_privs(name, {bring=true}) then
|
||||
local teleportee = nil
|
||||
local p = {}
|
||||
local teleportee_name = nil
|
||||
teleportee_name, p.x, p.y, p.z = string.match(param, "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||
if teleportee_name then
|
||||
teleportee = minetest.env:get_player_by_name(teleportee_name)
|
||||
end
|
||||
if teleportee and p.x and p.y and p.z then
|
||||
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to ("..p.x..", "..p.y..", "..p.z..")")
|
||||
teleportee:setpos(p)
|
||||
return
|
||||
end
|
||||
|
||||
local teleportee = nil
|
||||
local p = nil
|
||||
local teleportee_name = nil
|
||||
local target_name = nil
|
||||
teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$")
|
||||
if teleportee_name then
|
||||
teleportee = minetest.env:get_player_by_name(teleportee_name)
|
||||
end
|
||||
if target_name then
|
||||
local target = minetest.env:get_player_by_name(target_name)
|
||||
if target then
|
||||
p = target:getpos()
|
||||
end
|
||||
end
|
||||
if teleportee and p then
|
||||
p = find_free_position_near(p)
|
||||
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
|
||||
teleportee:setpos(p)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
minetest.chat_send_player(name, "Invalid parameters (\""..param.."\") or player not found (see /help teleport)")
|
||||
return
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("set", {
|
||||
params = "[-n] <name> <value> | <name>",
|
||||
description = "set or read server configuration setting",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
|
||||
if arg and arg == "-n" and setname and setvalue then
|
||||
minetest.setting_set(setname, setvalue)
|
||||
minetest.chat_send_player(name, setname.." = "..setvalue)
|
||||
return
|
||||
end
|
||||
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
|
||||
if setname and setvalue then
|
||||
if not minetest.setting_get(setname) then
|
||||
minetest.chat_send_player(name, "Failed. Use '/set -n <name> <value>' to create a new setting.")
|
||||
return
|
||||
end
|
||||
minetest.setting_set(setname, setvalue)
|
||||
minetest.chat_send_player(name, setname.." = "..setvalue)
|
||||
return
|
||||
end
|
||||
local setname = string.match(param, "([^ ]+)")
|
||||
if setname then
|
||||
local setvalue = minetest.setting_get(setname)
|
||||
if not setvalue then
|
||||
setvalue = "<not set>"
|
||||
end
|
||||
minetest.chat_send_player(name, setname.." = "..setvalue)
|
||||
return
|
||||
end
|
||||
minetest.chat_send_player(name, "Invalid parameters (see /help set)")
|
||||
end,
|
||||
})
|
||||
|
||||
19
builtin/deprecated.lua
Normal file
19
builtin/deprecated.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
-- Minetest: builtin/deprecated.lua
|
||||
|
||||
--
|
||||
-- Default material types
|
||||
--
|
||||
function digprop_err()
|
||||
minetest.log("info", debug.traceback())
|
||||
minetest.log("info", "WARNING: The minetest.digprop_* functions are obsolete and need to be replaced by item groups.")
|
||||
end
|
||||
|
||||
minetest.digprop_constanttime = digprop_err
|
||||
minetest.digprop_stonelike = digprop_err
|
||||
minetest.digprop_dirtlike = digprop_err
|
||||
minetest.digprop_gravellike = digprop_err
|
||||
minetest.digprop_woodlike = digprop_err
|
||||
minetest.digprop_leaveslike = digprop_err
|
||||
minetest.digprop_glasslike = digprop_err
|
||||
|
||||
|
||||
444
builtin/item.lua
Normal file
444
builtin/item.lua
Normal file
@@ -0,0 +1,444 @@
|
||||
-- Minetest: builtin/item.lua
|
||||
|
||||
--
|
||||
-- Item definition helpers
|
||||
--
|
||||
|
||||
function minetest.inventorycube(img1, img2, img3)
|
||||
img2 = img2 or img1
|
||||
img3 = img3 or img1
|
||||
return "[inventorycube"
|
||||
.. "{" .. img1:gsub("%^", "&")
|
||||
.. "{" .. img2:gsub("%^", "&")
|
||||
.. "{" .. img3:gsub("%^", "&")
|
||||
end
|
||||
|
||||
function minetest.get_pointed_thing_position(pointed_thing, above)
|
||||
if pointed_thing.type == "node" then
|
||||
if above then
|
||||
-- The position where a node would be placed
|
||||
return pointed_thing.above
|
||||
else
|
||||
-- The position where a node would be dug
|
||||
return pointed_thing.under
|
||||
end
|
||||
elseif pointed_thing.type == "object" then
|
||||
obj = pointed_thing.ref
|
||||
if obj ~= nil then
|
||||
return obj:getpos()
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.dir_to_facedir(dir)
|
||||
if math.abs(dir.x) > math.abs(dir.z) then
|
||||
if dir.x < 0 then
|
||||
return 3
|
||||
else
|
||||
return 1
|
||||
end
|
||||
else
|
||||
if dir.z < 0 then
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.dir_to_wallmounted(dir)
|
||||
if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
|
||||
if dir.y < 0 then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif math.abs(dir.x) > math.abs(dir.z) then
|
||||
if dir.x < 0 then
|
||||
return 3
|
||||
else
|
||||
return 2
|
||||
end
|
||||
else
|
||||
if dir.z < 0 then
|
||||
return 5
|
||||
else
|
||||
return 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.get_node_drops(nodename, toolname)
|
||||
local drop = ItemStack({name=nodename}):get_definition().drop
|
||||
if drop == nil then
|
||||
-- default drop
|
||||
return {ItemStack({name=nodename})}
|
||||
elseif type(drop) == "string" then
|
||||
-- itemstring drop
|
||||
return {ItemStack(drop)}
|
||||
elseif drop.items == nil then
|
||||
-- drop = {} to disable default drop
|
||||
return {}
|
||||
end
|
||||
|
||||
-- Extended drop table
|
||||
local got_items = {}
|
||||
local got_count = 0
|
||||
local _, item, tool
|
||||
for _, item in ipairs(drop.items) do
|
||||
local good_rarity = true
|
||||
local good_tool = true
|
||||
if item.rarity ~= nil then
|
||||
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
|
||||
end
|
||||
if item.tools ~= nil then
|
||||
good_tool = false
|
||||
for _, tool in ipairs(item.tools) do
|
||||
if tool:sub(1, 1) == '~' then
|
||||
good_tool = toolname:find(tool:sub(2)) ~= nil
|
||||
else
|
||||
good_tool = toolname == tool
|
||||
end
|
||||
if good_tool then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if good_rarity and good_tool then
|
||||
got_count = got_count + 1
|
||||
for _, add_item in ipairs(item.items) do
|
||||
got_items[#got_items+1] = add_item
|
||||
end
|
||||
if drop.max_items ~= nil and got_count == drop.max_items then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return got_items
|
||||
end
|
||||
|
||||
function minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||
local item = itemstack:peek_item()
|
||||
local def = itemstack:get_definition()
|
||||
if def.type == "node" and pointed_thing.type == "node" then
|
||||
local pos = pointed_thing.above
|
||||
local oldnode = minetest.env:get_node(pos)
|
||||
local olddef = ItemStack({name=oldnode.name}):get_definition()
|
||||
|
||||
if not olddef.buildable_to then
|
||||
minetest.log("info", placer:get_player_name() .. " tried to place"
|
||||
.. " node in invalid position " .. minetest.pos_to_string(pos)
|
||||
.. ", replacing " .. oldnode.name)
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log("action", placer:get_player_name() .. " places node "
|
||||
.. def.name .. " at " .. minetest.pos_to_string(pos))
|
||||
|
||||
local newnode = {name = def.name, param1 = 0, param2 = 0}
|
||||
|
||||
-- Calculate direction for wall mounted stuff like torches and signs
|
||||
if def.paramtype2 == 'wallmounted' then
|
||||
local under = pointed_thing.under
|
||||
local above = pointed_thing.above
|
||||
local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
|
||||
newnode.param2 = minetest.dir_to_wallmounted(dir)
|
||||
-- Calculate the direction for furnaces and chests and stuff
|
||||
elseif def.paramtype2 == 'facedir' then
|
||||
local playerpos = placer:getpos()
|
||||
local dir = {x = pos.x - playerpos.x, y = pos.y - playerpos.y, z = pos.z - playerpos.z}
|
||||
newnode.param2 = minetest.dir_to_facedir(dir)
|
||||
minetest.log("action", "facedir: " .. newnode.param2)
|
||||
end
|
||||
|
||||
-- Add node and update
|
||||
minetest.env:add_node(pos, newnode)
|
||||
|
||||
-- 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
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function minetest.item_place_object(itemstack, placer, pointed_thing)
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
|
||||
if pos ~= nil then
|
||||
local item = itemstack:take_item()
|
||||
minetest.env:add_item(pos, item)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function minetest.item_place(itemstack, placer, pointed_thing)
|
||||
if itemstack:get_definition().type == "node" then
|
||||
return minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||
else
|
||||
return minetest.item_place_object(itemstack, placer, pointed_thing)
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.item_drop(itemstack, dropper, pos)
|
||||
if dropper.get_player_name then
|
||||
local v = dropper:get_look_dir()
|
||||
local p = {x=pos.x+v.x, y=pos.y+1.5+v.y, z=pos.z+v.z}
|
||||
local obj = minetest.env:add_item(p, itemstack)
|
||||
v.x = v.x*2
|
||||
v.y = v.y*2 + 1
|
||||
v.z = v.z*2
|
||||
obj:setvelocity(v)
|
||||
else
|
||||
minetest.env:add_item(pos, itemstack)
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
function minetest.item_eat(hp_change, replace_with_item)
|
||||
return function(itemstack, user, pointed_thing) -- closure
|
||||
if itemstack:take_item() ~= nil then
|
||||
user:set_hp(user:get_hp() + hp_change)
|
||||
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.node_punch(pos, node, puncher)
|
||||
-- Run script hook
|
||||
local _, callback
|
||||
for _, callback in ipairs(minetest.registered_on_punchnodes) do
|
||||
callback(pos, node, puncher)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function minetest.node_dig(pos, node, digger)
|
||||
minetest.debug("node_dig")
|
||||
|
||||
local def = ItemStack({name=node.name}):get_definition()
|
||||
if not def.diggable or (def.can_dig and not def.can_dig(pos,digger)) then
|
||||
minetest.debug("not diggable")
|
||||
minetest.log("info", digger:get_player_name() .. " tried to dig "
|
||||
.. node.name .. " which is not diggable "
|
||||
.. minetest.pos_to_string(pos))
|
||||
return
|
||||
end
|
||||
|
||||
minetest.log('action', digger:get_player_name() .. " digs "
|
||||
.. node.name .. " at " .. minetest.pos_to_string(pos))
|
||||
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
local wielded = digger:get_wielded_item()
|
||||
local drops = minetest.get_node_drops(node.name, wielded:get_name())
|
||||
|
||||
-- Wear out tool
|
||||
tp = wielded:get_tool_capabilities()
|
||||
dp = minetest.get_dig_params(def.groups, tp)
|
||||
wielded:add_wear(dp.wear)
|
||||
digger:set_wielded_item(wielded)
|
||||
|
||||
-- Add dropped items 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
|
||||
end
|
||||
|
||||
local oldnode = nil
|
||||
local oldmetadata = nil
|
||||
if def.after_dig_node then
|
||||
oldnode = node;
|
||||
oldmetadata = minetest.env:get_meta(pos):to_table()
|
||||
end
|
||||
|
||||
-- Remove node and update
|
||||
minetest.env:remove_node(pos)
|
||||
|
||||
-- Run callback
|
||||
if def.after_dig_node then
|
||||
def.after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
end
|
||||
|
||||
-- Run script hook (deprecated)
|
||||
local _, callback
|
||||
for _, callback in ipairs(minetest.registered_on_dignodes) do
|
||||
callback(pos, node, 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
|
||||
local function redef_wrapper(table, name)
|
||||
return function(...)
|
||||
return table[name](...)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Item definition defaults
|
||||
--
|
||||
|
||||
minetest.nodedef_default = {
|
||||
-- Item properties
|
||||
type="node",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 99,
|
||||
usable = false,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
|
||||
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
|
||||
on_use = nil,
|
||||
can_dig = nil,
|
||||
|
||||
on_punch = redef_wrapper(minetest, 'node_punch'), -- minetest.node_punch
|
||||
on_dig = redef_wrapper(minetest, 'node_dig'), -- minetest.node_dig
|
||||
|
||||
on_receive_fields = nil,
|
||||
|
||||
on_metadata_inventory_move = minetest.node_metadata_inventory_move_allow_all,
|
||||
on_metadata_inventory_offer = minetest.node_metadata_inventory_offer_allow_all,
|
||||
on_metadata_inventory_take = minetest.node_metadata_inventory_take_allow_all,
|
||||
|
||||
-- Node properties
|
||||
drawtype = "normal",
|
||||
visual_scale = 1.0,
|
||||
tile_images = {""},
|
||||
special_materials = {
|
||||
{image="", backface_culling=true},
|
||||
{image="", backface_culling=true},
|
||||
},
|
||||
alpha = 255,
|
||||
post_effect_color = {a=0, r=0, g=0, b=0},
|
||||
paramtype = "none",
|
||||
paramtype2 = "none",
|
||||
is_ground_content = false,
|
||||
sunlight_propagates = false,
|
||||
walkable = true,
|
||||
pointable = true,
|
||||
diggable = true,
|
||||
climbable = false,
|
||||
buildable_to = false,
|
||||
liquidtype = "none",
|
||||
liquid_alternative_flowing = "",
|
||||
liquid_alternative_source = "",
|
||||
liquid_viscosity = 0,
|
||||
light_source = 0,
|
||||
damage_per_second = 0,
|
||||
selection_box = {type="regular"},
|
||||
legacy_facedir_simple = false,
|
||||
legacy_wallmounted = false,
|
||||
}
|
||||
|
||||
minetest.craftitemdef_default = {
|
||||
type="craft",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 99,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
|
||||
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
|
||||
on_use = nil,
|
||||
}
|
||||
|
||||
minetest.tooldef_default = {
|
||||
type="tool",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 1,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
|
||||
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
|
||||
on_use = nil,
|
||||
}
|
||||
|
||||
minetest.noneitemdef_default = { -- This is used for the hand and unknown items
|
||||
type="none",
|
||||
-- name intentionally not defined here
|
||||
description = "",
|
||||
groups = {},
|
||||
inventory_image = "",
|
||||
wield_image = "",
|
||||
wield_scale = {x=1,y=1,z=1},
|
||||
stack_max = 99,
|
||||
liquids_pointable = false,
|
||||
tool_capabilities = nil,
|
||||
|
||||
-- Interaction callbacks
|
||||
on_place = nil,
|
||||
on_drop = nil,
|
||||
on_use = nil,
|
||||
}
|
||||
|
||||
103
builtin/item_entity.lua
Normal file
103
builtin/item_entity.lua
Normal file
@@ -0,0 +1,103 @@
|
||||
-- Minetest: builtin/item_entity.lua
|
||||
|
||||
function minetest.spawn_item(pos, item)
|
||||
-- Take item in any format
|
||||
local stack = ItemStack(item)
|
||||
local obj = minetest.env:add_entity(pos, "__builtin:item")
|
||||
obj:get_luaentity():set_item(stack:to_string())
|
||||
return obj
|
||||
end
|
||||
|
||||
minetest.register_entity("__builtin:item", {
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
physical = true,
|
||||
collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17},
|
||||
visual = "sprite",
|
||||
visual_size = {x=0.5, y=0.5},
|
||||
textures = {""},
|
||||
spritediv = {x=1, y=1},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
is_visible = false,
|
||||
},
|
||||
|
||||
itemstring = '',
|
||||
physical_state = true,
|
||||
|
||||
set_item = function(self, itemstring)
|
||||
self.itemstring = itemstring
|
||||
local stack = ItemStack(itemstring)
|
||||
local itemtable = stack:to_table()
|
||||
local itemname = nil
|
||||
if itemtable then
|
||||
itemname = stack:to_table().name
|
||||
end
|
||||
local item_texture = nil
|
||||
local item_type = ""
|
||||
if minetest.registered_items[itemname] then
|
||||
item_texture = minetest.registered_items[itemname].inventory_image
|
||||
item_type = minetest.registered_items[itemname].type
|
||||
end
|
||||
prop = {
|
||||
is_visible = true,
|
||||
visual = "sprite",
|
||||
textures = {"unknown_item.png"}
|
||||
}
|
||||
if item_texture and item_texture ~= "" then
|
||||
prop.visual = "sprite"
|
||||
prop.textures = {item_texture}
|
||||
prop.visual_size = {x=0.50, y=0.50}
|
||||
else
|
||||
prop.visual = "wielditem"
|
||||
prop.textures = {itemname}
|
||||
prop.visual_size = {x=0.20, y=0.20}
|
||||
prop.automatic_rotate = math.pi * 0.25
|
||||
end
|
||||
self.object:set_properties(prop)
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
return self.itemstring
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.itemstring = staticdata
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
self.object:setvelocity({x=0, y=2, z=0})
|
||||
self.object:setacceleration({x=0, y=-10, z=0})
|
||||
self:set_item(self.itemstring)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local p = self.object:getpos()
|
||||
p.y = p.y - 0.3
|
||||
local nn = minetest.env:get_node(p).name
|
||||
if minetest.registered_nodes[nn].walkable then
|
||||
if self.physical_state then
|
||||
self.object:setvelocity({x=0,y=0,z=0})
|
||||
self.object:setacceleration({x=0, y=0, z=0})
|
||||
self.physical_state = false
|
||||
self.object:set_properties({
|
||||
physical = false
|
||||
})
|
||||
end
|
||||
else
|
||||
if not self.physical_state then
|
||||
self.object:setvelocity({x=0,y=0,z=0})
|
||||
self.object:setacceleration({x=0, y=-10, z=0})
|
||||
self.physical_state = true
|
||||
self.object:set_properties({
|
||||
physical = true
|
||||
})
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
on_punch = function(self, hitter)
|
||||
if self.itemstring ~= '' then
|
||||
hitter:get_inventory():add_item("main", self.itemstring)
|
||||
end
|
||||
self.object:remove()
|
||||
end,
|
||||
})
|
||||
|
||||
101
builtin/misc.lua
Normal file
101
builtin/misc.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
-- Minetest: builtin/misc.lua
|
||||
|
||||
--
|
||||
-- Misc. API functions
|
||||
--
|
||||
|
||||
minetest.timers_to_add = {}
|
||||
minetest.timers = {}
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for _, timer in ipairs(minetest.timers_to_add) do
|
||||
table.insert(minetest.timers, timer)
|
||||
end
|
||||
minetest.timers_to_add = {}
|
||||
for index, timer in ipairs(minetest.timers) do
|
||||
timer.time = timer.time - dtime
|
||||
if timer.time <= 0 then
|
||||
timer.func(timer.param)
|
||||
table.remove(minetest.timers,index)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function minetest.after(time, func, param)
|
||||
table.insert(minetest.timers_to_add, {time=time, func=func, param=param})
|
||||
end
|
||||
|
||||
function minetest.check_player_privs(name, privs)
|
||||
local player_privs = minetest.get_player_privs(name)
|
||||
local missing_privileges = {}
|
||||
for priv, val in pairs(privs) do
|
||||
if val then
|
||||
if not player_privs[priv] then
|
||||
table.insert(missing_privileges, priv)
|
||||
end
|
||||
end
|
||||
end
|
||||
if #missing_privileges > 0 then
|
||||
return false, missing_privileges
|
||||
end
|
||||
return true, ""
|
||||
end
|
||||
|
||||
function minetest.get_connected_players()
|
||||
-- This could be optimized a bit, but leave that for later
|
||||
local list = {}
|
||||
for _, obj in pairs(minetest.env:get_objects_inside_radius({x=0,y=0,z=0}, 1000000)) do
|
||||
if obj:is_player() then
|
||||
table.insert(list, obj)
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
function minetest.hash_node_position(pos)
|
||||
return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
|
||||
end
|
||||
|
||||
function minetest.get_item_group(name, group)
|
||||
if not minetest.registered_items[name] or not
|
||||
minetest.registered_items[name].groups[group] then
|
||||
return 0
|
||||
end
|
||||
return minetest.registered_items[name].groups[group]
|
||||
end
|
||||
|
||||
function minetest.get_node_group(name, group)
|
||||
return minetest.get_item_group(name, group)
|
||||
end
|
||||
|
||||
function minetest.string_to_pos(value)
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||
if p.x and p.y and p.z then
|
||||
p.x = tonumber(p.x)
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
return p
|
||||
end
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$")
|
||||
if p.x and p.y and p.z then
|
||||
p.x = tonumber(p.x)
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
return p
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
assert(minetest.string_to_pos("10.0, 5, -2").x == 10)
|
||||
assert(minetest.string_to_pos("( 10.0, 5, -2)").z == -2)
|
||||
assert(minetest.string_to_pos("asd, 5, -2)") == nil)
|
||||
|
||||
function minetest.setting_get_pos(name)
|
||||
local value = minetest.setting_get(name)
|
||||
if not value then
|
||||
return nil
|
||||
end
|
||||
return minetest.string_to_pos(value)
|
||||
end
|
||||
|
||||
94
builtin/misc_helpers.lua
Normal file
94
builtin/misc_helpers.lua
Normal file
@@ -0,0 +1,94 @@
|
||||
-- Minetest: builtin/misc_helpers.lua
|
||||
|
||||
function basic_dump2(o)
|
||||
if type(o) == "number" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "string" then
|
||||
return string.format("%q", o)
|
||||
elseif type(o) == "boolean" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "function" then
|
||||
return "<function>"
|
||||
elseif type(o) == "userdata" then
|
||||
return "<userdata>"
|
||||
elseif type(o) == "nil" then
|
||||
return "nil"
|
||||
else
|
||||
error("cannot dump a " .. type(o))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function dump2(o, name, dumped)
|
||||
name = name or "_"
|
||||
dumped = dumped or {}
|
||||
io.write(name, " = ")
|
||||
if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
|
||||
or type(o) == "function" or type(o) == "nil"
|
||||
or type(o) == "userdata" then
|
||||
io.write(basic_dump2(o), "\n")
|
||||
elseif type(o) == "table" then
|
||||
if dumped[o] then
|
||||
io.write(dumped[o], "\n")
|
||||
else
|
||||
dumped[o] = name
|
||||
io.write("{}\n") -- new table
|
||||
for k,v in pairs(o) do
|
||||
local fieldname = string.format("%s[%s]", name, basic_dump2(k))
|
||||
dump2(v, fieldname, dumped)
|
||||
end
|
||||
end
|
||||
else
|
||||
error("cannot dump a " .. type(o))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function dump(o, dumped)
|
||||
dumped = dumped or {}
|
||||
if type(o) == "number" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "string" then
|
||||
return string.format("%q", o)
|
||||
elseif type(o) == "table" then
|
||||
if dumped[o] then
|
||||
return "<circular reference>"
|
||||
end
|
||||
dumped[o] = true
|
||||
local t = {}
|
||||
for k,v in pairs(o) do
|
||||
t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
|
||||
end
|
||||
return "{" .. table.concat(t, ", ") .. "}"
|
||||
elseif type(o) == "boolean" then
|
||||
return tostring(o)
|
||||
elseif type(o) == "function" then
|
||||
return "<function>"
|
||||
elseif type(o) == "userdata" then
|
||||
return "<userdata>"
|
||||
elseif type(o) == "nil" then
|
||||
return "nil"
|
||||
else
|
||||
error("cannot dump a " .. type(o))
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function string:split(sep)
|
||||
local sep, fields = sep or ",", {}
|
||||
local pattern = string.format("([^%s]+)", sep)
|
||||
self:gsub(pattern, function(c) fields[#fields+1] = c end)
|
||||
return fields
|
||||
end
|
||||
|
||||
function string:trim()
|
||||
return (self:gsub("^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
assert(string.trim("\n \t\tfoo bar\t ") == "foo bar")
|
||||
|
||||
function minetest.pos_to_string(pos)
|
||||
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
|
||||
end
|
||||
|
||||
|
||||
324
builtin/misc_register.lua
Normal file
324
builtin/misc_register.lua
Normal file
@@ -0,0 +1,324 @@
|
||||
-- Minetest: builtin/misc_register.lua
|
||||
|
||||
--
|
||||
-- Make raw registration functions inaccessible to anyone except this file
|
||||
--
|
||||
|
||||
local register_item_raw = minetest.register_item_raw
|
||||
minetest.register_item_raw = nil
|
||||
|
||||
local register_alias_raw = minetest.register_alias_raw
|
||||
minetest.register_item_raw = nil
|
||||
|
||||
--
|
||||
-- Item / entity / ABM registration functions
|
||||
--
|
||||
|
||||
minetest.registered_abms = {}
|
||||
minetest.registered_entities = {}
|
||||
minetest.registered_items = {}
|
||||
minetest.registered_nodes = {}
|
||||
minetest.registered_craftitems = {}
|
||||
minetest.registered_tools = {}
|
||||
minetest.registered_aliases = {}
|
||||
|
||||
-- For tables that are indexed by item name:
|
||||
-- If table[X] does not exist, default to table[minetest.registered_aliases[X]]
|
||||
local function set_alias_metatable(table)
|
||||
setmetatable(table, {
|
||||
__index = function(name)
|
||||
return rawget(table, minetest.registered_aliases[name])
|
||||
end
|
||||
})
|
||||
end
|
||||
set_alias_metatable(minetest.registered_items)
|
||||
set_alias_metatable(minetest.registered_nodes)
|
||||
set_alias_metatable(minetest.registered_craftitems)
|
||||
set_alias_metatable(minetest.registered_tools)
|
||||
|
||||
-- These item names may not be used because they would interfere
|
||||
-- with legacy itemstrings
|
||||
local forbidden_item_names = {
|
||||
MaterialItem = true,
|
||||
MaterialItem2 = true,
|
||||
MaterialItem3 = true,
|
||||
NodeItem = true,
|
||||
node = true,
|
||||
CraftItem = true,
|
||||
craft = true,
|
||||
MBOItem = true,
|
||||
ToolItem = true,
|
||||
tool = true,
|
||||
}
|
||||
|
||||
local function check_modname_prefix(name)
|
||||
if name:sub(1,1) == ":" then
|
||||
-- Escape the modname prefix enforcement mechanism
|
||||
return name:sub(2)
|
||||
else
|
||||
-- Modname prefix enforcement
|
||||
local expected_prefix = minetest.get_current_modname() .. ":"
|
||||
if name:sub(1, #expected_prefix) ~= expected_prefix then
|
||||
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||
"\"modname:\" or \":\" prefix required")
|
||||
end
|
||||
local subname = name:sub(#expected_prefix+1)
|
||||
if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
|
||||
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||
"contains unallowed characters")
|
||||
end
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
function minetest.register_abm(spec)
|
||||
-- Add to minetest.registered_abms
|
||||
minetest.registered_abms[#minetest.registered_abms+1] = spec
|
||||
end
|
||||
|
||||
function minetest.register_entity(name, prototype)
|
||||
-- Check name
|
||||
if name == nil then
|
||||
error("Unable to register entity: Name is nil")
|
||||
end
|
||||
name = check_modname_prefix(tostring(name))
|
||||
|
||||
prototype.name = name
|
||||
prototype.__index = prototype -- so that it can be used as a metatable
|
||||
|
||||
-- Add to minetest.registered_entities
|
||||
minetest.registered_entities[name] = prototype
|
||||
end
|
||||
|
||||
function minetest.register_item(name, itemdef)
|
||||
-- Check name
|
||||
if name == nil then
|
||||
error("Unable to register item: Name is nil")
|
||||
end
|
||||
name = check_modname_prefix(tostring(name))
|
||||
if forbidden_item_names[name] then
|
||||
error("Unable to register item: Name is forbidden: " .. name)
|
||||
end
|
||||
itemdef.name = name
|
||||
|
||||
-- Apply defaults and add to registered_* table
|
||||
if itemdef.type == "node" then
|
||||
setmetatable(itemdef, {__index = minetest.nodedef_default})
|
||||
minetest.registered_nodes[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "craft" then
|
||||
setmetatable(itemdef, {__index = minetest.craftitemdef_default})
|
||||
minetest.registered_craftitems[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "tool" then
|
||||
setmetatable(itemdef, {__index = minetest.tooldef_default})
|
||||
minetest.registered_tools[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "none" then
|
||||
setmetatable(itemdef, {__index = minetest.noneitemdef_default})
|
||||
else
|
||||
error("Unable to register item: Type is invalid: " .. dump(itemdef))
|
||||
end
|
||||
|
||||
-- Flowing liquid uses param2
|
||||
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
|
||||
itemdef.paramtype2 = "flowingliquid"
|
||||
end
|
||||
|
||||
-- BEGIN Legacy stuff
|
||||
if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then
|
||||
minetest.register_craft({
|
||||
type="cooking",
|
||||
output=itemdef.cookresult_itemstring,
|
||||
recipe=itemdef.name,
|
||||
cooktime=itemdef.furnace_cooktime
|
||||
})
|
||||
end
|
||||
if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then
|
||||
minetest.register_craft({
|
||||
type="fuel",
|
||||
recipe=itemdef.name,
|
||||
burntime=itemdef.furnace_burntime
|
||||
})
|
||||
end
|
||||
-- END Legacy stuff
|
||||
|
||||
-- Disable all further modifications
|
||||
getmetatable(itemdef).__newindex = {}
|
||||
|
||||
--minetest.log("Registering item: " .. itemdef.name)
|
||||
minetest.registered_items[itemdef.name] = itemdef
|
||||
minetest.registered_aliases[itemdef.name] = nil
|
||||
register_item_raw(itemdef)
|
||||
end
|
||||
|
||||
function minetest.register_node(name, nodedef)
|
||||
nodedef.type = "node"
|
||||
minetest.register_item(name, nodedef)
|
||||
end
|
||||
|
||||
function minetest.register_craftitem(name, craftitemdef)
|
||||
craftitemdef.type = "craft"
|
||||
|
||||
-- BEGIN Legacy stuff
|
||||
if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then
|
||||
craftitemdef.inventory_image = craftitemdef.image
|
||||
end
|
||||
-- END Legacy stuff
|
||||
|
||||
minetest.register_item(name, craftitemdef)
|
||||
end
|
||||
|
||||
function minetest.register_tool(name, tooldef)
|
||||
tooldef.type = "tool"
|
||||
tooldef.stack_max = 1
|
||||
|
||||
-- BEGIN Legacy stuff
|
||||
if tooldef.inventory_image == nil and tooldef.image ~= nil then
|
||||
tooldef.inventory_image = tooldef.image
|
||||
end
|
||||
if tooldef.tool_capabilities == nil and
|
||||
(tooldef.full_punch_interval ~= nil or
|
||||
tooldef.basetime ~= nil or
|
||||
tooldef.dt_weight ~= nil or
|
||||
tooldef.dt_crackiness ~= nil or
|
||||
tooldef.dt_crumbliness ~= nil or
|
||||
tooldef.dt_cuttability ~= nil or
|
||||
tooldef.basedurability ~= nil or
|
||||
tooldef.dd_weight ~= nil or
|
||||
tooldef.dd_crackiness ~= nil or
|
||||
tooldef.dd_crumbliness ~= nil or
|
||||
tooldef.dd_cuttability ~= nil) then
|
||||
tooldef.tool_capabilities = {
|
||||
full_punch_interval = tooldef.full_punch_interval,
|
||||
basetime = tooldef.basetime,
|
||||
dt_weight = tooldef.dt_weight,
|
||||
dt_crackiness = tooldef.dt_crackiness,
|
||||
dt_crumbliness = tooldef.dt_crumbliness,
|
||||
dt_cuttability = tooldef.dt_cuttability,
|
||||
basedurability = tooldef.basedurability,
|
||||
dd_weight = tooldef.dd_weight,
|
||||
dd_crackiness = tooldef.dd_crackiness,
|
||||
dd_crumbliness = tooldef.dd_crumbliness,
|
||||
dd_cuttability = tooldef.dd_cuttability,
|
||||
}
|
||||
end
|
||||
-- END Legacy stuff
|
||||
|
||||
minetest.register_item(name, tooldef)
|
||||
end
|
||||
|
||||
function minetest.register_alias(name, convert_to)
|
||||
if forbidden_item_names[name] then
|
||||
error("Unable to register alias: Name is forbidden: " .. name)
|
||||
end
|
||||
if minetest.registered_items[name] ~= nil then
|
||||
minetest.log("WARNING: Not registering alias, item with same name" ..
|
||||
" is already defined: " .. name .. " -> " .. convert_to)
|
||||
else
|
||||
--minetest.log("Registering alias: " .. name .. " -> " .. convert_to)
|
||||
minetest.registered_aliases[name] = convert_to
|
||||
register_alias_raw(name, convert_to)
|
||||
end
|
||||
end
|
||||
|
||||
-- Alias the forbidden item names to "" so they can't be
|
||||
-- created via itemstrings (e.g. /give)
|
||||
local name
|
||||
for name in pairs(forbidden_item_names) do
|
||||
minetest.registered_aliases[name] = ""
|
||||
register_alias_raw(name, "")
|
||||
end
|
||||
|
||||
|
||||
-- Deprecated:
|
||||
-- Aliases for minetest.register_alias (how ironic...)
|
||||
--minetest.alias_node = minetest.register_alias
|
||||
--minetest.alias_tool = minetest.register_alias
|
||||
--minetest.alias_craftitem = minetest.register_alias
|
||||
|
||||
--
|
||||
-- Built-in node definitions. Also defined in C.
|
||||
--
|
||||
|
||||
minetest.register_item(":unknown", {
|
||||
type = "none",
|
||||
description = "Unknown Item",
|
||||
inventory_image = "unknown_item.png",
|
||||
on_place = minetest.item_place,
|
||||
on_drop = minetest.item_drop,
|
||||
})
|
||||
|
||||
minetest.register_node(":air", {
|
||||
description = "Air (you hacker you!)",
|
||||
inventory_image = "unknown_block.png",
|
||||
wield_image = "unknown_block.png",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
air_equivalent = true,
|
||||
})
|
||||
|
||||
minetest.register_node(":ignore", {
|
||||
description = "Ignore (you hacker you!)",
|
||||
inventory_image = "unknown_block.png",
|
||||
wield_image = "unknown_block.png",
|
||||
drawtype = "airlike",
|
||||
paramtype = "none",
|
||||
sunlight_propagates = false,
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true, -- A way to remove accidentally placed ignores
|
||||
air_equivalent = true,
|
||||
})
|
||||
|
||||
-- The hand (bare definition)
|
||||
minetest.register_item(":", {
|
||||
type = "none",
|
||||
})
|
||||
|
||||
--
|
||||
-- Creative inventory
|
||||
--
|
||||
|
||||
minetest.creative_inventory = {}
|
||||
|
||||
minetest.add_to_creative_inventory = function(itemstring)
|
||||
table.insert(minetest.creative_inventory, itemstring)
|
||||
end
|
||||
|
||||
--
|
||||
-- Callback registration
|
||||
--
|
||||
|
||||
local function make_registration()
|
||||
local t = {}
|
||||
local registerfunc = function(func) table.insert(t, func) end
|
||||
return t, registerfunc
|
||||
end
|
||||
|
||||
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
|
||||
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
|
||||
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
|
||||
minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
|
||||
minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
|
||||
minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registration()
|
||||
minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
|
||||
minetest.registered_on_joinplayers, minetest.register_on_joinplayer = make_registration()
|
||||
minetest.registered_on_leaveplayers, minetest.register_on_leaveplayer = make_registration()
|
||||
|
||||
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
|
||||
|
||||
48
builtin/privileges.lua
Normal file
48
builtin/privileges.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
-- Minetest: builtin/privileges.lua
|
||||
|
||||
--
|
||||
-- Privileges
|
||||
--
|
||||
|
||||
minetest.registered_privileges = {}
|
||||
|
||||
function minetest.register_privilege(name, param)
|
||||
local function fill_defaults(def)
|
||||
if def.give_to_singleplayer == nil then
|
||||
def.give_to_singleplayer = true
|
||||
end
|
||||
if def.description == nil then
|
||||
def.description = "(no description)"
|
||||
end
|
||||
end
|
||||
local def = {}
|
||||
if type(param) == "table" then
|
||||
def = param
|
||||
else
|
||||
def = {description = param}
|
||||
end
|
||||
fill_defaults(def)
|
||||
minetest.registered_privileges[name] = def
|
||||
end
|
||||
|
||||
minetest.register_privilege("interact", "Can interact with things and modify the world")
|
||||
minetest.register_privilege("teleport", "Can use /teleport command")
|
||||
minetest.register_privilege("bring", "Can teleport other players")
|
||||
minetest.register_privilege("settime", "Can use /time")
|
||||
minetest.register_privilege("privs", "Can modify privileges")
|
||||
minetest.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
|
||||
minetest.register_privilege("server", "Can do server maintenance stuff")
|
||||
minetest.register_privilege("shout", "Can speak in chat")
|
||||
minetest.register_privilege("ban", "Can ban and unban players")
|
||||
minetest.register_privilege("give", "Can use /give and /giveme")
|
||||
minetest.register_privilege("password", "Can use /setpassword and /clearpassword")
|
||||
minetest.register_privilege("fly", {
|
||||
description = "Can fly using the free_move mode",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
minetest.register_privilege("fast", {
|
||||
description = "Can walk fast using the fast_move mode",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
|
||||
|
||||
207
builtin/serialize.lua
Normal file
207
builtin/serialize.lua
Normal 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
|
||||
|
||||
33
builtin/static_spawn.lua
Normal file
33
builtin/static_spawn.lua
Normal file
@@ -0,0 +1,33 @@
|
||||
-- Minetest: builtin/static_spawn.lua
|
||||
|
||||
local function warn_invalid_static_spawnpoint()
|
||||
if minetest.setting_get("static_spawnpoint") and
|
||||
not minetest.setting_get_pos("static_spawnpoint") then
|
||||
minetest.log('error', "The static_spawnpoint setting is invalid: \""..
|
||||
minetest.setting_get("static_spawnpoint").."\"")
|
||||
end
|
||||
end
|
||||
|
||||
warn_invalid_static_spawnpoint()
|
||||
|
||||
local function put_player_in_spawn(obj)
|
||||
warn_invalid_static_spawnpoint()
|
||||
local static_spawnpoint = minetest.setting_get_pos("static_spawnpoint")
|
||||
if not static_spawnpoint then
|
||||
return false
|
||||
end
|
||||
minetest.log('action', "Moving "..obj:get_player_name()..
|
||||
" to static spawnpoint at "..
|
||||
minetest.pos_to_string(static_spawnpoint))
|
||||
obj:setpos(static_spawnpoint)
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_on_newplayer(function(obj)
|
||||
put_player_in_spawn(obj)
|
||||
end)
|
||||
|
||||
minetest.register_on_respawnplayer(function(obj)
|
||||
return put_player_in_spawn(obj)
|
||||
end)
|
||||
|
||||
748
doc/lua_api.txt
748
doc/lua_api.txt
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,9 @@ LIGHT_MAX = 14
|
||||
-- Definitions made by this mod that other mods can use too
|
||||
default = {}
|
||||
|
||||
-- Load other files
|
||||
dofile(minetest.get_modpath("default").."/mapgen.lua")
|
||||
|
||||
--
|
||||
-- Tool definition
|
||||
--
|
||||
@@ -24,10 +27,10 @@ minetest.register_item(":", {
|
||||
full_punch_interval = 1.0,
|
||||
max_drop_level = 0,
|
||||
groupcaps = {
|
||||
fleshy = {times={[2]=2.00, [3]=1.00}, maxwear=0, maxlevel=1},
|
||||
crumbly = {times={[3]=0.70}, maxwear=0, maxlevel=1},
|
||||
snappy = {times={[3]=0.40}, maxwear=0, maxlevel=1},
|
||||
oddly_breakable_by_hand = {times={[1]=3.50,[2]=2.00,[3]=0.70}, maxwear=0, maxlevel=3},
|
||||
fleshy = {times={[2]=2.00, [3]=1.00}, uses=0, maxlevel=1},
|
||||
crumbly = {times={[2]=3.00, [3]=0.70}, uses=0, maxlevel=1},
|
||||
snappy = {times={[3]=0.40}, uses=0, maxlevel=1},
|
||||
oddly_breakable_by_hand = {times={[1]=7.00,[2]=4.00,[3]=1.40}, uses=0, maxlevel=3},
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -38,7 +41,7 @@ minetest.register_tool("default:pick_wood", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
cracky={times={[2]=1.50, [3]=0.80}, maxwear=0.1, maxlevel=1}
|
||||
cracky={times={[2]=2.00, [3]=1.20}, uses=10, maxlevel=1}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -48,7 +51,7 @@ minetest.register_tool("default:pick_stone", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
cracky={times={[1]=1.50, [2]=0.80, [3]=0.60}, maxwear=0.05, maxlevel=1}
|
||||
cracky={times={[1]=2.00, [2]=1.20, [3]=0.80}, uses=20, maxlevel=1}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -58,7 +61,7 @@ minetest.register_tool("default:pick_steel", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
cracky={times={[1]=1.00, [2]=0.60, [3]=0.40}, maxwear=0.1, maxlevel=2}
|
||||
cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -69,9 +72,9 @@ minetest.register_tool("default:pick_mese", {
|
||||
full_punch_interval = 1.0,
|
||||
max_drop_level=3,
|
||||
groupcaps={
|
||||
cracky={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3},
|
||||
crumbly={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3},
|
||||
snappy={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3}
|
||||
cracky={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
|
||||
crumbly={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
|
||||
snappy={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -81,7 +84,7 @@ minetest.register_tool("default:shovel_wood", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
crumbly={times={[1]=1.50, [2]=0.80, [3]=0.50}, maxwear=0.1, maxlevel=1}
|
||||
crumbly={times={[1]=2.00, [2]=0.80, [3]=0.50}, uses=10, maxlevel=1}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -91,7 +94,7 @@ minetest.register_tool("default:shovel_stone", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
crumbly={times={[1]=0.80, [2]=0.50, [3]=0.30}, maxwear=0.05, maxlevel=1}
|
||||
crumbly={times={[1]=1.20, [2]=0.50, [3]=0.30}, uses=20, maxlevel=1}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -101,7 +104,7 @@ minetest.register_tool("default:shovel_steel", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
crumbly={times={[1]=0.50, [2]=0.35, [3]=0.30}, maxwear=0.1, maxlevel=2}
|
||||
crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=10, maxlevel=2}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -111,8 +114,8 @@ minetest.register_tool("default:axe_wood", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
choppy={times={[2]=1.40, [3]=0.80}, maxwear=0.1, maxlevel=1},
|
||||
fleshy={times={[2]=1.50, [3]=0.80}, maxwear=0.1, maxlevel=1}
|
||||
choppy={times={[2]=1.40, [3]=0.80}, uses=10, maxlevel=1},
|
||||
fleshy={times={[2]=1.50, [3]=0.80}, uses=10, maxlevel=1}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -122,8 +125,8 @@ minetest.register_tool("default:axe_stone", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
choppy={times={[1]=1.50, [2]=1.00, [3]=0.60}, maxwear=0.05, maxlevel=1},
|
||||
fleshy={times={[2]=1.30, [3]=0.70}, maxwear=0.05, maxlevel=1}
|
||||
choppy={times={[1]=1.50, [2]=1.00, [3]=0.60}, uses=20, maxlevel=1},
|
||||
fleshy={times={[2]=1.30, [3]=0.70}, uses=20, maxlevel=1}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -133,8 +136,8 @@ minetest.register_tool("default:axe_steel", {
|
||||
tool_capabilities = {
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
choppy={times={[1]=1.00, [2]=0.80, [3]=0.50}, maxwear=0.1, maxlevel=2},
|
||||
fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.03, maxlevel=1}
|
||||
choppy={times={[1]=2.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2},
|
||||
fleshy={times={[2]=1.10, [3]=0.60}, uses=40, maxlevel=1}
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -145,9 +148,9 @@ minetest.register_tool("default:sword_wood", {
|
||||
full_punch_interval = 1.0,
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.1, maxlevel=1},
|
||||
snappy={times={[2]=1.00, [3]=0.50}, maxwear=0.1, maxlevel=1},
|
||||
choppy={times={[3]=1.00}, maxwear=0.05, maxlevel=0}
|
||||
fleshy={times={[2]=1.10, [3]=0.60}, uses=10, maxlevel=1},
|
||||
snappy={times={[2]=1.00, [3]=0.50}, uses=10, maxlevel=1},
|
||||
choppy={times={[3]=1.00}, uses=20, maxlevel=0}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -158,9 +161,9 @@ minetest.register_tool("default:sword_stone", {
|
||||
full_punch_interval = 1.0,
|
||||
max_drop_level=0,
|
||||
groupcaps={
|
||||
fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
|
||||
snappy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
|
||||
choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0}
|
||||
fleshy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
|
||||
snappy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
|
||||
choppy={times={[3]=0.90}, uses=20, maxlevel=0}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -171,9 +174,9 @@ minetest.register_tool("default:sword_steel", {
|
||||
full_punch_interval = 1.0,
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
fleshy={times={[1]=1.00, [2]=0.40, [3]=0.20}, maxwear=0.1, maxlevel=2},
|
||||
snappy={times={[2]=0.70, [3]=0.30}, maxwear=0.03, maxlevel=1},
|
||||
choppy={times={[3]=0.70}, maxwear=0.03, maxlevel=0}
|
||||
fleshy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=10, maxlevel=2},
|
||||
snappy={times={[2]=0.70, [3]=0.30}, uses=40, maxlevel=1},
|
||||
choppy={times={[3]=0.70}, uses=40, maxlevel=0}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -962,7 +965,7 @@ minetest.register_node("default:mese", {
|
||||
description = "Mese",
|
||||
tile_images = {"default_mese.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=1},
|
||||
groups = {cracky=1,level=2},
|
||||
sounds = default.node_sound_defaults(),
|
||||
})
|
||||
|
||||
@@ -1109,6 +1112,21 @@ minetest.register_node("default:sign_wall", {
|
||||
groups = {choppy=2,dig_immediate=2},
|
||||
legacy_wallmounted = true,
|
||||
sounds = default.node_sound_defaults(),
|
||||
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("infotext", "\"\"")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
--print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
fields.text = fields.text or ""
|
||||
print((sender:get_player_name() or "").." wrote \""..fields.text..
|
||||
"\" to sign at "..minetest.pos_to_string(pos))
|
||||
meta:set_string("text", fields.text)
|
||||
meta:set_string("infotext", '"'..fields.text..'"')
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("default:chest", {
|
||||
@@ -1116,32 +1134,312 @@ minetest.register_node("default:chest", {
|
||||
tile_images = {"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",
|
||||
metadata_name = "chest",
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"invsize[8,9;]"..
|
||||
"list[current_name;main;0,0;8,4;]"..
|
||||
"list[current_player;main;0,5;8,4;]")
|
||||
meta:set_string("infotext", "Chest")
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 8*4)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.env:get_meta(pos);
|
||||
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)
|
||||
if player:get_player_name() ~= meta:get_string("owner") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_node("default:chest_locked", {
|
||||
description = "Locked Chest",
|
||||
tile_images = {"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",
|
||||
metadata_name = "locked_chest",
|
||||
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("owner", placer:get_player_name() or "")
|
||||
meta:set_string("infotext", "Locked Chest (owned by "..
|
||||
meta:get_string("owner")..")")
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"invsize[8,9;]"..
|
||||
"list[current_name;main;0,0;8,4;]"..
|
||||
"list[current_player;main;0,5;8,4;]")
|
||||
meta:set_string("infotext", "Locked Chest")
|
||||
meta:set_string("owner", "")
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 8*4)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.env:get_meta(pos);
|
||||
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)
|
||||
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
|
||||
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
|
||||
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
|
||||
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;]"..
|
||||
"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;]"..
|
||||
"list[current_name;dst;5,1;2,2;]"..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
|
||||
minetest.register_node("default:furnace", {
|
||||
description = "Furnace",
|
||||
tile_images = {"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",
|
||||
metadata_name = "furnace",
|
||||
groups = {cracky=2},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", default.furnace_inactive_formspec)
|
||||
meta:set_string("infotext", "Furnace")
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("fuel", 1)
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("dst", 4)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.env:get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("fuel") then
|
||||
return false
|
||||
elseif not inv:is_empty("dst") then
|
||||
return false
|
||||
elseif not inv:is_empty("src") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("default:furnace_active", {
|
||||
description = "Furnace",
|
||||
tile_images = {"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,
|
||||
drop = "default:furnace",
|
||||
groups = {cracky=2},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", default.furnace_inactive_formspec)
|
||||
meta:set_string("infotext", "Furnace");
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("fuel", 1)
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("dst", 4)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.env:get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("fuel") then
|
||||
return false
|
||||
elseif not inv:is_empty("dst") then
|
||||
return false
|
||||
elseif not inv:is_empty("src") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
})
|
||||
|
||||
function hacky_swap_node(pos,name)
|
||||
local node = minetest.env:get_node(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
local meta0 = meta:to_table()
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
local meta0 = meta:to_table()
|
||||
minetest.env:set_node(pos,node)
|
||||
meta = minetest.env:get_meta(pos)
|
||||
meta:from_table(meta0)
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"default:furnace","default:furnace_active"},
|
||||
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 meta:get_string(name) == "" then
|
||||
meta:set_float(name, 0.0)
|
||||
end
|
||||
end
|
||||
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
local srclist = inv:get_list("src")
|
||||
local cooked = nil
|
||||
|
||||
if srclist then
|
||||
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
|
||||
end
|
||||
|
||||
local was_active = false
|
||||
|
||||
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
||||
was_active = true
|
||||
meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
|
||||
meta:set_float("src_time", meta:get_float("src_time") + 1)
|
||||
if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
|
||||
-- check if there's room for output in "dst" list
|
||||
if inv:room_for_item("dst",cooked.item) then
|
||||
-- Put result in "dst" list
|
||||
inv:add_item("dst", cooked.item)
|
||||
-- take stuff from "src" list
|
||||
srcstack = inv:get_stack("src", 1)
|
||||
srcstack:take_item()
|
||||
inv:set_stack("src", 1, srcstack)
|
||||
else
|
||||
print("Could not insert '"..cooked.item.."'")
|
||||
end
|
||||
meta:set_string("src_time", 0)
|
||||
end
|
||||
end
|
||||
|
||||
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
||||
local percent = math.floor(meta:get_float("fuel_time") /
|
||||
meta:get_float("fuel_totaltime") * 100)
|
||||
meta:set_string("infotext","Furnace active: "..percent.."%")
|
||||
hacky_swap_node(pos,"default:furnace_active")
|
||||
meta:set_string("formspec",
|
||||
"invsize[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;]"..
|
||||
"list[current_name;src;2,1;1,1;]"..
|
||||
"list[current_name;dst;5,1;2,2;]"..
|
||||
"list[current_player;main;0,5;8,4;]")
|
||||
return
|
||||
end
|
||||
|
||||
local fuel = nil
|
||||
local cooked = nil
|
||||
local fuellist = inv:get_list("fuel")
|
||||
local srclist = inv:get_list("src")
|
||||
|
||||
if srclist then
|
||||
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
|
||||
end
|
||||
if fuellist then
|
||||
fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
|
||||
end
|
||||
|
||||
if fuel.time <= 0 then
|
||||
meta:set_string("infotext","Furnace out of fuel")
|
||||
hacky_swap_node(pos,"default:furnace")
|
||||
meta:set_string("formspec", default.furnace_inactive_formspec)
|
||||
return
|
||||
end
|
||||
|
||||
if cooked.item:is_empty() then
|
||||
if was_active then
|
||||
meta:set_string("infotext","Furnace is empty")
|
||||
hacky_swap_node(pos,"default:furnace")
|
||||
meta:set_string("formspec", default.furnace_inactive_formspec)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
meta:set_string("fuel_totaltime", fuel.time)
|
||||
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_node("default:cobble", {
|
||||
@@ -1298,6 +1596,29 @@ 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
|
||||
--
|
||||
|
||||
minetest.register_alias("mapgen_air", "air")
|
||||
minetest.register_alias("mapgen_stone", "default:stone")
|
||||
minetest.register_alias("mapgen_tree", "default:tree")
|
||||
minetest.register_alias("mapgen_leaves", "default:leaves")
|
||||
minetest.register_alias("mapgen_apple", "default:apple")
|
||||
minetest.register_alias("mapgen_water_source", "default:water_source")
|
||||
minetest.register_alias("mapgen_dirt", "default:dirt")
|
||||
minetest.register_alias("mapgen_sand", "default:sand")
|
||||
minetest.register_alias("mapgen_gravel", "default:gravel")
|
||||
minetest.register_alias("mapgen_clay", "default:clay")
|
||||
minetest.register_alias("mapgen_lava_source", "default:lava_source")
|
||||
minetest.register_alias("mapgen_cobble", "default:cobble")
|
||||
minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
|
||||
minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
|
||||
minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
|
||||
minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
|
||||
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
|
||||
minetest.register_alias("mapgen_mese", "default:mese")
|
||||
|
||||
--
|
||||
-- Some common functions
|
||||
--
|
||||
@@ -1500,6 +1821,57 @@ minetest.register_on_chat_message(function(name, message)
|
||||
end
|
||||
end)
|
||||
|
||||
--
|
||||
-- Test some things
|
||||
--
|
||||
|
||||
local function test_get_craft_result()
|
||||
print("test_get_craft_result()")
|
||||
-- normal
|
||||
local input = {
|
||||
method = "normal",
|
||||
width = 2,
|
||||
items = {"", "default:coal_lump", "", "default:stick"}
|
||||
}
|
||||
print("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))
|
||||
assert(output.item)
|
||||
print("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
|
||||
local input = {
|
||||
method = "fuel",
|
||||
width = 1,
|
||||
items = {"default:coal_lump"}
|
||||
}
|
||||
print("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))
|
||||
assert(output.time)
|
||||
assert(output.time > 0)
|
||||
-- cook
|
||||
local input = {
|
||||
method = "cooking",
|
||||
width = 1,
|
||||
items = {"default:cobble"}
|
||||
}
|
||||
print("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))
|
||||
assert(output.time)
|
||||
assert(output.time > 0)
|
||||
assert(output.item)
|
||||
print("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
|
||||
test_get_craft_result()
|
||||
|
||||
--
|
||||
-- Done, print some random stuff
|
||||
--
|
||||
|
||||
114
games/minimal/mods/default/mapgen.lua
Normal file
114
games/minimal/mods/default/mapgen.lua
Normal file
@@ -0,0 +1,114 @@
|
||||
-- minetest/default/mapgen.lua
|
||||
|
||||
--
|
||||
-- Aliases for map generator outputs
|
||||
--
|
||||
|
||||
minetest.register_alias("mapgen_air", "air")
|
||||
minetest.register_alias("mapgen_stone", "default:stone")
|
||||
minetest.register_alias("mapgen_tree", "default:tree")
|
||||
minetest.register_alias("mapgen_leaves", "default:leaves")
|
||||
minetest.register_alias("mapgen_apple", "default:apple")
|
||||
minetest.register_alias("mapgen_water_source", "default:water_source")
|
||||
minetest.register_alias("mapgen_dirt", "default:dirt")
|
||||
minetest.register_alias("mapgen_sand", "default:sand")
|
||||
minetest.register_alias("mapgen_gravel", "default:gravel")
|
||||
minetest.register_alias("mapgen_clay", "default:clay")
|
||||
minetest.register_alias("mapgen_lava_source", "default:lava_source")
|
||||
minetest.register_alias("mapgen_cobble", "default:cobble")
|
||||
minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
|
||||
minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
|
||||
minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
|
||||
minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
|
||||
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
|
||||
minetest.register_alias("mapgen_mese", "default:mese")
|
||||
|
||||
--
|
||||
-- Ore generation
|
||||
--
|
||||
|
||||
local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume, ore_per_chunk, height_min, height_max)
|
||||
if maxp.y < height_min or minp.y > height_max then
|
||||
return
|
||||
end
|
||||
local y_min = math.max(minp.y, height_min)
|
||||
local y_max = math.min(maxp.y, height_max)
|
||||
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
|
||||
local pr = PseudoRandom(seed)
|
||||
local num_chunks = math.floor(chunks_per_volume * volume)
|
||||
local chunk_size = 3
|
||||
if ore_per_chunk <= 4 then
|
||||
chunk_size = 2
|
||||
end
|
||||
local inverse_chance = math.floor(chunk_size*chunk_size*chunk_size / ore_per_chunk)
|
||||
--print("generate_ore num_chunks: "..dump(num_chunks))
|
||||
for i=1,num_chunks do
|
||||
local y0 = pr:next(y_min, y_max-chunk_size+1)
|
||||
if y0 >= height_min and y0 <= height_max then
|
||||
local x0 = pr:next(minp.x, maxp.x-chunk_size+1)
|
||||
local z0 = pr:next(minp.z, maxp.z-chunk_size+1)
|
||||
local p0 = {x=x0, y=y0, z=z0}
|
||||
for x1=0,chunk_size-1 do
|
||||
for y1=0,chunk_size-1 do
|
||||
for z1=0,chunk_size-1 do
|
||||
if pr:next(1,inverse_chance) == 1 then
|
||||
local x2 = x0+x1
|
||||
local y2 = y0+y1
|
||||
local z2 = z0+z1
|
||||
local p2 = {x=x2, y=y2, z=z2}
|
||||
if minetest.env:get_node(p2).name == wherein then
|
||||
minetest.env:set_node(p2, {name=name})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--print("generate_ore done")
|
||||
end
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
generate_ore("default:stone_with_coal", "default:stone", minp, maxp, seed, 1/8/8/8, 5, -31000, 64)
|
||||
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+1, 1/16/16/16, 5, -5, 7)
|
||||
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+2, 1/12/12/12, 5, -16, -5)
|
||||
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+3, 1/9/9/9, 5, -31000, -17)
|
||||
-- Generate clay
|
||||
if maxp.y >= 2 and minp.y <= 0 then
|
||||
-- Assume X and Z lengths are equal
|
||||
local divlen = 4
|
||||
local divs = (maxp.x-minp.x)/divlen+1;
|
||||
for divx=0+1,divs-1-1 do
|
||||
for divz=0+1,divs-1-1 do
|
||||
local cx = minp.x + math.floor((divx+0.5)*divlen)
|
||||
local cz = minp.z + math.floor((divz+0.5)*divlen)
|
||||
if minetest.env:get_node({x=cx,y=1,z=cz}).name == "default:water_source" and
|
||||
minetest.env:get_node({x=cx,y=0,z=cz}).name == "default:sand" then
|
||||
local is_shallow = true
|
||||
local num_water_around = 0
|
||||
if minetest.env:get_node({x=cx-divlen*2,y=1,z=cz+0}).name == "default:water_source" then
|
||||
num_water_around = num_water_around + 1 end
|
||||
if minetest.env:get_node({x=cx+divlen*2,y=1,z=cz+0}).name == "default:water_source" then
|
||||
num_water_around = num_water_around + 1 end
|
||||
if minetest.env:get_node({x=cx+0,y=1,z=cz-divlen*2}).name == "default:water_source" then
|
||||
num_water_around = num_water_around + 1 end
|
||||
if minetest.env:get_node({x=cx+0,y=1,z=cz+divlen*2}).name == "default:water_source" then
|
||||
num_water_around = num_water_around + 1 end
|
||||
if num_water_around >= 2 then
|
||||
is_shallow = false
|
||||
end
|
||||
if is_shallow then
|
||||
for x1=-divlen,divlen do
|
||||
for z1=-divlen,divlen do
|
||||
if minetest.env:get_node({x=cx+x1,y=0,z=cz+z1}).name == "default:sand" then
|
||||
minetest.env:set_node({x=cx+x1,y=0,z=cz+z1}, {name="default:clay"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
BIN
games/minimal/mods/default/sounds/default_grass_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_grass_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/textures/default_furnace_fire_bg.png
Normal file
BIN
games/minimal/mods/default/textures/default_furnace_fire_bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 313 B |
BIN
games/minimal/mods/default/textures/default_furnace_fire_fg.png
Normal file
BIN
games/minimal/mods/default/textures/default_furnace_fire_fg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 865 B |
Binary file not shown.
|
After Width: | Height: | Size: 376 B |
@@ -6,38 +6,59 @@
|
||||
|
||||
experimental = {}
|
||||
|
||||
timers_to_add = {}
|
||||
timers = {}
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for indes, timer in ipairs(timers_to_add) do
|
||||
table.insert(timers, timer)
|
||||
end
|
||||
timers_to_add = {}
|
||||
for index, timer in ipairs(timers) do
|
||||
timer.time = timer.time - dtime
|
||||
if timer.time <= 0 then
|
||||
timer.func()
|
||||
timers[index] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
after = function(time, func)
|
||||
table.insert(timers_to_add, {time=time, func=func})
|
||||
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()
|
||||
for _, obj in pairs(minetest.get_connected_players()) do
|
||||
if experimental.player_visual_index == 0 then
|
||||
obj:set_properties({visual="upright_sprite"})
|
||||
else
|
||||
obj:set_properties({visual="cube"})
|
||||
end
|
||||
end
|
||||
experimental.player_visual_index = (experimental.player_visual_index + 1) % 2
|
||||
minetest.after(1.0, switch_player_visual)
|
||||
end
|
||||
minetest.after(1.0, switch_player_visual)
|
||||
]]
|
||||
|
||||
minetest.register_node("experimental:soundblock", {
|
||||
tile_images = {"unknown_block.png", "default_tnt_bottom.png",
|
||||
"default_tnt_side.png", "default_tnt_side.png",
|
||||
"default_tnt_side.png", "default_tnt_side.png"},
|
||||
inventory_image = minetest.inventorycube("unknown_block.png",
|
||||
"default_tnt_side.png", "default_tnt_side.png"),
|
||||
groups = {dig_immediate=3},
|
||||
})
|
||||
|
||||
minetest.register_alias("sb", "experimental:soundblock")
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"experimental:soundblock"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(p0, node, _, _)
|
||||
minetest.sound_play("default_grass_footstep", {pos=p0, gain=0.5})
|
||||
end,
|
||||
})
|
||||
|
||||
--[[
|
||||
stepsound = -1
|
||||
function test_sound()
|
||||
print("test_sound")
|
||||
stepsound = minetest.sound_play("default_grass_footstep", {gain=1.0})
|
||||
after(2.0, test_sound)
|
||||
--after(0.1, test_sound_stop)
|
||||
minetest.after(2.0, test_sound)
|
||||
--minetest.after(0.1, test_sound_stop)
|
||||
end
|
||||
function test_sound_stop()
|
||||
print("test_sound_stop")
|
||||
minetest.sound_stop(stepsound)
|
||||
after(2.0, test_sound)
|
||||
minetest.after(2.0, test_sound)
|
||||
end
|
||||
test_sound()
|
||||
--]]
|
||||
@@ -81,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)
|
||||
--
|
||||
@@ -415,16 +211,17 @@ minetest.register_alias("TNT", "experimental:tnt")
|
||||
--
|
||||
|
||||
minetest.register_entity("experimental:dummyball", {
|
||||
-- Static definition
|
||||
hp_max = 20,
|
||||
physical = false,
|
||||
collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
|
||||
visual = "sprite",
|
||||
visual_size = {x=1, y=1},
|
||||
textures = {"experimental_dummyball.png"},
|
||||
spritediv = {x=1, y=3},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
-- Dynamic variables
|
||||
initial_properties = {
|
||||
hp_max = 20,
|
||||
physical = false,
|
||||
collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
|
||||
visual = "sprite",
|
||||
visual_size = {x=1, y=1},
|
||||
textures = {"experimental_dummyball.png"},
|
||||
spritediv = {x=1, y=3},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
},
|
||||
|
||||
phase = 0,
|
||||
phasetimer = 0,
|
||||
|
||||
@@ -645,6 +442,68 @@ minetest.register_abm({
|
||||
end,
|
||||
})--]]
|
||||
|
||||
minetest.register_node("experimental:tester_node_1", {
|
||||
description = "Tester Node 1",
|
||||
tile_images = {"wieldhand.png"},
|
||||
groups = {oddly_breakable_by_hand=2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
||||
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")
|
||||
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,
|
||||
})
|
||||
|
||||
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.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()))
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
minetest.register_on_newplayer(function(player)
|
||||
print("on_newplayer")
|
||||
if minetest.setting_getbool("give_initial_stuff") then
|
||||
print("giving give_initial_stuff to player")
|
||||
player:get_inventory():add_item('main', 'default:pick_steel')
|
||||
player:get_inventory():add_item('main', 'default:torch 99')
|
||||
player:get_inventory():add_item('main', 'default:axe_steel')
|
||||
player:get_inventory():add_item('main', 'default:shovel_steel')
|
||||
player:get_inventory():add_item('main', 'default:cobble 99')
|
||||
end
|
||||
print("[minimal] giving initial stuff to player")
|
||||
player:get_inventory():add_item('main', 'default:pick_stone')
|
||||
player:get_inventory():add_item('main', 'default:torch 99')
|
||||
player:get_inventory():add_item('main', 'default:cobble 99')
|
||||
player:get_inventory():add_item('main', 'default:wood 99')
|
||||
player:get_inventory():add_item('main', 'default:axe_steel')
|
||||
player:get_inventory():add_item('main', 'default:shovel_steel')
|
||||
player:get_inventory():add_item('main', 'default:pick_wood')
|
||||
player:get_inventory():add_item('main', 'default:pick_steel')
|
||||
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)
|
||||
|
||||
|
||||
11
games/minimal/mods/test/init.lua
Normal file
11
games/minimal/mods/test/init.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
--
|
||||
-- Minimal Development Test
|
||||
-- Mod: test
|
||||
--
|
||||
|
||||
-- Try out PseudoRandom
|
||||
pseudo = PseudoRandom(13)
|
||||
assert(pseudo:next() == 22290)
|
||||
assert(pseudo:next() == 13854)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# Uncomment settings by removing the preceding #.
|
||||
#
|
||||
# Further documentation:
|
||||
# http://celeron.55.lt/~celeron55/minetest/wiki/doku.php
|
||||
# http://c55.me/minetest/wiki/doku.php
|
||||
#
|
||||
# NOTE: This file might not be up-to-date, refer to the
|
||||
# defaultsettings.cpp file for an up-to-date list:
|
||||
@@ -16,6 +16,7 @@
|
||||
#
|
||||
# A vim command to convert most of defaultsettings.cpp to conf file format:
|
||||
# :'<,'>s/\tg_settings\.setDefault("\([^"]*\)", "\([^"]*\)");.*/#\1 = \2/g
|
||||
# Note: Some of the settings are implemented in Lua
|
||||
|
||||
#
|
||||
# Client and server
|
||||
@@ -47,7 +48,6 @@
|
||||
#keymap_rangeselect = KEY_KEY_R
|
||||
#keymap_freemove = KEY_KEY_K
|
||||
#keymap_fastmove = KEY_KEY_J
|
||||
#keymap_frametime_graph = KEY_F1
|
||||
#keymap_screenshot = KEY_F12
|
||||
# Some (temporary) keys for debugging
|
||||
#keymap_print_debug_stacks = KEY_KEY_P
|
||||
@@ -58,11 +58,17 @@
|
||||
# (to not waste CPU power for no benefit)
|
||||
#fps_max = 60
|
||||
# The allowed adjustment range for the automatic rendering range adjustment
|
||||
#viewing_range_nodes_max = 300
|
||||
#viewing_range_nodes_min = 25
|
||||
#viewing_range_nodes_max = 160
|
||||
#viewing_range_nodes_min = 35
|
||||
# Initial window size
|
||||
#screenW = 800
|
||||
#screenH = 600
|
||||
#fullscreen = false
|
||||
#fullscreen_bpp = 24
|
||||
# Experimental option, might cause visible spaces between blocks
|
||||
# when set to higher number than 0
|
||||
#fsaa = 0
|
||||
#vsync = false
|
||||
# Address to connect to (#blank = start local server)
|
||||
#address =
|
||||
# Enable random user input, for testing
|
||||
@@ -78,8 +84,6 @@
|
||||
# Enable smooth lighting with simple ambient occlusion;
|
||||
# disable for speed or for different looks.
|
||||
#smooth_lighting = true
|
||||
# Whether to draw a frametime graph (for debugging frametime)
|
||||
#frametime_graph = false
|
||||
# Enable combining mainly used textures to a bigger one for improved speed
|
||||
# disable if it causes graphics glitches.
|
||||
#enable_texture_atlas = true
|
||||
@@ -110,19 +114,22 @@
|
||||
#console_color = (0,0,0)
|
||||
# In-game chat console background alpha (opaqueness, between 0 and 255)
|
||||
#console_alpha = 200
|
||||
# Sound settings
|
||||
#enable_sound = true
|
||||
#sound_volume = 0.7
|
||||
|
||||
#
|
||||
# Server stuff
|
||||
#
|
||||
|
||||
# Default game (default when creating a new world)
|
||||
#default_game = mesetint
|
||||
# Map directory (everything in the world is stored here)
|
||||
#map-dir = /custom/map
|
||||
#default_game = minetest
|
||||
# World directory (everything in the world is stored here)
|
||||
#map-dir = /custom/world
|
||||
# Message of the Day
|
||||
#motd = Welcome to this awesome Minetest server!
|
||||
# Maximum number of players connected simultaneously
|
||||
#max_users = 20
|
||||
#max_users = 100
|
||||
# Set to false to allow old clients to connect
|
||||
#strict_protocol_version_checking = true
|
||||
# Set to true to enable creative mode (unlimited inventory)
|
||||
@@ -139,10 +146,12 @@
|
||||
#default_password =
|
||||
# Available privileges: build, teleport, settime, privs, shout
|
||||
#default_privs = build, shout
|
||||
# Whether players are transferred to client without any range limit
|
||||
# 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
|
||||
|
||||
# Profiler data print interval. #0 = disable.
|
||||
#profiler_print_interval = 0
|
||||
@@ -155,17 +164,21 @@
|
||||
#max_simultaneous_block_sends_per_client = 2
|
||||
# how many blocks are flying in the wire simultaneously per server
|
||||
#max_simultaneous_block_sends_server_total = 8
|
||||
#max_block_send_distance = 7
|
||||
#max_block_generate_distance = 5
|
||||
#time_send_interval = 20
|
||||
# From how far blocks are sent to clients (value * 16 nodes)
|
||||
#max_block_send_distance = 10
|
||||
# From how far blocks are generated for clients (value * 16 nodes)
|
||||
#max_block_generate_distance = 6
|
||||
# Interval of sending time of day to clients
|
||||
#time_send_interval = 5
|
||||
# Length of day/night cycle. 72=20min, 360=4min, 1=24hour, 0=day/night/whatever stays unchanged
|
||||
#time_speed = 72
|
||||
#time_speed = 96
|
||||
#server_unload_unused_data_timeout = 29
|
||||
# Interval of saving important changes in the world
|
||||
#server_map_save_interval = 5.3
|
||||
# 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
|
||||
# Set to true to enable experimental features or stuff that is tested
|
||||
# (varies from version to version, usually not useful at all)
|
||||
#enable_experimental = false
|
||||
|
||||
# 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
|
||||
|
||||
5
misc/winresource.rc
Normal file
5
misc/winresource.rc
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <richedit.h>
|
||||
LANGUAGE 0, SUBLANG_NEUTRAL
|
||||
130 ICON "minetest-icon.ico"
|
||||
901
po/minetest.pot
901
po/minetest.pot
@@ -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 ""
|
||||
|
||||
@@ -67,7 +67,7 @@ endif(ENABLE_SOUND AND BUILD_CLIENT)
|
||||
|
||||
if(SOUND_PROBLEM)
|
||||
message(FATAL_ERROR "Sound enabled, but cannot be used.\n"
|
||||
"To continue, either fill in the required paths or disable sound.")
|
||||
"To continue, either fill in the required paths or disable sound. (-DENABLE_SOUND=0)")
|
||||
endif()
|
||||
if(USE_SOUND)
|
||||
set(sound_SRCS sound_openal.cpp)
|
||||
@@ -106,6 +106,8 @@ if(WIN32)
|
||||
CACHE FILEPATH "Path to zlibwapi.dll (for installation)")
|
||||
set(IRRLICHT_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../../irrlicht-1.7.2"
|
||||
CACHE PATH "irrlicht dir")
|
||||
set(MINGWM10_DLL ""
|
||||
CACHE FILEPATH "Path to mingwm10.dll (for installation)")
|
||||
if(ENABLE_SOUND)
|
||||
set(OPENAL_DLL "" CACHE FILEPATH "Path to OpenAL32.dll for installation (optional)")
|
||||
set(OGG_DLL "" CACHE FILEPATH "Path to libogg.dll for installation (optional)")
|
||||
@@ -153,18 +155,19 @@ configure_file(
|
||||
)
|
||||
|
||||
set(common_SRCS
|
||||
genericobject.cpp
|
||||
voxelalgorithms.cpp
|
||||
sound.cpp
|
||||
quicktune.cpp
|
||||
subgame.cpp
|
||||
inventorymanager.cpp
|
||||
mods.cpp
|
||||
serverremoteplayer.cpp
|
||||
content_abm.cpp
|
||||
craftdef.cpp
|
||||
nameidmapping.cpp
|
||||
itemdef.cpp
|
||||
nodedef.cpp
|
||||
luaentity_common.cpp
|
||||
object_properties.cpp
|
||||
scriptapi.cpp
|
||||
script.cpp
|
||||
log.cpp
|
||||
@@ -172,9 +175,9 @@ set(common_SRCS
|
||||
mapgen.cpp
|
||||
content_nodemeta.cpp
|
||||
content_mapnode.cpp
|
||||
auth.cpp
|
||||
collision.cpp
|
||||
nodemetadata.cpp
|
||||
nodetimer.cpp
|
||||
serverobject.cpp
|
||||
noise.cpp
|
||||
porting.cpp
|
||||
@@ -205,14 +208,19 @@ set(common_SRCS
|
||||
|
||||
# This gives us the icon
|
||||
if(WIN32)
|
||||
set(WINRESOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../misc/winresource.rc)
|
||||
if(MINGW)
|
||||
if(NOT CMAKE_RC_COMPILER)
|
||||
set(CMAKE_RC_COMPILER "windres.exe")
|
||||
endif()
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o
|
||||
COMMAND windres.exe -I${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-i${CMAKE_CURRENT_SOURCE_DIR}/winresource.rc
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o)
|
||||
COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-i${WINRESOURCE_FILE}
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SET(common_SRCS ${common_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o)
|
||||
else(MINGW) # Probably MSVC
|
||||
set(common_SRCS ${common_SRCS} winresource.rc)
|
||||
set(common_SRCS ${common_SRCS} ${WINRESOURCE_FILE})
|
||||
endif(MINGW)
|
||||
endif()
|
||||
|
||||
@@ -220,6 +228,7 @@ endif()
|
||||
set(minetest_SRCS
|
||||
${common_SRCS}
|
||||
${sound_SRCS}
|
||||
localplayer.cpp
|
||||
sky.cpp
|
||||
clientmap.cpp
|
||||
content_cso.cpp
|
||||
@@ -347,14 +356,18 @@ else()
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-unused-but-set-variable")
|
||||
endif(HAS_UNUSED_BUT_SET_VARIABLE_WARNING)
|
||||
endif()
|
||||
|
||||
|
||||
if(MINGW)
|
||||
set(OTHER_FLAGS "-mthreads -fexceptions")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_OSX_ARCHITECTURES i386 CACHE STRING "do not build for 64-bit" FORCE)
|
||||
set(ARCH i386)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O1 -Wall ${WARNING_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} ${OTHER_FLAGS} -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O1 -Wall ${WARNING_FLAGS} ${OTHER_FLAGS}")
|
||||
|
||||
if(USE_GPROF)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
|
||||
@@ -374,6 +387,9 @@ endif()
|
||||
# Installation
|
||||
#
|
||||
if(WIN32)
|
||||
if(MINGWM10_DLL)
|
||||
install(FILES ${MINGWM10_DLL} DESTINATION ${BINDIR})
|
||||
endif()
|
||||
if(DEFINED ZLIB_DLL)
|
||||
install(FILES ${ZLIB_DLL} DESTINATION ${BINDIR})
|
||||
endif()
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
300
src/auth.cpp
300
src/auth.cpp
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "auth.h"
|
||||
#include <fstream>
|
||||
#include <jmutexautolock.h>
|
||||
//#include "main.h" // for g_settings
|
||||
#include <sstream>
|
||||
#include "strfnd.h"
|
||||
#include "log.h"
|
||||
|
||||
std::set<std::string> privsToSet(u64 privs)
|
||||
{
|
||||
std::set<std::string> s;
|
||||
if(privs & PRIV_INTERACT)
|
||||
s.insert("interact");
|
||||
if(privs & PRIV_TELEPORT)
|
||||
s.insert("teleport");
|
||||
if(privs & PRIV_SETTIME)
|
||||
s.insert("settime");
|
||||
if(privs & PRIV_PRIVS)
|
||||
s.insert("privs");
|
||||
if(privs & PRIV_SHOUT)
|
||||
s.insert("shout");
|
||||
if(privs & PRIV_BAN)
|
||||
s.insert("ban");
|
||||
if(privs & PRIV_GIVE)
|
||||
s.insert("give");
|
||||
if(privs & PRIV_PASSWORD)
|
||||
s.insert("password");
|
||||
return s;
|
||||
}
|
||||
|
||||
// Convert a privileges value into a human-readable string,
|
||||
// with each component separated by a comma.
|
||||
std::string privsToString(u64 privs)
|
||||
{
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
if(privs & PRIV_INTERACT)
|
||||
os<<"interact,";
|
||||
if(privs & PRIV_TELEPORT)
|
||||
os<<"teleport,";
|
||||
if(privs & PRIV_SETTIME)
|
||||
os<<"settime,";
|
||||
if(privs & PRIV_PRIVS)
|
||||
os<<"privs,";
|
||||
if(privs & PRIV_SHOUT)
|
||||
os<<"shout,";
|
||||
if(privs & PRIV_BAN)
|
||||
os<<"ban,";
|
||||
if(privs & PRIV_GIVE)
|
||||
os<<"give,";
|
||||
if(privs & PRIV_PASSWORD)
|
||||
os<<"password,";
|
||||
if(os.tellp())
|
||||
{
|
||||
// Drop the trailing comma. (Why on earth can't
|
||||
// you truncate a C++ stream anyway???)
|
||||
std::string tmp = os.str();
|
||||
return tmp.substr(0, tmp.length() -1);
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// Converts a comma-seperated list of privilege values into a
|
||||
// privileges value. The reverse of privsToString(). Returns
|
||||
// PRIV_INVALID if there is anything wrong with the input.
|
||||
u64 stringToPrivs(std::string str)
|
||||
{
|
||||
u64 privs=0;
|
||||
Strfnd f(str);
|
||||
while(f.atend() == false)
|
||||
{
|
||||
std::string s = trim(f.next(","));
|
||||
if(s == "build")
|
||||
privs |= PRIV_INTERACT;
|
||||
else if(s == "interact")
|
||||
privs |= PRIV_INTERACT;
|
||||
else if(s == "teleport")
|
||||
privs |= PRIV_TELEPORT;
|
||||
else if(s == "settime")
|
||||
privs |= PRIV_SETTIME;
|
||||
else if(s == "privs")
|
||||
privs |= PRIV_PRIVS;
|
||||
else if(s == "shout")
|
||||
privs |= PRIV_SHOUT;
|
||||
else if(s == "ban")
|
||||
privs |= PRIV_BAN;
|
||||
else if(s == "give")
|
||||
privs |= PRIV_GIVE;
|
||||
else if(s == "password")
|
||||
privs |= PRIV_PASSWORD;
|
||||
else
|
||||
return PRIV_INVALID;
|
||||
}
|
||||
return privs;
|
||||
}
|
||||
|
||||
AuthManager::AuthManager(const std::string &authfilepath):
|
||||
m_authfilepath(authfilepath),
|
||||
m_modified(false)
|
||||
{
|
||||
m_mutex.Init();
|
||||
|
||||
try{
|
||||
load();
|
||||
}
|
||||
catch(SerializationError &e)
|
||||
{
|
||||
infostream<<"WARNING: AuthManager: creating "
|
||||
<<m_authfilepath<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
AuthManager::~AuthManager()
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
void AuthManager::load()
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
infostream<<"AuthManager: loading from "<<m_authfilepath<<std::endl;
|
||||
std::ifstream is(m_authfilepath.c_str(), std::ios::binary);
|
||||
if(is.good() == false)
|
||||
{
|
||||
infostream<<"AuthManager: failed loading from "<<m_authfilepath<<std::endl;
|
||||
throw SerializationError("AuthManager::load(): Couldn't open file");
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(is.eof() || is.good() == false)
|
||||
break;
|
||||
|
||||
// Read a line
|
||||
std::string line;
|
||||
std::getline(is, line, '\n');
|
||||
|
||||
std::istringstream iss(line);
|
||||
|
||||
// Read name
|
||||
std::string name;
|
||||
std::getline(iss, name, ':');
|
||||
|
||||
// Read password
|
||||
std::string pwd;
|
||||
std::getline(iss, pwd, ':');
|
||||
|
||||
// Read privileges
|
||||
std::string stringprivs;
|
||||
std::getline(iss, stringprivs, ':');
|
||||
u64 privs = stringToPrivs(stringprivs);
|
||||
|
||||
// Store it
|
||||
AuthData ad;
|
||||
ad.pwd = pwd;
|
||||
ad.privs = privs;
|
||||
m_authdata[name] = ad;
|
||||
}
|
||||
|
||||
m_modified = false;
|
||||
}
|
||||
|
||||
void AuthManager::save()
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
infostream<<"AuthManager: saving to "<<m_authfilepath<<std::endl;
|
||||
std::ofstream os(m_authfilepath.c_str(), std::ios::binary);
|
||||
if(os.good() == false)
|
||||
{
|
||||
infostream<<"AuthManager: failed saving to "<<m_authfilepath<<std::endl;
|
||||
throw SerializationError("AuthManager::save(): Couldn't open file");
|
||||
}
|
||||
|
||||
for(core::map<std::string, AuthData>::Iterator
|
||||
i = m_authdata.getIterator();
|
||||
i.atEnd()==false; i++)
|
||||
{
|
||||
std::string name = i.getNode()->getKey();
|
||||
if(name == "")
|
||||
continue;
|
||||
AuthData ad = i.getNode()->getValue();
|
||||
os<<name<<":"<<ad.pwd<<":"<<privsToString(ad.privs)<<"\n";
|
||||
}
|
||||
|
||||
m_modified = false;
|
||||
}
|
||||
|
||||
bool AuthManager::exists(const std::string &username)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
core::map<std::string, AuthData>::Node *n;
|
||||
n = m_authdata.find(username);
|
||||
if(n == NULL)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AuthManager::set(const std::string &username, AuthData ad)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
m_authdata[username] = ad;
|
||||
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
void AuthManager::add(const std::string &username)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
m_authdata[username] = AuthData();
|
||||
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
std::string AuthManager::getPassword(const std::string &username)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
core::map<std::string, AuthData>::Node *n;
|
||||
n = m_authdata.find(username);
|
||||
if(n == NULL)
|
||||
throw AuthNotFoundException("");
|
||||
|
||||
return n->getValue().pwd;
|
||||
}
|
||||
|
||||
void AuthManager::setPassword(const std::string &username,
|
||||
const std::string &password)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
core::map<std::string, AuthData>::Node *n;
|
||||
n = m_authdata.find(username);
|
||||
if(n == NULL)
|
||||
throw AuthNotFoundException("");
|
||||
|
||||
AuthData ad = n->getValue();
|
||||
ad.pwd = password;
|
||||
n->setValue(ad);
|
||||
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
u64 AuthManager::getPrivs(const std::string &username)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
core::map<std::string, AuthData>::Node *n;
|
||||
n = m_authdata.find(username);
|
||||
if(n == NULL)
|
||||
throw AuthNotFoundException("");
|
||||
|
||||
return n->getValue().privs;
|
||||
}
|
||||
|
||||
void AuthManager::setPrivs(const std::string &username, u64 privs)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
core::map<std::string, AuthData>::Node *n;
|
||||
n = m_authdata.find(username);
|
||||
if(n == NULL)
|
||||
throw AuthNotFoundException("");
|
||||
|
||||
AuthData ad = n->getValue();
|
||||
ad.privs = privs;
|
||||
n->setValue(ad);
|
||||
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
bool AuthManager::isModified()
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
return m_modified;
|
||||
}
|
||||
|
||||
|
||||
107
src/auth.h
107
src/auth.h
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef AUTH_HEADER
|
||||
#define AUTH_HEADER
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <jthread.h>
|
||||
#include <jmutex.h>
|
||||
#include "irrlichttypes.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
// Player privileges. These form a bitmask stored in the privs field
|
||||
// of the player, and define things they're allowed to do. See also
|
||||
// the static methods Player::privsToString and stringToPrivs that
|
||||
// convert these to human-readable form.
|
||||
const u64 PRIV_INTERACT = 1; // Can interact
|
||||
const u64 PRIV_TELEPORT = 2; // Can teleport
|
||||
const u64 PRIV_SETTIME = 4; // Can set the time
|
||||
const u64 PRIV_PRIVS = 8; // Can grant and revoke privileges
|
||||
const u64 PRIV_SERVER = 16; // Can manage the server (e.g. shutodwn
|
||||
// ,settings)
|
||||
const u64 PRIV_SHOUT = 32; // Can broadcast chat messages to all
|
||||
// players
|
||||
const u64 PRIV_BAN = 64; // Can ban players
|
||||
const u64 PRIV_GIVE = 128; // Can give stuff
|
||||
const u64 PRIV_PASSWORD = 256; // Can set other players' passwords
|
||||
|
||||
// Default privileges - these can be overriden for new players using the
|
||||
// config option "default_privs" - however, this value still applies for
|
||||
// players that existed before the privileges system was added.
|
||||
const u64 PRIV_DEFAULT = PRIV_INTERACT|PRIV_SHOUT;
|
||||
const u64 PRIV_ALL = 0x7FFFFFFFFFFFFFFFULL;
|
||||
const u64 PRIV_INVALID = 0x8000000000000000ULL;
|
||||
|
||||
std::set<std::string> privsToSet(u64 privs);
|
||||
|
||||
// Convert a privileges value into a human-readable string,
|
||||
// with each component separated by a comma.
|
||||
std::string privsToString(u64 privs);
|
||||
|
||||
// Converts a comma-seperated list of privilege values into a
|
||||
// privileges value. The reverse of privsToString(). Returns
|
||||
// PRIV_INVALID if there is anything wrong with the input.
|
||||
u64 stringToPrivs(std::string str);
|
||||
|
||||
struct AuthData
|
||||
{
|
||||
std::string pwd;
|
||||
u64 privs;
|
||||
|
||||
AuthData():
|
||||
privs(PRIV_DEFAULT)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class AuthNotFoundException : public BaseException
|
||||
{
|
||||
public:
|
||||
AuthNotFoundException(const char *s):
|
||||
BaseException(s)
|
||||
{}
|
||||
};
|
||||
|
||||
class AuthManager
|
||||
{
|
||||
public:
|
||||
AuthManager(const std::string &authfilepath);
|
||||
~AuthManager();
|
||||
void load();
|
||||
void save();
|
||||
bool exists(const std::string &username);
|
||||
void set(const std::string &username, AuthData ad);
|
||||
void add(const std::string &username);
|
||||
std::string getPassword(const std::string &username);
|
||||
void setPassword(const std::string &username,
|
||||
const std::string &password);
|
||||
u64 getPrivs(const std::string &username);
|
||||
void setPrivs(const std::string &username, u64 privs);
|
||||
bool isModified();
|
||||
private:
|
||||
JMutex m_mutex;
|
||||
std::string m_authfilepath;
|
||||
core::map<std::string, AuthData> m_authdata;
|
||||
bool m_modified;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -38,6 +38,13 @@ static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
bool base64_is_valid(std::string const& s)
|
||||
{
|
||||
for(int i=0; i<s.size(); i++)
|
||||
if(!is_base64(s[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <string>
|
||||
|
||||
bool base64_is_valid(std::string const& s);
|
||||
std::string base64_encode(unsigned char const* , unsigned int len);
|
||||
std::string base64_decode(std::string const& s);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -290,6 +290,9 @@ 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;
|
||||
// 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
|
||||
m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y));
|
||||
m_cameranode->setAspectRatio(m_aspect);
|
||||
m_cameranode->setFOV(m_fov_y);
|
||||
@@ -348,7 +351,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
|
||||
if ((hypot(speed.X, speed.Z) > BS) &&
|
||||
(player->touching_ground) &&
|
||||
(g_settings->getBool("view_bobbing") == true) &&
|
||||
(g_settings->getBool("free_move") == false))
|
||||
(g_settings->getBool("free_move") == false ||
|
||||
!m_gamedef->checkLocalPrivilege("fly")))
|
||||
{
|
||||
// Start animation
|
||||
m_view_bobbing_state = 1;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
114
src/client.cpp
114
src/client.cpp
@@ -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.
|
||||
*/
|
||||
@@ -1397,45 +1397,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||
}
|
||||
else if(command == TOCLIENT_PLAYERITEM)
|
||||
{
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
|
||||
u16 count = readU16(is);
|
||||
|
||||
for (u16 i = 0; i < count; ++i) {
|
||||
u16 peer_id = readU16(is);
|
||||
Player *player = m_env.getPlayer(peer_id);
|
||||
|
||||
if (player == NULL)
|
||||
{
|
||||
infostream<<"Client: ignoring player item "
|
||||
<< deSerializeString(is)
|
||||
<< " for non-existing peer id " << peer_id
|
||||
<< std::endl;
|
||||
continue;
|
||||
} else if (player->isLocal()) {
|
||||
infostream<<"Client: ignoring player item "
|
||||
<< deSerializeString(is)
|
||||
<< " for local player" << std::endl;
|
||||
continue;
|
||||
} else {
|
||||
InventoryList *inv = player->inventory.getList("main");
|
||||
std::string itemstring(deSerializeString(is));
|
||||
ItemStack item;
|
||||
item.deSerialize(itemstring, m_itemdef);
|
||||
inv->changeItem(0, item);
|
||||
if(itemstring.empty())
|
||||
{
|
||||
infostream<<"Client: empty player item for peer "
|
||||
<<peer_id<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
infostream<<"Client: player item for peer "
|
||||
<<peer_id<<": "<<itemstring<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
infostream<<"Client: WARNING: Ignoring TOCLIENT_PLAYERITEM"<<std::endl;
|
||||
}
|
||||
else if(command == TOCLIENT_DEATHSCREEN)
|
||||
{
|
||||
@@ -1677,10 +1639,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||
int client_id = -1;
|
||||
switch(type){
|
||||
case 0: // local
|
||||
client_id = m_sound->playSound(name, false, gain);
|
||||
client_id = m_sound->playSound(name, loop, gain);
|
||||
break;
|
||||
case 1: // positional
|
||||
client_id = m_sound->playSoundAt(name, false, gain, pos);
|
||||
client_id = m_sound->playSoundAt(name, loop, gain, pos);
|
||||
break;
|
||||
case 2: { // object
|
||||
ClientActiveObject *cao = m_env.getActiveObject(object_id);
|
||||
@@ -1712,6 +1674,21 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||
m_sound->stopSound(client_id);
|
||||
}
|
||||
}
|
||||
else if(command == TOCLIENT_PRIVILEGES)
|
||||
{
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
|
||||
m_privileges.clear();
|
||||
infostream<<"Client: Privileges updated: ";
|
||||
u16 num_privileges = readU16(is);
|
||||
for(u16 i=0; i<num_privileges; i++){
|
||||
std::string priv = deSerializeString(is);
|
||||
m_privileges.insert(priv);
|
||||
infostream<<priv<<" ";
|
||||
}
|
||||
infostream<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
infostream<<"Client: Ignoring unknown command "
|
||||
@@ -1763,33 +1740,23 @@ void Client::interact(u8 action, const PointedThing& pointed)
|
||||
Send(0, data, true);
|
||||
}
|
||||
|
||||
void Client::sendSignNodeText(v3s16 p, std::string text)
|
||||
void Client::sendNodemetaFields(v3s16 p, const std::string &formname,
|
||||
const std::map<std::string, std::string> &fields)
|
||||
{
|
||||
/*
|
||||
u16 command
|
||||
v3s16 p
|
||||
u16 textlen
|
||||
textdata
|
||||
*/
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
u8 buf[12];
|
||||
|
||||
// Write command
|
||||
writeU16(buf, TOSERVER_SIGNNODETEXT);
|
||||
os.write((char*)buf, 2);
|
||||
|
||||
// Write p
|
||||
writeV3S16(buf, p);
|
||||
os.write((char*)buf, 6);
|
||||
|
||||
u16 textlen = text.size();
|
||||
// Write text length
|
||||
writeS16(buf, textlen);
|
||||
os.write((char*)buf, 2);
|
||||
writeU16(os, TOSERVER_NODEMETA_FIELDS);
|
||||
writeV3S16(os, p);
|
||||
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);
|
||||
}
|
||||
|
||||
// Write text
|
||||
os.write((char*)text.c_str(), textlen);
|
||||
|
||||
// Make data buffer
|
||||
std::string s = os.str();
|
||||
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
|
||||
@@ -2371,32 +2338,41 @@ ClientEvent Client::getClientEvent()
|
||||
|
||||
void Client::afterContentReceived()
|
||||
{
|
||||
verbosestream<<"Client::afterContentReceived() started"<<std::endl;
|
||||
assert(m_itemdef_received);
|
||||
assert(m_nodedef_received);
|
||||
assert(m_media_received);
|
||||
|
||||
|
||||
// remove the information about which checksum each texture
|
||||
// ought to have
|
||||
m_media_name_sha1_map.clear();
|
||||
|
||||
// Rebuild inherited images and recreate textures
|
||||
verbosestream<<"Rebuilding images and textures"<<std::endl;
|
||||
m_tsrc->rebuildImagesAndTextures();
|
||||
|
||||
// Update texture atlas
|
||||
verbosestream<<"Updating texture atlas"<<std::endl;
|
||||
if(g_settings->getBool("enable_texture_atlas"))
|
||||
m_tsrc->buildMainAtlas(this);
|
||||
|
||||
// Update node aliases
|
||||
verbosestream<<"Updating node aliases"<<std::endl;
|
||||
m_nodedef->updateAliases(m_itemdef);
|
||||
|
||||
// Update node textures
|
||||
verbosestream<<"Updating node textures"<<std::endl;
|
||||
m_nodedef->updateTextures(m_tsrc);
|
||||
|
||||
// Update item textures and meshes
|
||||
verbosestream<<"Updating item textures and meshes"<<std::endl;
|
||||
m_itemdef->updateTexturesAndMeshes(this);
|
||||
|
||||
// Start mesh update thread after setting up content definitions
|
||||
verbosestream<<"Starting mesh update thread"<<std::endl;
|
||||
m_mesh_update_thread.Start();
|
||||
|
||||
verbosestream<<"Client::afterContentReceived() done"<<std::endl;
|
||||
}
|
||||
|
||||
float Client::getRTT(void)
|
||||
|
||||
33
src/client.h
33
src/client.h
@@ -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,8 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef CLIENT_HEADER
|
||||
#define CLIENT_HEADER
|
||||
|
||||
#ifndef SERVER
|
||||
|
||||
#include "connection.h"
|
||||
#include "environment.h"
|
||||
#include "common_irrlicht.h"
|
||||
@@ -35,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "inventorymanager.h"
|
||||
#include "filesys.h"
|
||||
#include "filecache.h"
|
||||
#include "localplayer.h"
|
||||
|
||||
struct MeshMakeData;
|
||||
class MapBlockMesh;
|
||||
@@ -211,11 +210,12 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
|
||||
|
||||
void interact(u8 action, const PointedThing& pointed);
|
||||
|
||||
void sendSignNodeText(v3s16 p, std::string text);
|
||||
void sendNodemetaFields(v3s16 p, 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,
|
||||
const std::wstring newpassword);
|
||||
const std::wstring newpassword);
|
||||
void sendDamage(u8 damage);
|
||||
void sendRespawn();
|
||||
|
||||
@@ -262,14 +262,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
|
||||
|
||||
u16 getHP();
|
||||
|
||||
float getAvgRtt()
|
||||
{
|
||||
try{
|
||||
return m_con.GetPeerAvgRTT(PEER_ID_SERVER);
|
||||
} catch(con::PeerNotFoundException){
|
||||
return 1337;
|
||||
}
|
||||
}
|
||||
bool checkPrivilege(const std::string &priv)
|
||||
{ return (m_privileges.count(priv) != 0); }
|
||||
|
||||
bool getChatMessage(std::wstring &message);
|
||||
void typeChatMessage(const std::wstring& message);
|
||||
@@ -312,6 +306,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||
virtual ISoundManager* getSoundManager();
|
||||
virtual MtEventManager* getEventManager();
|
||||
virtual bool checkLocalPrivilege(const std::string &priv)
|
||||
{ return checkPrivilege(priv); }
|
||||
|
||||
private:
|
||||
|
||||
@@ -392,9 +388,10 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
|
||||
std::map<int, s32> m_sounds_client_to_server;
|
||||
// And relations to objects
|
||||
std::map<int, u16> m_sounds_to_objects;
|
||||
};
|
||||
|
||||
#endif // !SERVER
|
||||
// Privileges
|
||||
std::set<std::string> m_privileges;
|
||||
};
|
||||
|
||||
#endif // !CLIENT_HEADER
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -324,6 +324,16 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
Occlusion culling
|
||||
*/
|
||||
|
||||
// No occlusion culling when free_move is on and camera is
|
||||
// inside ground
|
||||
bool occlusion_culling_enabled = true;
|
||||
if(g_settings->getBool("free_move")){
|
||||
MapNode n = getNodeNoEx(cam_pos_nodes);
|
||||
if(n.getContent() == CONTENT_IGNORE ||
|
||||
nodemgr->get(n).solidness == 2)
|
||||
occlusion_culling_enabled = false;
|
||||
}
|
||||
|
||||
v3s16 cpn = block->getPos() * MAP_BLOCKSIZE;
|
||||
cpn += v3s16(MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2);
|
||||
float step = BS*1;
|
||||
@@ -334,6 +344,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
s16 bs2 = MAP_BLOCKSIZE/2 + 1;
|
||||
u32 needed_count = 1;
|
||||
if(
|
||||
occlusion_culling_enabled &&
|
||||
isOccluded(this, spn, cpn + v3s16(0,0,0),
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
|
||||
@@ -598,9 +609,9 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
|
||||
if(z_directions[0].X < -99){
|
||||
for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
|
||||
z_directions[i] = v3f(
|
||||
0.01 * myrand_range(-80, 80),
|
||||
0.01 * myrand_range(-100, 100),
|
||||
1.0,
|
||||
0.01 * myrand_range(-80, 80)
|
||||
0.01 * myrand_range(-100, 100)
|
||||
);
|
||||
z_offsets[i] = 0.01 * myrand_range(0,100);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -50,9 +50,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
PROTOCOL_VERSION 9:
|
||||
ContentFeatures and NodeDefManager use a different serialization
|
||||
format; better for future version cross-compatibility
|
||||
Many things
|
||||
PROTOCOL_VERSION 10:
|
||||
TOCLIENT_PRIVILEGES
|
||||
Version raised to force 'fly' and 'fast' privileges into effect.
|
||||
*/
|
||||
|
||||
#define PROTOCOL_VERSION 9
|
||||
#define PROTOCOL_VERSION 10
|
||||
|
||||
#define PROTOCOL_ID 0x4f457403
|
||||
|
||||
@@ -200,7 +204,7 @@ enum ToClientCommand
|
||||
wstring reason
|
||||
*/
|
||||
|
||||
TOCLIENT_PLAYERITEM = 0x36,
|
||||
TOCLIENT_PLAYERITEM = 0x36, // Obsolete
|
||||
/*
|
||||
u16 command
|
||||
u16 count of player items
|
||||
@@ -291,6 +295,15 @@ enum ToClientCommand
|
||||
u16 command
|
||||
s32 sound_id
|
||||
*/
|
||||
|
||||
TOCLIENT_PRIVILEGES = 0x41,
|
||||
/*
|
||||
u16 command
|
||||
u16 number of privileges
|
||||
for each privilege
|
||||
u16 len
|
||||
u8[len] privilege
|
||||
*/
|
||||
};
|
||||
|
||||
enum ToServerCommand
|
||||
@@ -402,7 +415,7 @@ enum ToServerCommand
|
||||
wstring message
|
||||
*/
|
||||
|
||||
TOSERVER_SIGNNODETEXT = 0x33,
|
||||
TOSERVER_SIGNNODETEXT = 0x33, // obsolete
|
||||
/*
|
||||
u16 command
|
||||
v3s16 p
|
||||
@@ -471,6 +484,20 @@ enum ToServerCommand
|
||||
s32[len] sound_id
|
||||
*/
|
||||
|
||||
TOSERVER_NODEMETA_FIELDS = 0x3b,
|
||||
/*
|
||||
u16 command
|
||||
v3s16 p
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
171
src/clouds.cpp
171
src/clouds.cpp
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -29,6 +29,10 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
|
||||
{
|
||||
collisionMoveResult result;
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -196,6 +200,10 @@ collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
|
||||
f32 dtime, v3f &pos_f, v3f &speed_f)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -353,9 +353,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;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -99,9 +99,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// Length of cracking animation in count of images
|
||||
#define CRACK_ANIMATION_LENGTH 5
|
||||
|
||||
// Some stuff needed by old code moved to here from heightmap.h
|
||||
#define GROUNDHEIGHT_NOTFOUND_SETVALUE (-10e6)
|
||||
#define GROUNDHEIGHT_VALID_MINVALUE ( -9e6)
|
||||
// Maximum hit points of a player
|
||||
#define PLAYER_MAX_HP 20
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -36,9 +36,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "content_cso.h"
|
||||
#include "sound.h"
|
||||
#include "nodedef.h"
|
||||
#include "localplayer.h"
|
||||
class Settings;
|
||||
struct ToolCapabilities;
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
|
||||
|
||||
/*
|
||||
@@ -533,28 +536,37 @@ void ItemCAO::initialize(const std::string &data)
|
||||
}
|
||||
|
||||
/*
|
||||
LuaEntityCAO
|
||||
GenericCAO
|
||||
*/
|
||||
|
||||
#include "luaentity_common.h"
|
||||
#include "genericobject.h"
|
||||
|
||||
class LuaEntityCAO : public ClientActiveObject
|
||||
class GenericCAO : public ClientActiveObject
|
||||
{
|
||||
private:
|
||||
// Only set at initialization
|
||||
std::string m_name;
|
||||
bool m_is_player;
|
||||
bool m_is_local_player; // determined locally
|
||||
// Property-ish things
|
||||
ObjectProperties m_prop;
|
||||
//
|
||||
scene::ISceneManager *m_smgr;
|
||||
IrrlichtDevice *m_irr;
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
scene::IMeshSceneNode *m_meshnode;
|
||||
scene::IBillboardSceneNode *m_spritenode;
|
||||
scene::ITextSceneNode* m_textnode;
|
||||
v3f m_position;
|
||||
v3f m_velocity;
|
||||
v3f m_acceleration;
|
||||
float m_yaw;
|
||||
s16 m_hp;
|
||||
struct LuaEntityProperties *m_prop;
|
||||
SmoothTranslator pos_translator;
|
||||
// Spritesheet/animation stuff
|
||||
v2f m_tx_size;
|
||||
v2s16 m_tx_basepos;
|
||||
bool m_initial_tx_basepos_set;
|
||||
bool m_tx_select_horiz_by_yawpitch;
|
||||
int m_anim_frame;
|
||||
int m_anim_num_frames;
|
||||
@@ -562,28 +574,40 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
float m_anim_timer;
|
||||
ItemGroupList m_armor_groups;
|
||||
float m_reset_textures_timer;
|
||||
bool m_visuals_expired;
|
||||
float m_step_distance_counter;
|
||||
u8 m_last_light;
|
||||
|
||||
public:
|
||||
LuaEntityCAO(IGameDef *gamedef, ClientEnvironment *env):
|
||||
GenericCAO(IGameDef *gamedef, ClientEnvironment *env):
|
||||
ClientActiveObject(0, gamedef, env),
|
||||
//
|
||||
m_is_player(false),
|
||||
m_is_local_player(false),
|
||||
//
|
||||
m_smgr(NULL),
|
||||
m_irr(NULL),
|
||||
m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.),
|
||||
m_meshnode(NULL),
|
||||
m_spritenode(NULL),
|
||||
m_textnode(NULL),
|
||||
m_position(v3f(0,10*BS,0)),
|
||||
m_velocity(v3f(0,0,0)),
|
||||
m_acceleration(v3f(0,0,0)),
|
||||
m_yaw(0),
|
||||
m_hp(1),
|
||||
m_prop(new LuaEntityProperties),
|
||||
m_tx_size(1,1),
|
||||
m_tx_basepos(0,0),
|
||||
m_initial_tx_basepos_set(false),
|
||||
m_tx_select_horiz_by_yawpitch(false),
|
||||
m_anim_frame(0),
|
||||
m_anim_num_frames(1),
|
||||
m_anim_framelength(0.2),
|
||||
m_anim_timer(0),
|
||||
m_reset_textures_timer(-1)
|
||||
m_reset_textures_timer(-1),
|
||||
m_visuals_expired(false),
|
||||
m_step_distance_counter(0),
|
||||
m_last_light(255)
|
||||
{
|
||||
if(gamedef == NULL)
|
||||
ClientActiveObject::registerType(getType(), create);
|
||||
@@ -591,108 +615,62 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
|
||||
void initialize(const std::string &data)
|
||||
{
|
||||
infostream<<"LuaEntityCAO: Got init data"<<std::endl;
|
||||
|
||||
infostream<<"GenericCAO: Got init data"<<std::endl;
|
||||
std::istringstream is(data, std::ios::binary);
|
||||
// version
|
||||
u8 version = readU8(is);
|
||||
// check version
|
||||
if(version != 1)
|
||||
if(version != 0){
|
||||
errorstream<<"GenericCAO: Unsupported init data version"
|
||||
<<std::endl;
|
||||
return;
|
||||
// pos
|
||||
}
|
||||
m_name = deSerializeString(is);
|
||||
m_is_player = readU8(is);
|
||||
m_position = readV3F1000(is);
|
||||
// yaw
|
||||
m_yaw = readF1000(is);
|
||||
// hp
|
||||
m_hp = readS16(is);
|
||||
// properties
|
||||
std::istringstream prop_is(deSerializeLongString(is), std::ios::binary);
|
||||
m_prop->deSerialize(prop_is);
|
||||
|
||||
infostream<<"m_prop: "<<m_prop->dump()<<std::endl;
|
||||
|
||||
m_selection_box = m_prop->collisionbox;
|
||||
m_selection_box.MinEdge *= BS;
|
||||
m_selection_box.MaxEdge *= BS;
|
||||
|
||||
pos_translator.init(m_position);
|
||||
|
||||
m_tx_size.X = 1.0 / m_prop->spritediv.X;
|
||||
m_tx_size.Y = 1.0 / m_prop->spritediv.Y;
|
||||
m_tx_basepos.X = m_tx_size.X * m_prop->initial_sprite_basepos.X;
|
||||
m_tx_basepos.Y = m_tx_size.Y * m_prop->initial_sprite_basepos.Y;
|
||||
|
||||
int num_messages = readU8(is);
|
||||
for(int i=0; i<num_messages; i++){
|
||||
std::string message = deSerializeLongString(is);
|
||||
processMessage(message);
|
||||
}
|
||||
|
||||
pos_translator.init(m_position);
|
||||
updateNodePos();
|
||||
|
||||
if(m_is_player){
|
||||
Player *player = m_env->getPlayer(m_name.c_str());
|
||||
if(player && player->isLocal()){
|
||||
m_is_local_player = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~LuaEntityCAO()
|
||||
~GenericCAO()
|
||||
{
|
||||
delete m_prop;
|
||||
}
|
||||
|
||||
static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env)
|
||||
{
|
||||
return new LuaEntityCAO(gamedef, env);
|
||||
return new GenericCAO(gamedef, env);
|
||||
}
|
||||
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_LUAENTITY;
|
||||
return ACTIVEOBJECT_TYPE_GENERIC;
|
||||
}
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
{
|
||||
if(!m_prop.is_visible || m_is_local_player)
|
||||
return NULL;
|
||||
return &m_selection_box;
|
||||
}
|
||||
v3f getPosition()
|
||||
{
|
||||
return pos_translator.vect_show;
|
||||
}
|
||||
|
||||
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
|
||||
IrrlichtDevice *irr)
|
||||
{
|
||||
m_smgr = smgr;
|
||||
|
||||
if(m_meshnode != NULL || m_spritenode != NULL)
|
||||
return;
|
||||
|
||||
//video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||
|
||||
if(m_prop->visual == "sprite"){
|
||||
infostream<<"LuaEntityCAO::addToScene(): single_sprite"<<std::endl;
|
||||
m_spritenode = smgr->addBillboardSceneNode(
|
||||
NULL, v2f(1, 1), v3f(0,0,0), -1);
|
||||
m_spritenode->setMaterialTexture(0,
|
||||
tsrc->getTextureRaw("unknown_block.png"));
|
||||
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
|
||||
m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
||||
m_spritenode->setColor(video::SColor(255,0,0,0));
|
||||
m_spritenode->setVisible(false); /* Set visible when brightness is known */
|
||||
m_spritenode->setSize(m_prop->visual_size*BS);
|
||||
{
|
||||
const float txs = 1.0 / 1;
|
||||
const float tys = 1.0 / 1;
|
||||
setBillboardTextureMatrix(m_spritenode,
|
||||
txs, tys, 0, 0);
|
||||
}
|
||||
} else if(m_prop->visual == "cube"){
|
||||
infostream<<"LuaEntityCAO::addToScene(): cube"<<std::endl;
|
||||
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
|
||||
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
|
||||
mesh->drop();
|
||||
|
||||
m_meshnode->setScale(v3f(1));
|
||||
// Will be shown when we know the brightness
|
||||
m_meshnode->setVisible(false);
|
||||
} else {
|
||||
infostream<<"LuaEntityCAO::addToScene(): \""<<m_prop->visual
|
||||
<<"\" not supported"<<std::endl;
|
||||
}
|
||||
updateTextures("");
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
void removeFromScene()
|
||||
{
|
||||
@@ -706,10 +684,157 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
}
|
||||
}
|
||||
|
||||
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
|
||||
IrrlichtDevice *irr)
|
||||
{
|
||||
m_smgr = smgr;
|
||||
m_irr = irr;
|
||||
|
||||
if(m_meshnode != NULL || m_spritenode != NULL)
|
||||
return;
|
||||
|
||||
m_visuals_expired = false;
|
||||
|
||||
if(!m_prop.is_visible || m_is_local_player)
|
||||
return;
|
||||
|
||||
//video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||
|
||||
if(m_prop.visual == "sprite"){
|
||||
infostream<<"GenericCAO::addToScene(): single_sprite"<<std::endl;
|
||||
m_spritenode = smgr->addBillboardSceneNode(
|
||||
NULL, v2f(1, 1), v3f(0,0,0), -1);
|
||||
m_spritenode->setMaterialTexture(0,
|
||||
tsrc->getTextureRaw("unknown_block.png"));
|
||||
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
|
||||
m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
||||
u8 li = m_last_light;
|
||||
m_spritenode->setColor(video::SColor(255,li,li,li));
|
||||
m_spritenode->setSize(m_prop.visual_size*BS);
|
||||
{
|
||||
const float txs = 1.0 / 1;
|
||||
const float tys = 1.0 / 1;
|
||||
setBillboardTextureMatrix(m_spritenode,
|
||||
txs, tys, 0, 0);
|
||||
}
|
||||
}
|
||||
else if(m_prop.visual == "upright_sprite")
|
||||
{
|
||||
scene::SMesh *mesh = new scene::SMesh();
|
||||
double dx = BS*m_prop.visual_size.X/2;
|
||||
double dy = BS*m_prop.visual_size.Y/2;
|
||||
{ // Front
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
u8 li = m_last_light;
|
||||
video::SColor c(255,li,li,li);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-dx,-dy,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(dx,-dy,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(dx,dy,0, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-dx,dy,0, 0,0,0, c, 0,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
}
|
||||
{ // Back
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
u8 li = m_last_light;
|
||||
video::SColor c(255,li,li,li);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(dx,-dy,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(-dx,-dy,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(-dx,dy,0, 0,0,0, c, 0,0),
|
||||
video::S3DVertex(dx,dy,0, 0,0,0, c, 1,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
}
|
||||
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
|
||||
mesh->drop();
|
||||
// Set it to use the materials of the meshbuffers directly.
|
||||
// This is needed for changing the texture in the future
|
||||
m_meshnode->setReadOnlyMaterials(true);
|
||||
}
|
||||
else if(m_prop.visual == "cube"){
|
||||
infostream<<"GenericCAO::addToScene(): cube"<<std::endl;
|
||||
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
|
||||
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
|
||||
mesh->drop();
|
||||
|
||||
m_meshnode->setScale(v3f(m_prop.visual_size.X,
|
||||
m_prop.visual_size.Y,
|
||||
m_prop.visual_size.X));
|
||||
u8 li = m_last_light;
|
||||
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
|
||||
} else if(m_prop.visual == "wielditem"){
|
||||
infostream<<"GenericCAO::addToScene(): node"<<std::endl;
|
||||
infostream<<"textures: "<<m_prop.textures.size()<<std::endl;
|
||||
if(m_prop.textures.size() >= 1){
|
||||
infostream<<"textures[0]: "<<m_prop.textures[0]<<std::endl;
|
||||
IItemDefManager *idef = m_gamedef->idef();
|
||||
ItemStack item(m_prop.textures[0], 1, 0, "", idef);
|
||||
scene::IMesh *mesh = item.getDefinition(idef).wield_mesh;
|
||||
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
|
||||
|
||||
m_meshnode->setScale(v3f(m_prop.visual_size.X/2,
|
||||
m_prop.visual_size.Y/2,
|
||||
m_prop.visual_size.X/2));
|
||||
u8 li = m_last_light;
|
||||
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
|
||||
}
|
||||
} else {
|
||||
infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual
|
||||
<<"\" not supported"<<std::endl;
|
||||
}
|
||||
updateTextures("");
|
||||
|
||||
scene::ISceneNode *node = NULL;
|
||||
if(m_spritenode)
|
||||
node = m_spritenode;
|
||||
else if(m_meshnode)
|
||||
node = m_meshnode;
|
||||
if(node && m_is_player && !m_is_local_player){
|
||||
// Add a text node for showing the name
|
||||
gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
|
||||
std::wstring wname = narrow_to_wide(m_name);
|
||||
m_textnode = smgr->addTextSceneNode(gui->getBuiltInFont(),
|
||||
wname.c_str(), video::SColor(255,255,255,255), node);
|
||||
m_textnode->setPosition(v3f(0, BS*1.1, 0));
|
||||
}
|
||||
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
void expireVisuals()
|
||||
{
|
||||
m_visuals_expired = true;
|
||||
}
|
||||
|
||||
void updateLight(u8 light_at_pos)
|
||||
{
|
||||
bool is_visible = (m_hp != 0);
|
||||
u8 li = decode_light(light_at_pos);
|
||||
m_last_light = li;
|
||||
video::SColor color(255,li,li,li);
|
||||
if(m_meshnode){
|
||||
setMeshColor(m_meshnode->getMesh(), color);
|
||||
@@ -730,6 +855,9 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
{
|
||||
if(m_meshnode){
|
||||
m_meshnode->setPosition(pos_translator.vect_show);
|
||||
v3f rot = m_meshnode->getRotation();
|
||||
rot.Y = -m_yaw;
|
||||
m_meshnode->setRotation(rot);
|
||||
}
|
||||
if(m_spritenode){
|
||||
m_spritenode->setPosition(pos_translator.vect_show);
|
||||
@@ -738,8 +866,16 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
|
||||
void step(float dtime, ClientEnvironment *env)
|
||||
{
|
||||
if(m_prop->physical){
|
||||
core::aabbox3d<f32> box = m_prop->collisionbox;
|
||||
v3f lastpos = pos_translator.vect_show;
|
||||
|
||||
if(m_visuals_expired && m_smgr && m_irr){
|
||||
m_visuals_expired = false;
|
||||
removeFromScene();
|
||||
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
|
||||
}
|
||||
|
||||
if(m_prop.physical){
|
||||
core::aabbox3d<f32> box = m_prop.collisionbox;
|
||||
box.MinEdge *= BS;
|
||||
box.MaxEdge *= BS;
|
||||
collisionMoveResult moveresult;
|
||||
@@ -767,6 +903,20 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
|
||||
m_step_distance_counter += moved;
|
||||
if(m_step_distance_counter > 1.5*BS){
|
||||
m_step_distance_counter = 0;
|
||||
if(!m_is_local_player && m_prop.makes_footstep_sound){
|
||||
INodeDefManager *ndef = m_gamedef->ndef();
|
||||
v3s16 p = floatToInt(getPosition() + v3f(0,
|
||||
(m_prop.collisionbox.MinEdge.Y-0.5)*BS, 0), BS);
|
||||
MapNode n = m_env->getMap().getNodeNoEx(p);
|
||||
SimpleSoundSpec spec = ndef->get(n).sound_footstep;
|
||||
m_gamedef->sound()->playSoundAt(spec, false, getPosition());
|
||||
}
|
||||
}
|
||||
|
||||
m_anim_timer += dtime;
|
||||
if(m_anim_timer >= m_anim_framelength){
|
||||
m_anim_timer -= m_anim_framelength;
|
||||
@@ -784,6 +934,10 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
updateTextures("");
|
||||
}
|
||||
}
|
||||
if(fabs(m_prop.automatic_rotate) > 0.001){
|
||||
m_yaw += dtime * m_prop.automatic_rotate * 180 / PI;
|
||||
updateNodePos();
|
||||
}
|
||||
}
|
||||
|
||||
void updateTexturePos()
|
||||
@@ -838,76 +992,125 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
{
|
||||
ITextureSource *tsrc = m_gamedef->tsrc();
|
||||
|
||||
if(m_spritenode){
|
||||
std::string texturestring = "unknown_block.png";
|
||||
if(m_prop->textures.size() >= 1)
|
||||
texturestring = m_prop->textures[0];
|
||||
texturestring += mod;
|
||||
m_spritenode->setMaterialTexture(0,
|
||||
tsrc->getTextureRaw(texturestring));
|
||||
}
|
||||
if(m_meshnode){
|
||||
for (u32 i = 0; i < 6; ++i)
|
||||
if(m_spritenode)
|
||||
{
|
||||
if(m_prop.visual == "sprite")
|
||||
{
|
||||
std::string texturestring = "unknown_block.png";
|
||||
if(m_prop->textures.size() > i)
|
||||
texturestring = m_prop->textures[i];
|
||||
if(m_prop.textures.size() >= 1)
|
||||
texturestring = m_prop.textures[0];
|
||||
texturestring += mod;
|
||||
AtlasPointer ap = tsrc->getTexture(texturestring);
|
||||
m_spritenode->setMaterialTexture(0,
|
||||
tsrc->getTextureRaw(texturestring));
|
||||
}
|
||||
}
|
||||
if(m_meshnode)
|
||||
{
|
||||
if(m_prop.visual == "cube")
|
||||
{
|
||||
for (u32 i = 0; i < 6; ++i)
|
||||
{
|
||||
std::string texturestring = "unknown_block.png";
|
||||
if(m_prop.textures.size() > i)
|
||||
texturestring = m_prop.textures[i];
|
||||
texturestring += mod;
|
||||
AtlasPointer ap = tsrc->getTexture(texturestring);
|
||||
|
||||
// Get the tile texture and atlas transformation
|
||||
video::ITexture* atlas = ap.atlas;
|
||||
v2f pos = ap.pos;
|
||||
v2f size = ap.size;
|
||||
// Get the tile texture and atlas transformation
|
||||
video::ITexture* atlas = ap.atlas;
|
||||
v2f pos = ap.pos;
|
||||
v2f size = ap.size;
|
||||
|
||||
// Set material flags and texture
|
||||
video::SMaterial& material = m_meshnode->getMaterial(i);
|
||||
material.setFlag(video::EMF_LIGHTING, false);
|
||||
material.setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
material.setTexture(0, atlas);
|
||||
material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
|
||||
material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
|
||||
// Set material flags and texture
|
||||
video::SMaterial& material = m_meshnode->getMaterial(i);
|
||||
material.setFlag(video::EMF_LIGHTING, false);
|
||||
material.setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
material.setTexture(0, atlas);
|
||||
material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
|
||||
material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
|
||||
}
|
||||
}
|
||||
else if(m_prop.visual == "upright_sprite")
|
||||
{
|
||||
scene::IMesh *mesh = m_meshnode->getMesh();
|
||||
{
|
||||
std::string tname = "unknown_object.png";
|
||||
if(m_prop.textures.size() >= 1)
|
||||
tname = m_prop.textures[0];
|
||||
tname += mod;
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
|
||||
buf->getMaterial().setTexture(0,
|
||||
tsrc->getTextureRaw(tname));
|
||||
}
|
||||
{
|
||||
std::string tname = "unknown_object.png";
|
||||
if(m_prop.textures.size() >= 2)
|
||||
tname = m_prop.textures[1];
|
||||
else if(m_prop.textures.size() >= 1)
|
||||
tname = m_prop.textures[0];
|
||||
tname += mod;
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
|
||||
buf->getMaterial().setTexture(0,
|
||||
tsrc->getTextureRaw(tname));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processMessage(const std::string &data)
|
||||
{
|
||||
//infostream<<"LuaEntityCAO: Got message"<<std::endl;
|
||||
//infostream<<"GenericCAO: Got message"<<std::endl;
|
||||
std::istringstream is(data, std::ios::binary);
|
||||
// command
|
||||
u8 cmd = readU8(is);
|
||||
if(cmd == LUAENTITY_CMD_UPDATE_POSITION) // update position
|
||||
if(cmd == GENERIC_CMD_SET_PROPERTIES)
|
||||
{
|
||||
m_prop = gob_read_set_properties(is);
|
||||
|
||||
m_selection_box = m_prop.collisionbox;
|
||||
m_selection_box.MinEdge *= BS;
|
||||
m_selection_box.MaxEdge *= BS;
|
||||
|
||||
m_tx_size.X = 1.0 / m_prop.spritediv.X;
|
||||
m_tx_size.Y = 1.0 / m_prop.spritediv.Y;
|
||||
|
||||
if(!m_initial_tx_basepos_set){
|
||||
m_initial_tx_basepos_set = true;
|
||||
m_tx_basepos = m_prop.initial_sprite_basepos;
|
||||
}
|
||||
|
||||
expireVisuals();
|
||||
}
|
||||
else if(cmd == GENERIC_CMD_UPDATE_POSITION)
|
||||
{
|
||||
// do_interpolate
|
||||
bool do_interpolate = readU8(is);
|
||||
// pos
|
||||
m_position = readV3F1000(is);
|
||||
// velocity
|
||||
m_velocity = readV3F1000(is);
|
||||
// acceleration
|
||||
m_acceleration = readV3F1000(is);
|
||||
// yaw
|
||||
m_yaw = readF1000(is);
|
||||
// is_end_position (for interpolation)
|
||||
if(fabs(m_prop.automatic_rotate) < 0.001)
|
||||
m_yaw = readF1000(is);
|
||||
bool do_interpolate = readU8(is);
|
||||
bool is_end_position = readU8(is);
|
||||
// update_interval
|
||||
float update_interval = readF1000(is);
|
||||
|
||||
// Place us a bit higher if we're physical, to not sink into
|
||||
// the ground due to sucky collision detection...
|
||||
if(m_prop.physical)
|
||||
m_position += v3f(0,0.002,0);
|
||||
|
||||
if(do_interpolate){
|
||||
if(!m_prop->physical)
|
||||
if(!m_prop.physical)
|
||||
pos_translator.update(m_position, is_end_position, update_interval);
|
||||
} else {
|
||||
pos_translator.init(m_position);
|
||||
}
|
||||
updateNodePos();
|
||||
}
|
||||
else if(cmd == LUAENTITY_CMD_SET_TEXTURE_MOD) // set texture modification
|
||||
else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD)
|
||||
{
|
||||
std::string mod = deSerializeString(is);
|
||||
updateTextures(mod);
|
||||
}
|
||||
else if(cmd == LUAENTITY_CMD_SET_SPRITE) // set sprite
|
||||
else if(cmd == GENERIC_CMD_SET_SPRITE)
|
||||
{
|
||||
v2s16 p = readV2S16(is);
|
||||
int num_frames = readU16(is);
|
||||
@@ -921,15 +1124,14 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
|
||||
updateTexturePos();
|
||||
}
|
||||
else if(cmd == LUAENTITY_CMD_PUNCHED)
|
||||
else if(cmd == GENERIC_CMD_PUNCHED)
|
||||
{
|
||||
/*s16 damage =*/ readS16(is);
|
||||
s16 result_hp = readS16(is);
|
||||
|
||||
m_hp = result_hp;
|
||||
// TODO: Execute defined fast response
|
||||
}
|
||||
else if(cmd == LUAENTITY_CMD_UPDATE_ARMOR_GROUPS)
|
||||
else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS)
|
||||
{
|
||||
m_armor_groups.clear();
|
||||
int armor_groups_size = readU16(is);
|
||||
@@ -952,7 +1154,7 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
toolcap,
|
||||
punchitem,
|
||||
time_from_last_punch);
|
||||
|
||||
|
||||
if(result.did_punch && result.damage != 0)
|
||||
{
|
||||
if(result.damage < m_hp){
|
||||
@@ -963,13 +1165,15 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
// As there is no definition, make a smoke puff
|
||||
ClientSimpleObject *simple = createSmokePuff(
|
||||
m_smgr, m_env, m_position,
|
||||
m_prop->visual_size * BS);
|
||||
m_prop.visual_size * BS);
|
||||
m_env->addSimpleObject(simple);
|
||||
}
|
||||
// TODO: Execute defined fast response
|
||||
// Flashing shall suffice as there is no definition
|
||||
m_reset_textures_timer = 0.05;
|
||||
if(result.damage >= 2)
|
||||
m_reset_textures_timer += 0.05 * result.damage;
|
||||
updateTextures("^[brighten");
|
||||
m_reset_textures_timer = 0.1;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -978,7 +1182,7 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
std::string debugInfoText()
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
os<<"LuaEntityCAO hp="<<m_hp<<"\n";
|
||||
os<<"GenericCAO hp="<<m_hp<<"\n";
|
||||
os<<"armor={";
|
||||
for(ItemGroupList::const_iterator i = m_armor_groups.begin();
|
||||
i != m_armor_groups.end(); i++){
|
||||
@@ -990,307 +1194,6 @@ class LuaEntityCAO : public ClientActiveObject
|
||||
};
|
||||
|
||||
// Prototype
|
||||
LuaEntityCAO proto_LuaEntityCAO(NULL, NULL);
|
||||
|
||||
/*
|
||||
PlayerCAO
|
||||
*/
|
||||
|
||||
class PlayerCAO : public ClientActiveObject
|
||||
{
|
||||
private:
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
scene::IMeshSceneNode *m_node;
|
||||
scene::ITextSceneNode* m_text;
|
||||
std::string m_name;
|
||||
v3f m_position;
|
||||
float m_yaw;
|
||||
SmoothTranslator pos_translator;
|
||||
bool m_is_local_player;
|
||||
LocalPlayer *m_local_player;
|
||||
float m_damage_visual_timer;
|
||||
bool m_dead;
|
||||
float m_step_distance_counter;
|
||||
|
||||
public:
|
||||
PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
|
||||
ClientActiveObject(0, gamedef, env),
|
||||
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.0,BS/3.),
|
||||
m_node(NULL),
|
||||
m_text(NULL),
|
||||
m_position(v3f(0,10*BS,0)),
|
||||
m_yaw(0),
|
||||
m_is_local_player(false),
|
||||
m_local_player(NULL),
|
||||
m_damage_visual_timer(0),
|
||||
m_dead(false),
|
||||
m_step_distance_counter(0)
|
||||
{
|
||||
if(gamedef == NULL)
|
||||
ClientActiveObject::registerType(getType(), create);
|
||||
}
|
||||
|
||||
void initialize(const std::string &data)
|
||||
{
|
||||
infostream<<"PlayerCAO: Got init data"<<std::endl;
|
||||
|
||||
std::istringstream is(data, std::ios::binary);
|
||||
// version
|
||||
u8 version = readU8(is);
|
||||
// check version
|
||||
if(version != 0)
|
||||
return;
|
||||
// name
|
||||
m_name = deSerializeString(is);
|
||||
// pos
|
||||
m_position = readV3F1000(is);
|
||||
// yaw
|
||||
m_yaw = readF1000(is);
|
||||
// dead
|
||||
m_dead = readU8(is);
|
||||
|
||||
pos_translator.init(m_position);
|
||||
|
||||
Player *player = m_env->getPlayer(m_name.c_str());
|
||||
if(player && player->isLocal()){
|
||||
m_is_local_player = true;
|
||||
m_local_player = (LocalPlayer*)player;
|
||||
}
|
||||
}
|
||||
|
||||
~PlayerCAO()
|
||||
{
|
||||
if(m_node)
|
||||
m_node->remove();
|
||||
}
|
||||
|
||||
static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env)
|
||||
{
|
||||
return new PlayerCAO(gamedef, env);
|
||||
}
|
||||
|
||||
u8 getType() const
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_PLAYER;
|
||||
}
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
{
|
||||
if(m_is_local_player)
|
||||
return NULL;
|
||||
if(m_dead)
|
||||
return NULL;
|
||||
return &m_selection_box;
|
||||
}
|
||||
v3f getPosition()
|
||||
{
|
||||
return pos_translator.vect_show;
|
||||
}
|
||||
|
||||
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
|
||||
IrrlichtDevice *irr)
|
||||
{
|
||||
if(m_node != NULL)
|
||||
return;
|
||||
if(m_is_local_player)
|
||||
return;
|
||||
|
||||
//video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||
gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
|
||||
|
||||
scene::SMesh *mesh = new scene::SMesh();
|
||||
{ // Front
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
video::SColor c(255,255,255,255);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
}
|
||||
{ // Back
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
video::SColor c(255,255,255,255);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
|
||||
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
}
|
||||
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||
mesh->drop();
|
||||
// Set it to use the materials of the meshbuffers directly.
|
||||
// This is needed for changing the texture in the future
|
||||
m_node->setReadOnlyMaterials(true);
|
||||
updateNodePos();
|
||||
|
||||
// Add a text node for showing the name
|
||||
std::wstring wname = narrow_to_wide(m_name);
|
||||
m_text = smgr->addTextSceneNode(gui->getBuiltInFont(),
|
||||
wname.c_str(), video::SColor(255,255,255,255), m_node);
|
||||
m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
|
||||
|
||||
updateTextures("");
|
||||
updateVisibility();
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
void removeFromScene()
|
||||
{
|
||||
if(m_node == NULL)
|
||||
return;
|
||||
|
||||
m_node->remove();
|
||||
m_node = NULL;
|
||||
}
|
||||
|
||||
void updateLight(u8 light_at_pos)
|
||||
{
|
||||
if(m_node == NULL)
|
||||
return;
|
||||
|
||||
u8 li = decode_light(light_at_pos);
|
||||
video::SColor color(255,li,li,li);
|
||||
setMeshColor(m_node->getMesh(), color);
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
v3s16 getLightPosition()
|
||||
{
|
||||
return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
|
||||
}
|
||||
|
||||
void updateVisibility()
|
||||
{
|
||||
if(m_node == NULL)
|
||||
return;
|
||||
|
||||
m_node->setVisible(!m_dead);
|
||||
}
|
||||
|
||||
void updateNodePos()
|
||||
{
|
||||
if(m_node == NULL)
|
||||
return;
|
||||
|
||||
m_node->setPosition(pos_translator.vect_show);
|
||||
|
||||
v3f rot = m_node->getRotation();
|
||||
rot.Y = -m_yaw;
|
||||
m_node->setRotation(rot);
|
||||
}
|
||||
|
||||
void step(float dtime, ClientEnvironment *env)
|
||||
{
|
||||
v3f lastpos = pos_translator.vect_show;
|
||||
pos_translator.translate(dtime);
|
||||
float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
|
||||
updateVisibility();
|
||||
updateNodePos();
|
||||
|
||||
if(m_damage_visual_timer > 0){
|
||||
m_damage_visual_timer -= dtime;
|
||||
if(m_damage_visual_timer <= 0){
|
||||
updateTextures("");
|
||||
}
|
||||
}
|
||||
|
||||
m_step_distance_counter += moved;
|
||||
if(m_step_distance_counter > 1.5*BS){
|
||||
m_step_distance_counter = 0;
|
||||
if(!m_is_local_player){
|
||||
INodeDefManager *ndef = m_gamedef->ndef();
|
||||
v3s16 p = floatToInt(getPosition()+v3f(0,-0.5*BS, 0), BS);
|
||||
MapNode n = m_env->getMap().getNodeNoEx(p);
|
||||
SimpleSoundSpec spec = ndef->get(n).sound_footstep;
|
||||
m_gamedef->sound()->playSoundAt(spec, false, getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processMessage(const std::string &data)
|
||||
{
|
||||
//infostream<<"PlayerCAO: Got message"<<std::endl;
|
||||
std::istringstream is(data, std::ios::binary);
|
||||
// command
|
||||
u8 cmd = readU8(is);
|
||||
if(cmd == 0) // update position
|
||||
{
|
||||
// pos
|
||||
m_position = readV3F1000(is);
|
||||
// yaw
|
||||
m_yaw = readF1000(is);
|
||||
|
||||
pos_translator.update(m_position, false);
|
||||
|
||||
updateNodePos();
|
||||
}
|
||||
else if(cmd == 1) // punched
|
||||
{
|
||||
// damage
|
||||
s16 damage = readS16(is);
|
||||
m_damage_visual_timer = 0.05;
|
||||
if(damage >= 2)
|
||||
m_damage_visual_timer += 0.05 * damage;
|
||||
updateTextures("^[brighten");
|
||||
}
|
||||
else if(cmd == 2) // died or respawned
|
||||
{
|
||||
m_dead = readU8(is);
|
||||
updateVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
void updateTextures(const std::string &mod)
|
||||
{
|
||||
if(!m_node)
|
||||
return;
|
||||
ITextureSource *tsrc = m_gamedef->tsrc();
|
||||
scene::IMesh *mesh = m_node->getMesh();
|
||||
if(mesh){
|
||||
{
|
||||
std::string tname = "player.png";
|
||||
tname += mod;
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
|
||||
buf->getMaterial().setTexture(0,
|
||||
tsrc->getTextureRaw(tname));
|
||||
}
|
||||
{
|
||||
std::string tname = "player_back.png";
|
||||
tname += mod;
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
|
||||
buf->getMaterial().setTexture(0,
|
||||
tsrc->getTextureRaw(tname));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Prototype
|
||||
PlayerCAO proto_PlayerCAO(NULL, NULL);
|
||||
GenericCAO proto_GenericCAO(NULL, NULL);
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -210,8 +210,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||
top_is_same_liquid = true;
|
||||
|
||||
u16 l = 0;
|
||||
// If this liquid emits light and doesn't contain light, draw
|
||||
// it at what it emits, for an increased effect
|
||||
u8 light_source = nodedef->get(n).light_source;
|
||||
if(light_source != 0){
|
||||
//l = decode_light(undiminish_light(light_source));
|
||||
l = decode_light(light_source);
|
||||
l = l | (l<<8);
|
||||
}
|
||||
// Use the light of the node on top if possible
|
||||
if(nodedef->get(ntop).param_type == CPT_LIGHT)
|
||||
else if(nodedef->get(ntop).param_type == CPT_LIGHT)
|
||||
l = getInteriorLight(ntop, 0, data);
|
||||
// Otherwise use the light of this node (the liquid)
|
||||
else
|
||||
@@ -727,12 +735,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||
TileSpec tile = getNodeTile(n, p, v3s16(0,0,0), data);
|
||||
TileSpec tile_nocrack = tile;
|
||||
tile_nocrack.material_flags &= ~MATERIAL_FLAG_CRACK;
|
||||
|
||||
|
||||
// A hack to put wood the right way around in the posts
|
||||
ITextureSource *tsrc = data->m_gamedef->tsrc();
|
||||
TileSpec tile_rot = tile;
|
||||
tile_rot.texture = tsrc->getTexture(tsrc->getTextureName(
|
||||
tile.texture.id) + "^[transformR90");
|
||||
|
||||
u16 l = getInteriorLight(n, 1, data);
|
||||
video::SColor c = MapBlock_LightColor(255, l);
|
||||
|
||||
const f32 post_rad=(f32)BS/10;
|
||||
const f32 bar_rad=(f32)BS/20;
|
||||
const f32 post_rad=(f32)BS/8;
|
||||
const f32 bar_rad=(f32)BS/16;
|
||||
const f32 bar_len=(f32)(BS/2)-post_rad;
|
||||
|
||||
v3f pos = intToFloat(p, BS);
|
||||
@@ -742,13 +756,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||
post.MinEdge += pos;
|
||||
post.MaxEdge += pos;
|
||||
f32 postuv[24]={
|
||||
0.4,0.4,0.6,0.6,
|
||||
0.4,0.4,0.6,0.6,
|
||||
0.35,0,0.65,1,
|
||||
0.35,0,0.65,1,
|
||||
0.35,0,0.65,1,
|
||||
0.35,0,0.65,1};
|
||||
makeCuboid(&collector, post, &tile, 1, c, postuv);
|
||||
6/16.,6/16.,10/16.,10/16.,
|
||||
6/16.,6/16.,10/16.,10/16.,
|
||||
0/16.,0,4/16.,1,
|
||||
4/16.,0,8/16.,1,
|
||||
8/16.,0,12/16.,1,
|
||||
12/16.,0,16/16.,1};
|
||||
makeCuboid(&collector, post, &tile_rot, 1, c, postuv);
|
||||
|
||||
// Now a section of fence, +X, if there's a post there
|
||||
v3s16 p2 = p;
|
||||
@@ -762,17 +776,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||
bar.MinEdge += pos;
|
||||
bar.MaxEdge += pos;
|
||||
f32 xrailuv[24]={
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6};
|
||||
0/16.,2/16.,16/16.,4/16.,
|
||||
0/16.,4/16.,16/16.,6/16.,
|
||||
6/16.,6/16.,8/16.,8/16.,
|
||||
10/16.,10/16.,12/16.,12/16.,
|
||||
0/16.,8/16.,16/16.,10/16.,
|
||||
0/16.,14/16.,16/16.,16/16.};
|
||||
makeCuboid(&collector, bar, &tile_nocrack, 1,
|
||||
c, xrailuv);
|
||||
bar.MinEdge.Y -= BS/2;
|
||||
bar.MaxEdge.Y -= BS/2;
|
||||
// TODO: no crack
|
||||
makeCuboid(&collector, bar, &tile_nocrack, 1,
|
||||
c, xrailuv);
|
||||
}
|
||||
@@ -789,13 +802,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||
bar.MinEdge += pos;
|
||||
bar.MaxEdge += pos;
|
||||
f32 zrailuv[24]={
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6,
|
||||
0,0.4,1,0.6};
|
||||
|
||||
3/16.,1/16.,5/16.,5/16., // cannot rotate; stretch
|
||||
4/16.,1/16.,6/16.,5/16., // for wood texture instead
|
||||
0/16.,9/16.,16/16.,11/16.,
|
||||
0/16.,6/16.,16/16.,8/16.,
|
||||
6/16.,6/16.,8/16.,8/16.,
|
||||
10/16.,10/16.,12/16.,12/16.};
|
||||
makeCuboid(&collector, bar, &tile_nocrack, 1,
|
||||
c, zrailuv);
|
||||
bar.MinEdge.Y -= BS/2;
|
||||
@@ -856,7 +868,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];
|
||||
@@ -864,30 +875,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;
|
||||
@@ -916,61 +966,10 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -1,32 +1,27 @@
|
||||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "content_nodemeta.h"
|
||||
|
||||
#include <map>
|
||||
#include "inventory.h"
|
||||
#include "log.h"
|
||||
#include "utility.h"
|
||||
#include "craftdef.h"
|
||||
#include "gamedef.h"
|
||||
|
||||
class Inventory;
|
||||
#include <sstream>
|
||||
|
||||
#define NODEMETA_GENERIC 1
|
||||
#define NODEMETA_SIGN 14
|
||||
@@ -34,809 +29,167 @@ class Inventory;
|
||||
#define NODEMETA_FURNACE 16
|
||||
#define NODEMETA_LOCKABLE_CHEST 17
|
||||
|
||||
core::map<u16, NodeMetadata::Factory> NodeMetadata::m_types;
|
||||
core::map<std::string, NodeMetadata::Factory2> NodeMetadata::m_names;
|
||||
// Returns true if node timer must be set
|
||||
static bool content_nodemeta_deserialize_legacy_body(
|
||||
std::istream &is, s16 id, NodeMetadata *meta)
|
||||
{
|
||||
meta->clear();
|
||||
|
||||
class SignNodeMetadata : public NodeMetadata
|
||||
{
|
||||
public:
|
||||
SignNodeMetadata(IGameDef *gamedef, std::string text);
|
||||
//~SignNodeMetadata();
|
||||
|
||||
virtual u16 typeId() const;
|
||||
virtual const char* typeName() const
|
||||
{ return "sign"; }
|
||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
||||
static NodeMetadata* create(IGameDef *gamedef);
|
||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
||||
virtual void serializeBody(std::ostream &os);
|
||||
virtual std::string infoText();
|
||||
|
||||
virtual bool allowsTextInput(){ return true; }
|
||||
virtual std::string getText(){ return m_text; }
|
||||
virtual void setText(const std::string &t){ m_text = t; }
|
||||
|
||||
private:
|
||||
std::string m_text;
|
||||
};
|
||||
|
||||
class ChestNodeMetadata : public NodeMetadata
|
||||
{
|
||||
public:
|
||||
ChestNodeMetadata(IGameDef *gamedef);
|
||||
~ChestNodeMetadata();
|
||||
|
||||
virtual u16 typeId() const;
|
||||
virtual const char* typeName() const
|
||||
{ return "chest"; }
|
||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
||||
static NodeMetadata* create(IGameDef *gamedef);
|
||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
||||
virtual void serializeBody(std::ostream &os);
|
||||
virtual std::string infoText();
|
||||
virtual Inventory* getInventory() {return m_inventory;}
|
||||
virtual bool nodeRemovalDisabled();
|
||||
virtual std::string getInventoryDrawSpecString();
|
||||
|
||||
private:
|
||||
Inventory *m_inventory;
|
||||
};
|
||||
|
||||
class LockingChestNodeMetadata : public NodeMetadata
|
||||
{
|
||||
public:
|
||||
LockingChestNodeMetadata(IGameDef *gamedef);
|
||||
~LockingChestNodeMetadata();
|
||||
|
||||
virtual u16 typeId() const;
|
||||
virtual const char* typeName() const
|
||||
{ return "locked_chest"; }
|
||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
||||
static NodeMetadata* create(IGameDef *gamedef);
|
||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
||||
virtual void serializeBody(std::ostream &os);
|
||||
virtual std::string infoText();
|
||||
virtual Inventory* getInventory() {return m_inventory;}
|
||||
virtual bool nodeRemovalDisabled();
|
||||
virtual std::string getInventoryDrawSpecString();
|
||||
|
||||
virtual std::string getOwner(){ return m_text; }
|
||||
virtual void setOwner(std::string t){ m_text = t; }
|
||||
|
||||
private:
|
||||
Inventory *m_inventory;
|
||||
std::string m_text;
|
||||
};
|
||||
|
||||
class FurnaceNodeMetadata : public NodeMetadata
|
||||
{
|
||||
public:
|
||||
FurnaceNodeMetadata(IGameDef *gamedef);
|
||||
~FurnaceNodeMetadata();
|
||||
|
||||
virtual u16 typeId() const;
|
||||
virtual const char* typeName() const
|
||||
{ return "furnace"; }
|
||||
virtual NodeMetadata* clone(IGameDef *gamedef);
|
||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
|
||||
static NodeMetadata* create(IGameDef *gamedef);
|
||||
virtual void serializeBody(std::ostream &os);
|
||||
virtual std::string infoText();
|
||||
virtual Inventory* getInventory() {return m_inventory;}
|
||||
virtual void inventoryModified();
|
||||
virtual bool step(float dtime);
|
||||
virtual bool nodeRemovalDisabled();
|
||||
virtual std::string getInventoryDrawSpecString();
|
||||
|
||||
protected:
|
||||
bool getCookResult(bool remove, std::string &cookresult, float &cooktime);
|
||||
bool getBurnResult(bool remove, float &burntime);
|
||||
|
||||
private:
|
||||
Inventory *m_inventory;
|
||||
std::string m_infotext;
|
||||
float m_step_accumulator;
|
||||
float m_fuel_totaltime;
|
||||
float m_fuel_time;
|
||||
float m_src_totaltime;
|
||||
float m_src_time;
|
||||
};
|
||||
|
||||
/*
|
||||
SignNodeMetadata
|
||||
*/
|
||||
|
||||
// Prototype
|
||||
SignNodeMetadata proto_SignNodeMetadata(NULL, "");
|
||||
|
||||
SignNodeMetadata::SignNodeMetadata(IGameDef *gamedef, std::string text):
|
||||
NodeMetadata(gamedef),
|
||||
m_text(text)
|
||||
{
|
||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
||||
}
|
||||
u16 SignNodeMetadata::typeId() const
|
||||
{
|
||||
return NODEMETA_SIGN;
|
||||
}
|
||||
NodeMetadata* SignNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
||||
{
|
||||
std::string text = deSerializeString(is);
|
||||
return new SignNodeMetadata(gamedef, text);
|
||||
}
|
||||
NodeMetadata* SignNodeMetadata::create(IGameDef *gamedef)
|
||||
{
|
||||
return new SignNodeMetadata(gamedef, "");
|
||||
}
|
||||
NodeMetadata* SignNodeMetadata::clone(IGameDef *gamedef)
|
||||
{
|
||||
return new SignNodeMetadata(gamedef, m_text);
|
||||
}
|
||||
void SignNodeMetadata::serializeBody(std::ostream &os)
|
||||
{
|
||||
os<<serializeString(m_text);
|
||||
}
|
||||
std::string SignNodeMetadata::infoText()
|
||||
{
|
||||
return std::string("\"")+m_text+"\"";
|
||||
}
|
||||
|
||||
/*
|
||||
ChestNodeMetadata
|
||||
*/
|
||||
|
||||
// Prototype
|
||||
ChestNodeMetadata proto_ChestNodeMetadata(NULL);
|
||||
|
||||
ChestNodeMetadata::ChestNodeMetadata(IGameDef *gamedef):
|
||||
NodeMetadata(gamedef)
|
||||
{
|
||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
||||
m_inventory = NULL;
|
||||
}
|
||||
ChestNodeMetadata::~ChestNodeMetadata()
|
||||
{
|
||||
delete m_inventory;
|
||||
}
|
||||
u16 ChestNodeMetadata::typeId() const
|
||||
{
|
||||
return NODEMETA_CHEST;
|
||||
}
|
||||
NodeMetadata* ChestNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
||||
{
|
||||
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
d->m_inventory->deSerialize(is);
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* ChestNodeMetadata::create(IGameDef *gamedef)
|
||||
{
|
||||
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
d->m_inventory->addList("0", 8*4);
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* ChestNodeMetadata::clone(IGameDef *gamedef)
|
||||
{
|
||||
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
|
||||
d->m_inventory = new Inventory(*m_inventory);
|
||||
return d;
|
||||
}
|
||||
void ChestNodeMetadata::serializeBody(std::ostream &os)
|
||||
{
|
||||
m_inventory->serialize(os);
|
||||
}
|
||||
std::string ChestNodeMetadata::infoText()
|
||||
{
|
||||
return "Chest";
|
||||
}
|
||||
bool ChestNodeMetadata::nodeRemovalDisabled()
|
||||
{
|
||||
/*
|
||||
Disable removal if chest contains something
|
||||
*/
|
||||
InventoryList *list = m_inventory->getList("0");
|
||||
if(list == NULL)
|
||||
return false;
|
||||
if(list->getUsedSlots() == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
std::string ChestNodeMetadata::getInventoryDrawSpecString()
|
||||
{
|
||||
return
|
||||
"invsize[8,9;]"
|
||||
"list[current_name;0;0,0;8,4;]"
|
||||
"list[current_player;main;0,5;8,4;]";
|
||||
}
|
||||
|
||||
/*
|
||||
LockingChestNodeMetadata
|
||||
*/
|
||||
|
||||
// Prototype
|
||||
LockingChestNodeMetadata proto_LockingChestNodeMetadata(NULL);
|
||||
|
||||
LockingChestNodeMetadata::LockingChestNodeMetadata(IGameDef *gamedef):
|
||||
NodeMetadata(gamedef)
|
||||
{
|
||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
||||
m_inventory = NULL;
|
||||
}
|
||||
LockingChestNodeMetadata::~LockingChestNodeMetadata()
|
||||
{
|
||||
delete m_inventory;
|
||||
}
|
||||
u16 LockingChestNodeMetadata::typeId() const
|
||||
{
|
||||
return NODEMETA_LOCKABLE_CHEST;
|
||||
}
|
||||
NodeMetadata* LockingChestNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
||||
{
|
||||
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
|
||||
d->setOwner(deSerializeString(is));
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
d->m_inventory->deSerialize(is);
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* LockingChestNodeMetadata::create(IGameDef *gamedef)
|
||||
{
|
||||
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
d->m_inventory->addList("0", 8*4);
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* LockingChestNodeMetadata::clone(IGameDef *gamedef)
|
||||
{
|
||||
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
|
||||
d->m_inventory = new Inventory(*m_inventory);
|
||||
return d;
|
||||
}
|
||||
void LockingChestNodeMetadata::serializeBody(std::ostream &os)
|
||||
{
|
||||
os<<serializeString(m_text);
|
||||
m_inventory->serialize(os);
|
||||
}
|
||||
std::string LockingChestNodeMetadata::infoText()
|
||||
{
|
||||
return "Locking Chest";
|
||||
}
|
||||
bool LockingChestNodeMetadata::nodeRemovalDisabled()
|
||||
{
|
||||
/*
|
||||
Disable removal if chest contains something
|
||||
*/
|
||||
InventoryList *list = m_inventory->getList("0");
|
||||
if(list == NULL)
|
||||
return false;
|
||||
if(list->getUsedSlots() == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
std::string LockingChestNodeMetadata::getInventoryDrawSpecString()
|
||||
{
|
||||
return
|
||||
"invsize[8,9;]"
|
||||
"list[current_name;0;0,0;8,4;]"
|
||||
"list[current_player;main;0,5;8,4;]";
|
||||
}
|
||||
|
||||
/*
|
||||
FurnaceNodeMetadata
|
||||
*/
|
||||
|
||||
// Prototype
|
||||
FurnaceNodeMetadata proto_FurnaceNodeMetadata(NULL);
|
||||
|
||||
FurnaceNodeMetadata::FurnaceNodeMetadata(IGameDef *gamedef):
|
||||
NodeMetadata(gamedef)
|
||||
{
|
||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
||||
|
||||
m_inventory = NULL;
|
||||
|
||||
m_infotext = "Furnace is inactive";
|
||||
|
||||
m_step_accumulator = 0;
|
||||
m_fuel_totaltime = 0;
|
||||
m_fuel_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
m_src_time = 0;
|
||||
}
|
||||
FurnaceNodeMetadata::~FurnaceNodeMetadata()
|
||||
{
|
||||
delete m_inventory;
|
||||
}
|
||||
u16 FurnaceNodeMetadata::typeId() const
|
||||
{
|
||||
return NODEMETA_FURNACE;
|
||||
}
|
||||
NodeMetadata* FurnaceNodeMetadata::clone(IGameDef *gamedef)
|
||||
{
|
||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(m_gamedef);
|
||||
d->m_inventory = new Inventory(*m_inventory);
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* FurnaceNodeMetadata::create(std::istream &is, IGameDef *gamedef)
|
||||
{
|
||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef);
|
||||
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
d->m_inventory->deSerialize(is);
|
||||
|
||||
int temp = 0;
|
||||
is>>temp;
|
||||
d->m_fuel_totaltime = (float)temp/10;
|
||||
temp = 0;
|
||||
is>>temp;
|
||||
d->m_fuel_time = (float)temp/10;
|
||||
temp = 0;
|
||||
is>>temp;
|
||||
d->m_src_totaltime = (float)temp/10;
|
||||
temp = 0;
|
||||
is>>temp;
|
||||
d->m_src_time = (float)temp/10;
|
||||
|
||||
if(is.eof())
|
||||
if(id == NODEMETA_GENERIC) // GenericNodeMetadata (0.4-dev)
|
||||
{
|
||||
// Old furnaces didn't serialize src_totaltime and src_time
|
||||
d->m_src_totaltime = 0;
|
||||
d->m_src_time = 0;
|
||||
d->m_infotext = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
// New furnaces also serialize the infotext (so that the
|
||||
// client doesn't need to have the list of cooking recipes).
|
||||
d->m_infotext = deSerializeJsonString(is);
|
||||
}
|
||||
meta->getInventory()->deSerialize(is);
|
||||
deSerializeLongString(is); // m_text
|
||||
deSerializeString(is); // m_owner
|
||||
|
||||
return d;
|
||||
}
|
||||
NodeMetadata* FurnaceNodeMetadata::create(IGameDef *gamedef)
|
||||
{
|
||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef);
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
d->m_inventory->addList("fuel", 1);
|
||||
d->m_inventory->addList("src", 1);
|
||||
d->m_inventory->addList("dst", 4);
|
||||
return d;
|
||||
}
|
||||
void FurnaceNodeMetadata::serializeBody(std::ostream &os)
|
||||
{
|
||||
m_inventory->serialize(os);
|
||||
os<<itos(m_fuel_totaltime*10)<<" ";
|
||||
os<<itos(m_fuel_time*10)<<" ";
|
||||
os<<itos(m_src_totaltime*10)<<" ";
|
||||
os<<itos(m_src_time*10)<<" ";
|
||||
os<<serializeJsonString(m_infotext);
|
||||
}
|
||||
std::string FurnaceNodeMetadata::infoText()
|
||||
{
|
||||
return m_infotext;
|
||||
}
|
||||
bool FurnaceNodeMetadata::nodeRemovalDisabled()
|
||||
{
|
||||
/*
|
||||
Disable removal if furnace is not empty
|
||||
*/
|
||||
InventoryList *list[3] = {m_inventory->getList("src"),
|
||||
m_inventory->getList("dst"), m_inventory->getList("fuel")};
|
||||
|
||||
for(int i = 0; i < 3; i++) {
|
||||
if(list[i] == NULL)
|
||||
continue;
|
||||
if(list[i]->getUsedSlots() == 0)
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
void FurnaceNodeMetadata::inventoryModified()
|
||||
{
|
||||
infostream<<"Furnace inventory modification callback"<<std::endl;
|
||||
}
|
||||
bool FurnaceNodeMetadata::step(float dtime)
|
||||
{
|
||||
if(dtime > 60.0)
|
||||
infostream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
|
||||
|
||||
InventoryList *dst_list = m_inventory->getList("dst");
|
||||
assert(dst_list);
|
||||
|
||||
// Update at a fixed frequency
|
||||
const float interval = 2.0;
|
||||
m_step_accumulator += dtime;
|
||||
bool changed = false;
|
||||
while(m_step_accumulator > interval)
|
||||
{
|
||||
m_step_accumulator -= interval;
|
||||
dtime = interval;
|
||||
|
||||
//infostream<<"Furnace step dtime="<<dtime<<std::endl;
|
||||
|
||||
bool changed_this_loop = false;
|
||||
|
||||
// Check
|
||||
// 1. if the source item is cookable
|
||||
// 2. if there is room for the cooked item
|
||||
std::string cookresult;
|
||||
float cooktime;
|
||||
bool cookable = getCookResult(false, cookresult, cooktime);
|
||||
ItemStack cookresult_item;
|
||||
bool room_available = false;
|
||||
if(cookable)
|
||||
{
|
||||
cookresult_item.deSerialize(cookresult, m_gamedef->idef());
|
||||
room_available = dst_list->roomForItem(cookresult_item);
|
||||
}
|
||||
|
||||
// Step fuel time
|
||||
bool burning = (m_fuel_time < m_fuel_totaltime);
|
||||
if(burning)
|
||||
{
|
||||
changed_this_loop = true;
|
||||
m_fuel_time += dtime;
|
||||
}
|
||||
|
||||
std::string infotext;
|
||||
if(room_available)
|
||||
{
|
||||
float burntime;
|
||||
if(burning)
|
||||
{
|
||||
changed_this_loop = true;
|
||||
m_src_time += dtime;
|
||||
m_src_totaltime = cooktime;
|
||||
infotext = "Furnace is cooking";
|
||||
}
|
||||
else if(getBurnResult(true, burntime))
|
||||
{
|
||||
// Fuel inserted
|
||||
changed_this_loop = true;
|
||||
m_fuel_time = 0;
|
||||
m_fuel_totaltime = burntime;
|
||||
//m_src_time += dtime;
|
||||
//m_src_totaltime = cooktime;
|
||||
infotext = "Furnace is cooking";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_src_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
infotext = "Furnace is out of fuel";
|
||||
}
|
||||
if(m_src_totaltime > 0.001 && m_src_time >= m_src_totaltime)
|
||||
{
|
||||
// One item fully cooked
|
||||
changed_this_loop = true;
|
||||
dst_list->addItem(cookresult_item);
|
||||
getCookResult(true, cookresult, cooktime); // decrement source
|
||||
m_src_totaltime = 0;
|
||||
m_src_time = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not cookable or no room available
|
||||
m_src_totaltime = 0;
|
||||
m_src_time = 0;
|
||||
if(cookable)
|
||||
infotext = "Furnace is overloaded";
|
||||
else if(burning)
|
||||
infotext = "Furnace is active";
|
||||
else
|
||||
{
|
||||
infotext = "Furnace is inactive";
|
||||
m_fuel_totaltime = 0;
|
||||
m_fuel_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Do this so it doesn't always show (0%) for weak fuel
|
||||
if(m_fuel_totaltime > 3) {
|
||||
infotext += " (";
|
||||
infotext += itos(m_fuel_time/m_fuel_totaltime*100);
|
||||
infotext += "%)";
|
||||
}
|
||||
|
||||
if(infotext != m_infotext)
|
||||
{
|
||||
m_infotext = infotext;
|
||||
changed_this_loop = true;
|
||||
}
|
||||
|
||||
if(burning && m_fuel_time >= m_fuel_totaltime)
|
||||
{
|
||||
m_fuel_time = 0;
|
||||
m_fuel_totaltime = 0;
|
||||
}
|
||||
|
||||
if(changed_this_loop)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_step_accumulator = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
std::string FurnaceNodeMetadata::getInventoryDrawSpecString()
|
||||
{
|
||||
return
|
||||
"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;]";
|
||||
}
|
||||
bool FurnaceNodeMetadata::getCookResult(bool remove,
|
||||
std::string &cookresult, float &cooktime)
|
||||
{
|
||||
std::vector<ItemStack> items;
|
||||
InventoryList *src_list = m_inventory->getList("src");
|
||||
assert(src_list);
|
||||
items.push_back(src_list->getItem(0));
|
||||
|
||||
CraftInput ci(CRAFT_METHOD_COOKING, 1, items);
|
||||
CraftOutput co;
|
||||
bool found = m_gamedef->getCraftDefManager()->getCraftResult(
|
||||
ci, co, remove, m_gamedef);
|
||||
if(remove)
|
||||
src_list->changeItem(0, ci.items[0]);
|
||||
|
||||
cookresult = co.item;
|
||||
cooktime = co.time;
|
||||
return found;
|
||||
}
|
||||
bool FurnaceNodeMetadata::getBurnResult(bool remove, float &burntime)
|
||||
{
|
||||
std::vector<ItemStack> items;
|
||||
InventoryList *fuel_list = m_inventory->getList("fuel");
|
||||
assert(fuel_list);
|
||||
items.push_back(fuel_list->getItem(0));
|
||||
|
||||
CraftInput ci(CRAFT_METHOD_FUEL, 1, items);
|
||||
CraftOutput co;
|
||||
bool found = m_gamedef->getCraftDefManager()->getCraftResult(
|
||||
ci, co, remove, m_gamedef);
|
||||
if(remove)
|
||||
fuel_list->changeItem(0, ci.items[0]);
|
||||
|
||||
burntime = co.time;
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GenericNodeMetadata
|
||||
*/
|
||||
|
||||
class GenericNodeMetadata : public NodeMetadata
|
||||
{
|
||||
private:
|
||||
Inventory *m_inventory;
|
||||
std::string m_text;
|
||||
std::string m_owner;
|
||||
|
||||
std::string m_infotext;
|
||||
std::string m_inventorydrawspec;
|
||||
bool m_allow_text_input;
|
||||
bool m_removal_disabled;
|
||||
bool m_enforce_owner;
|
||||
|
||||
bool m_inventory_modified;
|
||||
bool m_text_modified;
|
||||
|
||||
std::map<std::string, std::string> m_stringvars;
|
||||
|
||||
public:
|
||||
u16 typeId() const
|
||||
{
|
||||
return NODEMETA_GENERIC;
|
||||
}
|
||||
const char* typeName() const
|
||||
{
|
||||
return "generic";
|
||||
}
|
||||
|
||||
GenericNodeMetadata(IGameDef *gamedef):
|
||||
NodeMetadata(gamedef),
|
||||
|
||||
m_inventory(NULL),
|
||||
m_text(""),
|
||||
m_owner(""),
|
||||
|
||||
m_infotext("GenericNodeMetadata"),
|
||||
m_inventorydrawspec(""),
|
||||
m_allow_text_input(false),
|
||||
m_removal_disabled(false),
|
||||
m_enforce_owner(false),
|
||||
|
||||
m_inventory_modified(false),
|
||||
m_text_modified(false)
|
||||
{
|
||||
NodeMetadata::registerType(typeId(), typeName(), create, create);
|
||||
}
|
||||
virtual ~GenericNodeMetadata()
|
||||
{
|
||||
delete m_inventory;
|
||||
}
|
||||
NodeMetadata* clone(IGameDef *gamedef)
|
||||
{
|
||||
GenericNodeMetadata *d = new GenericNodeMetadata(m_gamedef);
|
||||
|
||||
d->m_inventory = new Inventory(*m_inventory);
|
||||
d->m_text = m_text;
|
||||
d->m_owner = m_owner;
|
||||
|
||||
d->m_infotext = m_infotext;
|
||||
d->m_inventorydrawspec = m_inventorydrawspec;
|
||||
d->m_allow_text_input = m_allow_text_input;
|
||||
d->m_removal_disabled = m_removal_disabled;
|
||||
d->m_enforce_owner = m_enforce_owner;
|
||||
d->m_inventory_modified = m_inventory_modified;
|
||||
d->m_text_modified = m_text_modified;
|
||||
return d;
|
||||
}
|
||||
static NodeMetadata* create(IGameDef *gamedef)
|
||||
{
|
||||
GenericNodeMetadata *d = new GenericNodeMetadata(gamedef);
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
return d;
|
||||
}
|
||||
static NodeMetadata* create(std::istream &is, IGameDef *gamedef)
|
||||
{
|
||||
GenericNodeMetadata *d = new GenericNodeMetadata(gamedef);
|
||||
|
||||
d->m_inventory = new Inventory(gamedef->idef());
|
||||
d->m_inventory->deSerialize(is);
|
||||
d->m_text = deSerializeLongString(is);
|
||||
d->m_owner = deSerializeString(is);
|
||||
|
||||
d->m_infotext = deSerializeString(is);
|
||||
d->m_inventorydrawspec = deSerializeString(is);
|
||||
d->m_allow_text_input = readU8(is);
|
||||
d->m_removal_disabled = readU8(is);
|
||||
d->m_enforce_owner = readU8(is);
|
||||
meta->setString("infotext",deSerializeString(is));
|
||||
meta->setString("formspec",deSerializeString(is));
|
||||
readU8(is); // m_allow_text_input
|
||||
readU8(is); // m_allow_removal
|
||||
readU8(is); // m_enforce_owner
|
||||
|
||||
int num_vars = readU32(is);
|
||||
for(int i=0; i<num_vars; i++){
|
||||
std::string name = deSerializeString(is);
|
||||
std::string var = deSerializeLongString(is);
|
||||
d->m_stringvars[name] = var;
|
||||
meta->setString(name, var);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
void serializeBody(std::ostream &os)
|
||||
{
|
||||
m_inventory->serialize(os);
|
||||
os<<serializeLongString(m_text);
|
||||
os<<serializeString(m_owner);
|
||||
|
||||
os<<serializeString(m_infotext);
|
||||
os<<serializeString(m_inventorydrawspec);
|
||||
writeU8(os, m_allow_text_input);
|
||||
writeU8(os, m_removal_disabled);
|
||||
writeU8(os, m_enforce_owner);
|
||||
|
||||
int num_vars = m_stringvars.size();
|
||||
writeU32(os, num_vars);
|
||||
for(std::map<std::string, std::string>::iterator
|
||||
i = m_stringvars.begin(); i != m_stringvars.end(); i++){
|
||||
os<<serializeString(i->first);
|
||||
os<<serializeLongString(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
std::string infoText()
|
||||
{
|
||||
return m_infotext;
|
||||
}
|
||||
Inventory* getInventory()
|
||||
{
|
||||
return m_inventory;
|
||||
}
|
||||
void inventoryModified()
|
||||
{
|
||||
m_inventory_modified = true;
|
||||
}
|
||||
bool step(float dtime)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool nodeRemovalDisabled()
|
||||
else if(id == NODEMETA_SIGN) // SignNodeMetadata
|
||||
{
|
||||
return m_removal_disabled;
|
||||
meta->setString("text", deSerializeString(is));
|
||||
//meta->setString("infotext","\"${text}\"");
|
||||
meta->setString("infotext",
|
||||
std::string("\"") + meta->getString("text") + "\"");
|
||||
meta->setString("formspec","hack:sign_text_input");
|
||||
return false;
|
||||
}
|
||||
std::string getInventoryDrawSpecString()
|
||||
else if(id == NODEMETA_CHEST) // ChestNodeMetadata
|
||||
{
|
||||
return m_inventorydrawspec;
|
||||
}
|
||||
bool allowsTextInput()
|
||||
{
|
||||
return m_allow_text_input;
|
||||
}
|
||||
std::string getText()
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
void setText(const std::string &t)
|
||||
{
|
||||
m_text = t;
|
||||
m_text_modified = true;
|
||||
}
|
||||
std::string getOwner()
|
||||
{
|
||||
if(m_enforce_owner)
|
||||
return m_owner;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
void setOwner(std::string t)
|
||||
{
|
||||
m_owner = t;
|
||||
}
|
||||
|
||||
/* Interface for GenericNodeMetadata */
|
||||
meta->getInventory()->deSerialize(is);
|
||||
|
||||
void setInfoText(const std::string &text)
|
||||
{
|
||||
infostream<<"GenericNodeMetadata::setInfoText(\""
|
||||
<<text<<"\")"<<std::endl;
|
||||
m_infotext = text;
|
||||
// Rename inventory list "0" to "main"
|
||||
Inventory *inv = meta->getInventory();
|
||||
if(!inv->getList("main") && inv->getList("0")){
|
||||
inv->getList("0")->setName("main");
|
||||
}
|
||||
assert(inv->getList("main") && !inv->getList("0"));
|
||||
|
||||
meta->setString("formspec","invsize[8,9;]"
|
||||
"list[current_name;main;0,0;8,4;]"
|
||||
"list[current_player;main;0,5;8,4;]");
|
||||
return false;
|
||||
}
|
||||
void setInventoryDrawSpec(const std::string &text)
|
||||
else if(id == NODEMETA_LOCKABLE_CHEST) // LockingChestNodeMetadata
|
||||
{
|
||||
m_inventorydrawspec = text;
|
||||
}
|
||||
void setAllowTextInput(bool b)
|
||||
{
|
||||
m_allow_text_input = b;
|
||||
}
|
||||
void setRemovalDisabled(bool b)
|
||||
{
|
||||
m_removal_disabled = b;
|
||||
}
|
||||
void setEnforceOwner(bool b)
|
||||
{
|
||||
m_enforce_owner = b;
|
||||
}
|
||||
bool isInventoryModified()
|
||||
{
|
||||
return m_inventory_modified;
|
||||
}
|
||||
void resetInventoryModified()
|
||||
{
|
||||
m_inventory_modified = false;
|
||||
}
|
||||
bool isTextModified()
|
||||
{
|
||||
return m_text_modified;
|
||||
}
|
||||
void resetTextModified()
|
||||
{
|
||||
m_text_modified = false;
|
||||
}
|
||||
void setString(const std::string &name, const std::string &var)
|
||||
{
|
||||
m_stringvars[name] = var;
|
||||
}
|
||||
std::string getString(const std::string &name)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator i;
|
||||
i = m_stringvars.find(name);
|
||||
if(i == m_stringvars.end())
|
||||
return "";
|
||||
return i->second;
|
||||
}
|
||||
};
|
||||
meta->setString("owner", deSerializeString(is));
|
||||
meta->getInventory()->deSerialize(is);
|
||||
|
||||
// Prototype
|
||||
GenericNodeMetadata proto_GenericNodeMetadata(NULL);
|
||||
// Rename inventory list "0" to "main"
|
||||
Inventory *inv = meta->getInventory();
|
||||
if(!inv->getList("main") && inv->getList("0")){
|
||||
inv->getList("0")->setName("main");
|
||||
}
|
||||
assert(inv->getList("main") && !inv->getList("0"));
|
||||
|
||||
meta->setString("formspec","invsize[8,9;]"
|
||||
"list[current_name;main;0,0;8,4;]"
|
||||
"list[current_player;main;0,5;8,4;]");
|
||||
return false;
|
||||
}
|
||||
else if(id == NODEMETA_FURNACE) // FurnaceNodeMetadata
|
||||
{
|
||||
meta->getInventory()->deSerialize(is);
|
||||
int temp = 0;
|
||||
is>>temp;
|
||||
meta->setString("fuel_totaltime", ftos((float)temp/10));
|
||||
temp = 0;
|
||||
is>>temp;
|
||||
meta->setString("fuel_time", ftos((float)temp/10));
|
||||
temp = 0;
|
||||
is>>temp;
|
||||
//meta->setString("src_totaltime", ftos((float)temp/10));
|
||||
temp = 0;
|
||||
is>>temp;
|
||||
meta->setString("src_time", ftos((float)temp/10));
|
||||
|
||||
meta->setString("formspec","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;]");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SerializationError("Unknown legacy node metadata");
|
||||
}
|
||||
}
|
||||
|
||||
static bool content_nodemeta_deserialize_legacy_meta(
|
||||
std::istream &is, NodeMetadata *meta)
|
||||
{
|
||||
// Read id
|
||||
s16 id = readS16(is);
|
||||
|
||||
// Read data
|
||||
std::string data = deSerializeString(is);
|
||||
std::istringstream tmp_is(data, std::ios::binary);
|
||||
return content_nodemeta_deserialize_legacy_body(tmp_is, id, meta);
|
||||
}
|
||||
|
||||
void content_nodemeta_deserialize_legacy(std::istream &is,
|
||||
NodeMetadataList *meta, NodeTimerList *timers,
|
||||
IGameDef *gamedef)
|
||||
{
|
||||
meta->clear();
|
||||
timers->clear();
|
||||
|
||||
u16 version = readU16(is);
|
||||
|
||||
if(version > 1)
|
||||
{
|
||||
infostream<<__FUNCTION_NAME<<": version "<<version<<" not supported"
|
||||
<<std::endl;
|
||||
throw SerializationError(__FUNCTION_NAME);
|
||||
}
|
||||
|
||||
u16 count = readU16(is);
|
||||
|
||||
for(u16 i=0; i<count; i++)
|
||||
{
|
||||
u16 p16 = readU16(is);
|
||||
|
||||
v3s16 p(0,0,0);
|
||||
p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
|
||||
p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
||||
p.Y += p16 / MAP_BLOCKSIZE;
|
||||
p16 -= p.Y * MAP_BLOCKSIZE;
|
||||
p.X += p16;
|
||||
|
||||
if(meta->get(p) != NULL)
|
||||
{
|
||||
infostream<<"WARNING: "<<__FUNCTION_NAME<<": "
|
||||
<<"already set data at position"
|
||||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
|
||||
<<std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
NodeMetadata *data = new NodeMetadata(gamedef);
|
||||
bool need_timer = content_nodemeta_deserialize_legacy_meta(is, data);
|
||||
meta->set(p, data);
|
||||
|
||||
if(need_timer)
|
||||
timers->set(p, NodeTimer(1., 0.));
|
||||
}
|
||||
}
|
||||
|
||||
void content_nodemeta_serialize_legacy(std::ostream &os, NodeMetadataList *meta)
|
||||
{
|
||||
// Sorry, I was too lazy to implement this. --kahrl
|
||||
writeU16(os, 1); // version
|
||||
writeU16(os, 0); // count
|
||||
}
|
||||
|
||||
// END
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -21,6 +21,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define CONTENT_NODEMETA_HEADER
|
||||
|
||||
#include "nodemetadata.h"
|
||||
#include "nodetimer.h"
|
||||
|
||||
/*
|
||||
Legacy nodemeta definitions
|
||||
*/
|
||||
|
||||
void content_nodemeta_deserialize_legacy(std::istream &is,
|
||||
NodeMetadataList *meta, NodeTimerList *timers,
|
||||
IGameDef *gamedef);
|
||||
|
||||
void content_nodemeta_serialize_legacy(std::ostream &os, NodeMetadataList *meta);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -32,5 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// Special type, not stored as a static object
|
||||
#define ACTIVEOBJECT_TYPE_PLAYER 100
|
||||
|
||||
// Special type, only exists as CAO
|
||||
#define ACTIVEOBJECT_TYPE_GENERIC 101
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -26,6 +26,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "serialization.h" // For compressZlib
|
||||
#include "tool.h" // For ToolCapabilities
|
||||
#include "gamedef.h"
|
||||
#include "player.h"
|
||||
#include "scriptapi.h"
|
||||
#include "genericobject.h"
|
||||
|
||||
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
|
||||
|
||||
@@ -333,9 +336,6 @@ ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
|
||||
LuaEntitySAO
|
||||
*/
|
||||
|
||||
#include "scriptapi.h"
|
||||
#include "luaentity_common.h"
|
||||
|
||||
// Prototype (registers item for deserialization)
|
||||
LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", "");
|
||||
|
||||
@@ -345,11 +345,11 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
||||
m_init_name(name),
|
||||
m_init_state(state),
|
||||
m_registered(false),
|
||||
m_prop(new LuaEntityProperties),
|
||||
m_hp(-1),
|
||||
m_velocity(0,0,0),
|
||||
m_acceleration(0,0,0),
|
||||
m_yaw(0),
|
||||
m_properties_sent(true),
|
||||
m_last_sent_yaw(0),
|
||||
m_last_sent_position(0,0,0),
|
||||
m_last_sent_velocity(0,0,0),
|
||||
@@ -374,7 +374,6 @@ LuaEntitySAO::~LuaEntitySAO()
|
||||
lua_State *L = m_env->getLua();
|
||||
scriptapi_luaentity_rm(L, m_id);
|
||||
}
|
||||
delete m_prop;
|
||||
}
|
||||
|
||||
void LuaEntitySAO::addedToEnvironment()
|
||||
@@ -387,13 +386,12 @@ void LuaEntitySAO::addedToEnvironment()
|
||||
|
||||
if(m_registered){
|
||||
// Get properties
|
||||
scriptapi_luaentity_get_properties(L, m_id, m_prop);
|
||||
scriptapi_luaentity_get_properties(L, m_id, &m_prop);
|
||||
// Initialize HP from properties
|
||||
m_hp = m_prop->hp_max;
|
||||
m_hp = m_prop.hp_max;
|
||||
// Activate entity, supplying serialized state
|
||||
scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
|
||||
}
|
||||
|
||||
// Activate entity, supplying serialized state
|
||||
scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
|
||||
}
|
||||
|
||||
ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
|
||||
@@ -433,10 +431,19 @@ ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
|
||||
|
||||
void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||
{
|
||||
if(!m_properties_sent)
|
||||
{
|
||||
m_properties_sent = true;
|
||||
std::string str = getPropertyPacket();
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
m_last_sent_position_timer += dtime;
|
||||
|
||||
if(m_prop->physical){
|
||||
core::aabbox3d<f32> box = m_prop->collisionbox;
|
||||
if(m_prop.physical){
|
||||
core::aabbox3d<f32> box = m_prop.collisionbox;
|
||||
box.MinEdge *= BS;
|
||||
box.MaxEdge *= BS;
|
||||
collisionMoveResult moveresult;
|
||||
@@ -482,16 +489,10 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||
|
||||
if(m_armor_groups_sent == false){
|
||||
m_armor_groups_sent = true;
|
||||
std::ostringstream os(std::ios::binary);
|
||||
writeU8(os, LUAENTITY_CMD_UPDATE_ARMOR_GROUPS);
|
||||
writeU16(os, m_armor_groups.size());
|
||||
for(ItemGroupList::const_iterator i = m_armor_groups.begin();
|
||||
i != m_armor_groups.end(); i++){
|
||||
os<<serializeString(i->first);
|
||||
writeS16(os, i->second);
|
||||
}
|
||||
std::string str = gob_cmd_update_armor_groups(
|
||||
m_armor_groups);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, os.str());
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
}
|
||||
@@ -499,18 +500,15 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||
std::string LuaEntitySAO::getClientInitializationData()
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// version
|
||||
writeU8(os, 1);
|
||||
// pos
|
||||
writeU8(os, 0); // version
|
||||
os<<serializeString(""); // name
|
||||
writeU8(os, 0); // is_player
|
||||
writeV3F1000(os, m_base_position);
|
||||
// yaw
|
||||
writeF1000(os, m_yaw);
|
||||
// hp
|
||||
writeS16(os, m_hp);
|
||||
// properties
|
||||
std::ostringstream prop_os(std::ios::binary);
|
||||
m_prop->serialize(prop_os);
|
||||
os<<serializeLongString(prop_os.str());
|
||||
writeU8(os, 2); // number of messages stuffed in here
|
||||
os<<serializeLongString(getPropertyPacket()); // message 1
|
||||
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
||||
// return result
|
||||
return os.str();
|
||||
}
|
||||
@@ -573,15 +571,9 @@ int LuaEntitySAO::punch(v3f dir,
|
||||
<<" hp, health now "<<getHP()<<" hp"<<std::endl;
|
||||
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, LUAENTITY_CMD_PUNCHED);
|
||||
// damage
|
||||
writeS16(os, result.damage);
|
||||
// result_hp
|
||||
writeS16(os, getHP());
|
||||
std::string str = gob_cmd_punched(result.damage, getHP());
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, os.str());
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
@@ -604,17 +596,6 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker)
|
||||
scriptapi_luaentity_rightclick(L, m_id, clicker);
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setHP(s16 hp)
|
||||
{
|
||||
if(hp < 0) hp = 0;
|
||||
m_hp = hp;
|
||||
}
|
||||
|
||||
s16 LuaEntitySAO::getHP()
|
||||
{
|
||||
return m_hp;
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setPos(v3f pos)
|
||||
{
|
||||
m_base_position = pos;
|
||||
@@ -644,6 +625,33 @@ std::string LuaEntitySAO::getDescription()
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setHP(s16 hp)
|
||||
{
|
||||
if(hp < 0) hp = 0;
|
||||
m_hp = hp;
|
||||
}
|
||||
|
||||
s16 LuaEntitySAO::getHP() const
|
||||
{
|
||||
return m_hp;
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
|
||||
{
|
||||
m_armor_groups = armor_groups;
|
||||
m_armor_groups_sent = false;
|
||||
}
|
||||
|
||||
ObjectProperties* LuaEntitySAO::accessObjectProperties()
|
||||
{
|
||||
return &m_prop;
|
||||
}
|
||||
|
||||
void LuaEntitySAO::notifyObjectPropertiesModified()
|
||||
{
|
||||
m_properties_sent = false;
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setVelocity(v3f velocity)
|
||||
{
|
||||
m_velocity = velocity;
|
||||
@@ -676,29 +684,23 @@ float LuaEntitySAO::getYaw()
|
||||
|
||||
void LuaEntitySAO::setTextureMod(const std::string &mod)
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, LUAENTITY_CMD_SET_TEXTURE_MOD);
|
||||
// parameters
|
||||
os<<serializeString(mod);
|
||||
std::string str = gob_cmd_set_texture_mod(mod);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, os.str());
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
|
||||
bool select_horiz_by_yawpitch)
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, LUAENTITY_CMD_SET_SPRITE);
|
||||
// parameters
|
||||
writeV2S16(os, p);
|
||||
writeU16(os, num_frames);
|
||||
writeF1000(os, framelength);
|
||||
writeU8(os, select_horiz_by_yawpitch);
|
||||
std::string str = gob_cmd_set_sprite(
|
||||
p,
|
||||
num_frames,
|
||||
framelength,
|
||||
select_horiz_by_yawpitch
|
||||
);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, os.str());
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
@@ -707,10 +709,9 @@ std::string LuaEntitySAO::getName()
|
||||
return m_init_name;
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
|
||||
std::string LuaEntitySAO::getPropertyPacket()
|
||||
{
|
||||
m_armor_groups = armor_groups;
|
||||
m_armor_groups_sent = false;
|
||||
return gob_cmd_set_properties(m_prop);
|
||||
}
|
||||
|
||||
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
||||
@@ -725,27 +726,423 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
||||
|
||||
float update_interval = m_env->getSendRecommendedInterval();
|
||||
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, LUAENTITY_CMD_UPDATE_POSITION);
|
||||
|
||||
// do_interpolate
|
||||
writeU8(os, do_interpolate);
|
||||
// pos
|
||||
writeV3F1000(os, m_base_position);
|
||||
// velocity
|
||||
writeV3F1000(os, m_velocity);
|
||||
// acceleration
|
||||
writeV3F1000(os, m_acceleration);
|
||||
// yaw
|
||||
writeF1000(os, m_yaw);
|
||||
// is_end_position (for interpolation)
|
||||
writeU8(os, is_movement_end);
|
||||
// update_interval (for interpolation)
|
||||
writeF1000(os, update_interval);
|
||||
|
||||
std::string str = gob_cmd_update_position(
|
||||
m_base_position,
|
||||
m_velocity,
|
||||
m_acceleration,
|
||||
m_yaw,
|
||||
do_interpolate,
|
||||
is_movement_end,
|
||||
update_interval
|
||||
);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, os.str());
|
||||
ActiveObjectMessage aom(getId(), false, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
/*
|
||||
PlayerSAO
|
||||
*/
|
||||
|
||||
// No prototype, PlayerSAO does not need to be deserialized
|
||||
|
||||
PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
||||
const std::set<std::string> &privs, bool is_singleplayer):
|
||||
ServerActiveObject(env_, v3f(0,0,0)),
|
||||
m_player(player_),
|
||||
m_peer_id(peer_id_),
|
||||
m_inventory(NULL),
|
||||
m_last_good_position(0,0,0),
|
||||
m_last_good_position_age(0),
|
||||
m_time_from_last_punch(0),
|
||||
m_wield_index(0),
|
||||
m_position_not_sent(false),
|
||||
m_armor_groups_sent(false),
|
||||
m_properties_sent(true),
|
||||
m_privs(privs),
|
||||
m_is_singleplayer(is_singleplayer),
|
||||
// public
|
||||
m_teleported(false),
|
||||
m_inventory_not_sent(false),
|
||||
m_hp_not_sent(false),
|
||||
m_wielded_item_not_sent(false)
|
||||
{
|
||||
assert(m_player);
|
||||
assert(m_peer_id != 0);
|
||||
setBasePosition(m_player->getPosition());
|
||||
m_inventory = &m_player->inventory;
|
||||
m_armor_groups["choppy"] = 2;
|
||||
m_armor_groups["fleshy"] = 3;
|
||||
|
||||
m_prop.hp_max = PLAYER_MAX_HP;
|
||||
m_prop.physical = false;
|
||||
m_prop.weight = 75;
|
||||
m_prop.collisionbox = core::aabbox3d<f32>(-1/3.,-1.0,-1/3., 1/3.,1.0,1/3.);
|
||||
m_prop.visual = "upright_sprite";
|
||||
m_prop.visual_size = v2f(1, 2);
|
||||
m_prop.textures.clear();
|
||||
m_prop.textures.push_back("player.png");
|
||||
m_prop.textures.push_back("player_back.png");
|
||||
m_prop.spritediv = v2s16(1,1);
|
||||
m_prop.is_visible = (getHP() != 0);
|
||||
m_prop.makes_footstep_sound = true;
|
||||
}
|
||||
|
||||
PlayerSAO::~PlayerSAO()
|
||||
{
|
||||
if(m_inventory != &m_player->inventory)
|
||||
delete m_inventory;
|
||||
|
||||
}
|
||||
|
||||
std::string PlayerSAO::getDescription()
|
||||
{
|
||||
return std::string("player ") + m_player->getName();
|
||||
}
|
||||
|
||||
// Called after id has been set and has been inserted in environment
|
||||
void PlayerSAO::addedToEnvironment()
|
||||
{
|
||||
ServerActiveObject::addedToEnvironment();
|
||||
ServerActiveObject::setBasePosition(m_player->getPosition());
|
||||
m_player->setPlayerSAO(this);
|
||||
m_player->peer_id = m_peer_id;
|
||||
m_last_good_position = m_player->getPosition();
|
||||
m_last_good_position_age = 0.0;
|
||||
}
|
||||
|
||||
// Called before removing from environment
|
||||
void PlayerSAO::removingFromEnvironment()
|
||||
{
|
||||
ServerActiveObject::removingFromEnvironment();
|
||||
if(m_player->getPlayerSAO() == this)
|
||||
{
|
||||
m_player->setPlayerSAO(NULL);
|
||||
m_player->peer_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool PlayerSAO::isStaticAllowed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerSAO::unlimitedTransferDistance() const
|
||||
{
|
||||
return g_settings->getBool("unlimited_player_transfer_distance");
|
||||
}
|
||||
|
||||
std::string PlayerSAO::getClientInitializationData()
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
writeU8(os, 0); // version
|
||||
os<<serializeString(m_player->getName()); // name
|
||||
writeU8(os, 1); // is_player
|
||||
writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
|
||||
writeF1000(os, m_player->getYaw());
|
||||
writeS16(os, getHP());
|
||||
writeU8(os, 2); // number of messages stuffed in here
|
||||
os<<serializeLongString(getPropertyPacket()); // message 1
|
||||
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string PlayerSAO::getStaticData()
|
||||
{
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
void PlayerSAO::step(float dtime, bool send_recommended)
|
||||
{
|
||||
if(!m_properties_sent)
|
||||
{
|
||||
m_properties_sent = true;
|
||||
std::string str = getPropertyPacket();
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
m_time_from_last_punch += dtime;
|
||||
|
||||
if(m_is_singleplayer)
|
||||
{
|
||||
m_last_good_position = m_player->getPosition();
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Check player movements
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
float player_max_speed = 0;
|
||||
float player_max_speed_up = 0;
|
||||
if(m_privs.count("fast") != 0){
|
||||
// Fast speed
|
||||
player_max_speed = BS * 20;
|
||||
player_max_speed_up = BS * 20;
|
||||
} else {
|
||||
// Normal speed
|
||||
player_max_speed = BS * 4.0;
|
||||
player_max_speed_up = BS * 4.0;
|
||||
}
|
||||
// Tolerance
|
||||
player_max_speed *= 2.5;
|
||||
player_max_speed_up *= 2.5;
|
||||
|
||||
m_last_good_position_age += dtime;
|
||||
if(m_last_good_position_age >= 1.0){
|
||||
float age = m_last_good_position_age;
|
||||
v3f diff = (m_player->getPosition() - m_last_good_position);
|
||||
float d_vert = diff.Y;
|
||||
diff.Y = 0;
|
||||
float d_horiz = diff.getLength();
|
||||
/*infostream<<m_player->getName()<<"'s horizontal speed is "
|
||||
<<(d_horiz/age)<<std::endl;*/
|
||||
if(d_horiz <= age * player_max_speed &&
|
||||
(d_vert < 0 || d_vert < age * player_max_speed_up)){
|
||||
m_last_good_position = m_player->getPosition();
|
||||
} else {
|
||||
actionstream<<"Player "<<m_player->getName()
|
||||
<<" moved too fast; resetting position"
|
||||
<<std::endl;
|
||||
m_player->setPosition(m_last_good_position);
|
||||
m_teleported = true;
|
||||
}
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(send_recommended == false)
|
||||
return;
|
||||
|
||||
if(m_position_not_sent)
|
||||
{
|
||||
m_position_not_sent = false;
|
||||
float update_interval = m_env->getSendRecommendedInterval();
|
||||
std::string str = gob_cmd_update_position(
|
||||
m_player->getPosition() + v3f(0,BS*1,0),
|
||||
v3f(0,0,0),
|
||||
v3f(0,0,0),
|
||||
m_player->getYaw(),
|
||||
true,
|
||||
false,
|
||||
update_interval
|
||||
);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), false, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
if(m_wielded_item_not_sent)
|
||||
{
|
||||
m_wielded_item_not_sent = false;
|
||||
// GenericCAO has no special way to show this
|
||||
}
|
||||
|
||||
if(m_armor_groups_sent == false){
|
||||
m_armor_groups_sent = true;
|
||||
std::string str = gob_cmd_update_armor_groups(
|
||||
m_armor_groups);
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerSAO::setBasePosition(const v3f &position)
|
||||
{
|
||||
ServerActiveObject::setBasePosition(position);
|
||||
m_position_not_sent = true;
|
||||
}
|
||||
|
||||
void PlayerSAO::setPos(v3f pos)
|
||||
{
|
||||
m_player->setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
// Force position change on client
|
||||
m_teleported = true;
|
||||
}
|
||||
|
||||
void PlayerSAO::moveTo(v3f pos, bool continuous)
|
||||
{
|
||||
m_player->setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
// Force position change on client
|
||||
m_teleported = true;
|
||||
}
|
||||
|
||||
int PlayerSAO::punch(v3f dir,
|
||||
const ToolCapabilities *toolcap,
|
||||
ServerActiveObject *puncher,
|
||||
float time_from_last_punch)
|
||||
{
|
||||
if(!toolcap)
|
||||
return 0;
|
||||
|
||||
// No effect if PvP disabled
|
||||
if(g_settings->getBool("enable_pvp") == false){
|
||||
if(puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER){
|
||||
std::string str = gob_cmd_punched(0, getHP());
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
HitParams hitparams = getHitParams(m_armor_groups, toolcap,
|
||||
time_from_last_punch);
|
||||
|
||||
actionstream<<"Player "<<m_player->getName()<<" punched by "
|
||||
<<puncher->getDescription()<<", damage "<<hitparams.hp
|
||||
<<" HP"<<std::endl;
|
||||
|
||||
setHP(getHP() - hitparams.hp);
|
||||
|
||||
if(hitparams.hp != 0)
|
||||
{
|
||||
std::string str = gob_cmd_punched(hitparams.hp, getHP());
|
||||
// create message and add to list
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
|
||||
return hitparams.wear;
|
||||
}
|
||||
|
||||
void PlayerSAO::rightClick(ServerActiveObject *clicker)
|
||||
{
|
||||
}
|
||||
|
||||
s16 PlayerSAO::getHP() const
|
||||
{
|
||||
return m_player->hp;
|
||||
}
|
||||
|
||||
void PlayerSAO::setHP(s16 hp)
|
||||
{
|
||||
s16 oldhp = m_player->hp;
|
||||
|
||||
if(hp < 0)
|
||||
hp = 0;
|
||||
else if(hp > PLAYER_MAX_HP)
|
||||
hp = PLAYER_MAX_HP;
|
||||
|
||||
if(hp < oldhp && g_settings->getBool("enable_damage") == false)
|
||||
{
|
||||
m_hp_not_sent = true; // fix wrong prediction on client
|
||||
return;
|
||||
}
|
||||
|
||||
m_player->hp = hp;
|
||||
|
||||
if(hp != oldhp)
|
||||
m_hp_not_sent = true;
|
||||
|
||||
// On death or reincarnation send an active object message
|
||||
if((hp == 0) != (oldhp == 0))
|
||||
{
|
||||
// Will send new is_visible value based on (getHP()!=0)
|
||||
m_properties_sent = false;
|
||||
// Send new HP
|
||||
std::string str = gob_cmd_punched(0, getHP());
|
||||
ActiveObjectMessage aom(getId(), true, str);
|
||||
m_messages_out.push_back(aom);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups)
|
||||
{
|
||||
m_armor_groups = armor_groups;
|
||||
m_armor_groups_sent = false;
|
||||
}
|
||||
|
||||
ObjectProperties* PlayerSAO::accessObjectProperties()
|
||||
{
|
||||
return &m_prop;
|
||||
}
|
||||
|
||||
void PlayerSAO::notifyObjectPropertiesModified()
|
||||
{
|
||||
m_properties_sent = false;
|
||||
}
|
||||
|
||||
Inventory* PlayerSAO::getInventory()
|
||||
{
|
||||
return m_inventory;
|
||||
}
|
||||
const Inventory* PlayerSAO::getInventory() const
|
||||
{
|
||||
return m_inventory;
|
||||
}
|
||||
|
||||
InventoryLocation PlayerSAO::getInventoryLocation() const
|
||||
{
|
||||
InventoryLocation loc;
|
||||
loc.setPlayer(m_player->getName());
|
||||
return loc;
|
||||
}
|
||||
|
||||
void PlayerSAO::setInventoryModified()
|
||||
{
|
||||
m_inventory_not_sent = true;
|
||||
}
|
||||
|
||||
std::string PlayerSAO::getWieldList() const
|
||||
{
|
||||
return "main";
|
||||
}
|
||||
|
||||
int PlayerSAO::getWieldIndex() const
|
||||
{
|
||||
return m_wield_index;
|
||||
}
|
||||
|
||||
void PlayerSAO::setWieldIndex(int i)
|
||||
{
|
||||
if(i != m_wield_index)
|
||||
{
|
||||
m_wield_index = i;
|
||||
m_wielded_item_not_sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerSAO::disconnected()
|
||||
{
|
||||
m_peer_id = 0;
|
||||
m_removed = true;
|
||||
if(m_player->getPlayerSAO() == this)
|
||||
{
|
||||
m_player->setPlayerSAO(NULL);
|
||||
m_player->peer_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
return gob_cmd_set_properties(m_prop);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -23,18 +23,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "serverobject.h"
|
||||
#include "content_object.h"
|
||||
#include "itemgroup.h"
|
||||
#include "player.h"
|
||||
#include "object_properties.h"
|
||||
|
||||
ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
|
||||
const std::string itemstring);
|
||||
|
||||
/*
|
||||
LuaEntitySAO
|
||||
|
||||
This is the only SAO that needs to have a bunch of it's internals exposed.
|
||||
LuaEntitySAO needs some internals exposed.
|
||||
*/
|
||||
|
||||
struct LuaEntityProperties;
|
||||
|
||||
class LuaEntitySAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
@@ -42,7 +40,9 @@ class LuaEntitySAO : public ServerActiveObject
|
||||
const std::string &name, const std::string &state);
|
||||
~LuaEntitySAO();
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_LUAENTITY;}
|
||||
{ return ACTIVEOBJECT_TYPE_LUAENTITY; }
|
||||
u8 getSendType() const
|
||||
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
||||
virtual void addedToEnvironment();
|
||||
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||
const std::string &data);
|
||||
@@ -59,7 +59,10 @@ class LuaEntitySAO : public ServerActiveObject
|
||||
float getMinimumSavedMovement();
|
||||
std::string getDescription();
|
||||
void setHP(s16 hp);
|
||||
s16 getHP();
|
||||
s16 getHP() const;
|
||||
void setArmorGroups(const ItemGroupList &armor_groups);
|
||||
ObjectProperties* accessObjectProperties();
|
||||
void notifyObjectPropertiesModified();
|
||||
/* LuaEntitySAO-specific */
|
||||
void setVelocity(v3f velocity);
|
||||
v3f getVelocity();
|
||||
@@ -71,21 +74,22 @@ class LuaEntitySAO : public ServerActiveObject
|
||||
void setSprite(v2s16 p, int num_frames, float framelength,
|
||||
bool select_horiz_by_yawpitch);
|
||||
std::string getName();
|
||||
void setArmorGroups(const ItemGroupList &armor_groups);
|
||||
private:
|
||||
std::string getPropertyPacket();
|
||||
void sendPosition(bool do_interpolate, bool is_movement_end);
|
||||
|
||||
std::string m_init_name;
|
||||
std::string m_init_state;
|
||||
bool m_registered;
|
||||
struct LuaEntityProperties *m_prop;
|
||||
struct ObjectProperties m_prop;
|
||||
|
||||
s16 m_hp;
|
||||
v3f m_velocity;
|
||||
v3f m_acceleration;
|
||||
float m_yaw;
|
||||
ItemGroupList m_armor_groups;
|
||||
|
||||
|
||||
bool m_properties_sent;
|
||||
float m_last_sent_yaw;
|
||||
v3f m_last_sent_position;
|
||||
v3f m_last_sent_velocity;
|
||||
@@ -94,5 +98,124 @@ class LuaEntitySAO : public ServerActiveObject
|
||||
bool m_armor_groups_sent;
|
||||
};
|
||||
|
||||
/*
|
||||
PlayerSAO needs some internals exposed.
|
||||
*/
|
||||
|
||||
class PlayerSAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
||||
const std::set<std::string> &privs, bool is_singleplayer);
|
||||
~PlayerSAO();
|
||||
u8 getType() const
|
||||
{ return ACTIVEOBJECT_TYPE_PLAYER; }
|
||||
u8 getSendType() const
|
||||
{ return ACTIVEOBJECT_TYPE_GENERIC; }
|
||||
std::string getDescription();
|
||||
|
||||
/*
|
||||
Active object <-> environment interface
|
||||
*/
|
||||
|
||||
void addedToEnvironment();
|
||||
void removingFromEnvironment();
|
||||
bool isStaticAllowed() const;
|
||||
bool unlimitedTransferDistance() const;
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
void step(float dtime, bool send_recommended);
|
||||
void setBasePosition(const v3f &position);
|
||||
void setPos(v3f pos);
|
||||
void moveTo(v3f pos, bool continuous);
|
||||
|
||||
/*
|
||||
Interaction interface
|
||||
*/
|
||||
|
||||
int punch(v3f dir,
|
||||
const ToolCapabilities *toolcap,
|
||||
ServerActiveObject *puncher,
|
||||
float time_from_last_punch);
|
||||
void rightClick(ServerActiveObject *clicker);
|
||||
s16 getHP() const;
|
||||
void setHP(s16 hp);
|
||||
|
||||
void setArmorGroups(const ItemGroupList &armor_groups);
|
||||
ObjectProperties* accessObjectProperties();
|
||||
void notifyObjectPropertiesModified();
|
||||
|
||||
/*
|
||||
Inventory interface
|
||||
*/
|
||||
|
||||
Inventory* getInventory();
|
||||
const Inventory* getInventory() const;
|
||||
InventoryLocation getInventoryLocation() const;
|
||||
void setInventoryModified();
|
||||
std::string getWieldList() const;
|
||||
int getWieldIndex() const;
|
||||
void setWieldIndex(int i);
|
||||
|
||||
/*
|
||||
PlayerSAO-specific
|
||||
*/
|
||||
|
||||
void disconnected();
|
||||
|
||||
void createCreativeInventory();
|
||||
|
||||
Player* getPlayer()
|
||||
{
|
||||
return m_player;
|
||||
}
|
||||
u16 getPeerID() const
|
||||
{
|
||||
return m_peer_id;
|
||||
}
|
||||
v3f getLastGoodPosition() const
|
||||
{
|
||||
return m_last_good_position;
|
||||
}
|
||||
float resetTimeFromLastPunch()
|
||||
{
|
||||
float r = m_time_from_last_punch;
|
||||
m_time_from_last_punch = 0.0;
|
||||
return r;
|
||||
}
|
||||
void updatePrivileges(const std::set<std::string> &privs,
|
||||
bool is_singleplayer)
|
||||
{
|
||||
m_privs = privs;
|
||||
m_is_singleplayer = is_singleplayer;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string getPropertyPacket();
|
||||
|
||||
Player *m_player;
|
||||
u16 m_peer_id;
|
||||
Inventory *m_inventory;
|
||||
v3f m_last_good_position;
|
||||
float m_last_good_position_age;
|
||||
float m_time_from_last_punch;
|
||||
int m_wield_index;
|
||||
bool m_position_not_sent;
|
||||
ItemGroupList m_armor_groups;
|
||||
bool m_armor_groups_sent;
|
||||
bool m_properties_sent;
|
||||
struct ObjectProperties m_prop;
|
||||
// Cached privileges for enforcement
|
||||
std::set<std::string> m_privs;
|
||||
bool m_is_singleplayer;
|
||||
|
||||
public:
|
||||
// Some flags used by Server
|
||||
bool m_teleported;
|
||||
bool m_inventory_not_sent;
|
||||
bool m_hp_not_sent;
|
||||
bool m_wielded_item_not_sent;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
102
src/craftdef.cpp
102
src/craftdef.cpp
@@ -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.
|
||||
*/
|
||||
@@ -27,6 +27,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "gamedef.h"
|
||||
#include "inventory.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)){
|
||||
std::string rec_group = rec_name.substr(6);
|
||||
const struct ItemDefinition &def = idef->get(inp_name);
|
||||
if(itemgroup_get(def.groups, rec_group) != 0)
|
||||
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)
|
||||
@@ -260,6 +280,7 @@ std::string CraftOutput::dump() const
|
||||
/*
|
||||
CraftReplacements
|
||||
*/
|
||||
|
||||
std::string CraftReplacements::dump() const
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
@@ -276,6 +297,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 +423,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;
|
||||
}
|
||||
@@ -418,12 +460,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 +473,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -497,12 +527,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 +539,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -664,7 +682,7 @@ CraftOutput CraftDefinitionCooking::getOutput(const CraftInput &input, IGameDef
|
||||
|
||||
void CraftDefinitionCooking::decrementInput(CraftInput &input, IGameDef *gamedef) const
|
||||
{
|
||||
craftDecrementInput(input, gamedef);
|
||||
craftDecrementOrReplaceInput(input, replacements, gamedef);
|
||||
}
|
||||
|
||||
std::string CraftDefinitionCooking::dump() const
|
||||
@@ -672,7 +690,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 +700,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 +710,7 @@ void CraftDefinitionCooking::deSerializeBody(std::istream &is, int version)
|
||||
output = deSerializeString(is);
|
||||
recipe = deSerializeString(is);
|
||||
cooktime = readF1000(is);
|
||||
replacements.deSerialize(is);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -725,14 +746,15 @@ CraftOutput CraftDefinitionFuel::getOutput(const CraftInput &input, IGameDef *ga
|
||||
|
||||
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 +762,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 +771,7 @@ void CraftDefinitionFuel::deSerializeBody(std::istream &is, int version)
|
||||
"unsupported CraftDefinitionFuel version");
|
||||
recipe = deSerializeString(is);
|
||||
burntime = readF1000(is);
|
||||
replacements.deSerialize(is);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -270,8 +272,9 @@ 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(){}
|
||||
|
||||
@@ -293,6 +296,8 @@ class CraftDefinitionCooking: public CraftDefinition
|
||||
std::string recipe;
|
||||
// Time in seconds
|
||||
float cooktime;
|
||||
// Replacement items for decrementInput()
|
||||
CraftReplacements replacements;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -305,8 +310,10 @@ 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(){}
|
||||
|
||||
@@ -326,6 +333,8 @@ class CraftDefinitionFuel: public CraftDefinition
|
||||
std::string recipe;
|
||||
// Time in seconds
|
||||
float burntime;
|
||||
// Replacement items for decrementInput()
|
||||
CraftReplacements replacements;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -70,10 +69,14 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("wanted_fps", "30");
|
||||
settings->setDefault("fps_max", "60");
|
||||
// A bit more than the server will send around the player, to make fog blend well
|
||||
settings->setDefault("viewing_range_nodes_min", "35");
|
||||
settings->setDefault("viewing_range_nodes_max", "160");
|
||||
settings->setDefault("viewing_range_nodes_min", "35");
|
||||
settings->setDefault("screenW", "800");
|
||||
settings->setDefault("screenH", "600");
|
||||
settings->setDefault("fullscreen", "false");
|
||||
settings->setDefault("fullscreen_bpp", "24");
|
||||
settings->setDefault("fsaa", "0");
|
||||
settings->setDefault("vsync", "false");
|
||||
settings->setDefault("address", "");
|
||||
settings->setDefault("random_input", "false");
|
||||
settings->setDefault("client_unload_unused_data_timeout", "600");
|
||||
@@ -81,7 +84,7 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("fov", "72");
|
||||
settings->setDefault("view_bobbing", "true");
|
||||
settings->setDefault("new_style_water", "false");
|
||||
settings->setDefault("new_style_leaves", "false");
|
||||
settings->setDefault("new_style_leaves", "true");
|
||||
settings->setDefault("smooth_lighting", "true");
|
||||
settings->setDefault("enable_texture_atlas", "true");
|
||||
settings->setDefault("texture_path", "");
|
||||
@@ -94,10 +97,12 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("enable_clouds", "true");
|
||||
settings->setDefault("screenshot_path", ".");
|
||||
settings->setDefault("view_bobbing_amount", "1.0");
|
||||
settings->setDefault("enable_3d_clouds", "false");
|
||||
settings->setDefault("enable_3d_clouds", "true");
|
||||
settings->setDefault("opaque_water", "false");
|
||||
settings->setDefault("console_color", "(0,0,0)");
|
||||
settings->setDefault("console_alpha", "200");
|
||||
settings->setDefault("enable_sound", "true");
|
||||
settings->setDefault("sound_volume", "0.8");
|
||||
|
||||
// Server stuff
|
||||
// "map-dir" doesn't exist by default.
|
||||
@@ -111,7 +116,7 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("fixed_map_seed", "");
|
||||
settings->setDefault("give_initial_stuff", "false");
|
||||
settings->setDefault("default_password", "");
|
||||
settings->setDefault("default_privs", "build, shout");
|
||||
settings->setDefault("default_privs", "interact, shout");
|
||||
settings->setDefault("unlimited_player_transfer_distance", "true");
|
||||
settings->setDefault("enable_pvp", "true");
|
||||
|
||||
@@ -123,14 +128,14 @@ void set_default_settings(Settings *settings)
|
||||
// This causes frametime jitter on client side, or does it?
|
||||
settings->setDefault("max_simultaneous_block_sends_per_client", "4");
|
||||
settings->setDefault("max_simultaneous_block_sends_server_total", "20");
|
||||
settings->setDefault("max_block_send_distance", "10");
|
||||
settings->setDefault("max_block_generate_distance", "6");
|
||||
settings->setDefault("max_block_send_distance", "9");
|
||||
settings->setDefault("max_block_generate_distance", "7");
|
||||
settings->setDefault("time_send_interval", "5");
|
||||
settings->setDefault("time_speed", "96");
|
||||
settings->setDefault("time_speed", "72");
|
||||
settings->setDefault("server_unload_unused_data_timeout", "29");
|
||||
settings->setDefault("server_map_save_interval", "5.3");
|
||||
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
||||
settings->setDefault("enable_experimental", "false");
|
||||
settings->setDefault("dedicated_server_step", "0.05");
|
||||
settings->setDefault("ignore_world_load_errors", "false");
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -37,9 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "nodemetadata.h"
|
||||
#include "main.h" // For g_settings, g_profiler
|
||||
#include "gamedef.h"
|
||||
#include "serverremoteplayer.h"
|
||||
#ifndef SERVER
|
||||
#include "clientmap.h"
|
||||
#include "localplayer.h"
|
||||
#endif
|
||||
#include "daynightratio.h"
|
||||
|
||||
@@ -368,7 +368,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
||||
//infostream<<"Checking player file "<<path<<std::endl;
|
||||
|
||||
// Load player to see what is its name
|
||||
ServerRemotePlayer testplayer(this);
|
||||
RemotePlayer testplayer(m_gamedef);
|
||||
{
|
||||
// Open file and deserialize
|
||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||
@@ -482,7 +482,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
||||
//infostream<<"Checking player file "<<path<<std::endl;
|
||||
|
||||
// Load player to see what is its name
|
||||
ServerRemotePlayer testplayer(this);
|
||||
RemotePlayer testplayer(m_gamedef);
|
||||
{
|
||||
// Open file and deserialize
|
||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||
@@ -510,12 +510,10 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
||||
if(player == NULL)
|
||||
{
|
||||
//infostream<<"Is a new player"<<std::endl;
|
||||
player = new ServerRemotePlayer(this);
|
||||
player = new RemotePlayer(m_gamedef);
|
||||
newplayer = true;
|
||||
}
|
||||
|
||||
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
|
||||
|
||||
// Load player
|
||||
{
|
||||
verbosestream<<"Reading player "<<testplayer.getName()<<" from "
|
||||
@@ -527,9 +525,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
||||
infostream<<"Failed to read "<<path<<std::endl;
|
||||
continue;
|
||||
}
|
||||
srp->deSerialize(is);
|
||||
srp->m_last_good_position = srp->getBasePosition();
|
||||
srp->m_last_good_position_age = 0;
|
||||
player->deSerialize(is);
|
||||
}
|
||||
|
||||
if(newplayer)
|
||||
@@ -637,13 +633,15 @@ class ABMHandler
|
||||
i->timer -= trigger_interval;
|
||||
actual_interval = trigger_interval;
|
||||
}
|
||||
ActiveABM aabm;
|
||||
aabm.abm = abm;
|
||||
float intervals = actual_interval / trigger_interval;
|
||||
if(intervals == 0)
|
||||
continue;
|
||||
float chance = abm->getTriggerChance();
|
||||
if(chance == 0)
|
||||
chance = 1;
|
||||
aabm.chance = 1.0 / pow((float)1.0/chance, (float)intervals);
|
||||
ActiveABM aabm;
|
||||
aabm.abm = abm;
|
||||
aabm.chance = chance / intervals;
|
||||
if(aabm.chance == 0)
|
||||
aabm.chance = 1;
|
||||
// Trigger neighbors
|
||||
@@ -651,27 +649,30 @@ class ABMHandler
|
||||
= abm->getRequiredNeighbors();
|
||||
for(std::set<std::string>::iterator
|
||||
i = required_neighbors_s.begin();
|
||||
i != required_neighbors_s.end(); i++){
|
||||
content_t c = ndef->getId(*i);
|
||||
if(c == CONTENT_IGNORE)
|
||||
continue;
|
||||
aabm.required_neighbors.insert(c);
|
||||
i != required_neighbors_s.end(); i++)
|
||||
{
|
||||
ndef->getIds(*i, aabm.required_neighbors);
|
||||
}
|
||||
// Trigger contents
|
||||
std::set<std::string> contents_s = abm->getTriggerContents();
|
||||
for(std::set<std::string>::iterator
|
||||
i = contents_s.begin(); i != contents_s.end(); i++){
|
||||
content_t c = ndef->getId(*i);
|
||||
if(c == CONTENT_IGNORE)
|
||||
continue;
|
||||
std::map<content_t, std::list<ActiveABM> >::iterator j;
|
||||
j = m_aabms.find(c);
|
||||
if(j == m_aabms.end()){
|
||||
std::list<ActiveABM> aabmlist;
|
||||
m_aabms[c] = aabmlist;
|
||||
i = contents_s.begin(); i != contents_s.end(); i++)
|
||||
{
|
||||
std::set<content_t> ids;
|
||||
ndef->getIds(*i, ids);
|
||||
for(std::set<content_t>::const_iterator k = ids.begin();
|
||||
k != ids.end(); k++)
|
||||
{
|
||||
content_t c = *k;
|
||||
std::map<content_t, std::list<ActiveABM> >::iterator j;
|
||||
j = m_aabms.find(c);
|
||||
if(j == m_aabms.end()){
|
||||
std::list<ActiveABM> aabmlist;
|
||||
m_aabms[c] = aabmlist;
|
||||
j = m_aabms.find(c);
|
||||
}
|
||||
j->second.push_back(aabm);
|
||||
}
|
||||
j->second.push_back(aabm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -772,18 +773,11 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
|
||||
// Activate stored objects
|
||||
activateObjects(block);
|
||||
|
||||
// Run node metadata
|
||||
bool changed = block->m_node_metadata->step((float)dtime_s);
|
||||
if(changed)
|
||||
{
|
||||
MapEditEvent event;
|
||||
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
|
||||
event.p = block->getPos();
|
||||
m_map->dispatchEvent(&event);
|
||||
|
||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||
"node metadata modified in activateBlock");
|
||||
}
|
||||
// Run node timers
|
||||
std::map<v3s16, f32> elapsed_timers =
|
||||
block->m_node_timers.step((float)dtime_s);
|
||||
if(!elapsed_timers.empty())
|
||||
errorstream<<"Node timers don't work yet!"<<std::endl;
|
||||
|
||||
/* Handle ActiveBlockModifiers */
|
||||
ABMHandler abmhandler(m_abms, dtime_s, this, false);
|
||||
@@ -1063,18 +1057,11 @@ void ServerEnvironment::step(float dtime)
|
||||
block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD,
|
||||
"Timestamp older than 60s (step)");
|
||||
|
||||
// Run node metadata
|
||||
bool changed = block->m_node_metadata->step(dtime);
|
||||
if(changed)
|
||||
{
|
||||
MapEditEvent event;
|
||||
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
|
||||
event.p = p;
|
||||
m_map->dispatchEvent(&event);
|
||||
|
||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||
"node metadata modified in 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1747,6 +1734,15 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||
force_delete = true;
|
||||
} else {
|
||||
u16 new_id = pending_delete ? id : 0;
|
||||
// If static counterpart already exists, remove it first.
|
||||
// This shouldn't happen, but happens rarely for some
|
||||
// unknown reason. Unsuccessful attempts have been made to
|
||||
// find said reason.
|
||||
if(new_id && block->m_static_objects.m_active.find(new_id)){
|
||||
infostream<<"ServerEnv: WARNING: Performing hack #83274"
|
||||
<<std::endl;
|
||||
block->m_static_objects.remove(new_id);
|
||||
}
|
||||
block->m_static_objects.insert(new_id, s_obj);
|
||||
|
||||
// Only mark block as modified if data changed considerably
|
||||
@@ -1890,7 +1886,8 @@ void ClientEnvironment::step(float dtime)
|
||||
stepTimeOfDay(dtime);
|
||||
|
||||
// Get some settings
|
||||
bool free_move = g_settings->getBool("free_move");
|
||||
bool fly_allowed = m_gamedef->checkLocalPrivilege("fly");
|
||||
bool free_move = fly_allowed && g_settings->getBool("free_move");
|
||||
|
||||
// Get local player
|
||||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
@@ -2004,13 +2001,15 @@ void ClientEnvironment::step(float dtime)
|
||||
if(info.t == COLLISION_FALL)
|
||||
{
|
||||
//f32 tolerance = BS*10; // 2 without damage
|
||||
f32 tolerance = BS*12; // 3 without damage
|
||||
//f32 tolerance = BS*12; // 3 without damage
|
||||
f32 tolerance = BS*14; // 5 without damage
|
||||
f32 factor = 1;
|
||||
if(info.speed > tolerance)
|
||||
{
|
||||
f32 damage_f = (info.speed - tolerance)/BS*factor;
|
||||
u16 damage = (u16)(damage_f+0.5);
|
||||
damageLocalPlayer(damage, true);
|
||||
if(damage != 0)
|
||||
damageLocalPlayer(damage, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2074,7 +2073,7 @@ void ClientEnvironment::step(float dtime)
|
||||
catch(InvalidPositionException &e){
|
||||
light = blend_light(getDayNightRatio(), LIGHT_SUN, 0);
|
||||
}
|
||||
player->updateLight(light);
|
||||
player->light = light;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2226,8 +2225,19 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
|
||||
|
||||
obj->setId(id);
|
||||
|
||||
obj->initialize(init_data);
|
||||
|
||||
try
|
||||
{
|
||||
obj->initialize(init_data);
|
||||
}
|
||||
catch(SerializationError &e)
|
||||
{
|
||||
errorstream<<"ClientEnvironment::addActiveObject():"
|
||||
<<" id="<<id<<" type="<<type
|
||||
<<": SerializationError in initialize(),"
|
||||
<<" init_data="<<serializeJsonString(init_data)
|
||||
<<std::endl;
|
||||
}
|
||||
|
||||
addActiveObject(obj);
|
||||
}
|
||||
|
||||
@@ -2258,7 +2268,18 @@ void ClientEnvironment::processActiveObjectMessage(u16 id,
|
||||
<<std::endl;
|
||||
return;
|
||||
}
|
||||
obj->processMessage(data);
|
||||
try
|
||||
{
|
||||
obj->processMessage(data);
|
||||
}
|
||||
catch(SerializationError &e)
|
||||
{
|
||||
errorstream<<"ClientEnvironment::processActiveObjectMessage():"
|
||||
<<" id="<<id<<" type="<<obj->getType()
|
||||
<<" SerializationError in processMessage(),"
|
||||
<<" message="<<serializeJsonString(data)
|
||||
<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -125,7 +125,7 @@ HeightPoint ground_height(u64 seed, v2s16 p2d)
|
||||
hp.ma = (4)*BS;
|
||||
/*hp.gh = BS*base_rock_level_2d(seed, p2d);
|
||||
hp.ma = BS*get_mud_add_amount(seed, p2d);*/
|
||||
hp.have_sand = mapgen::get_have_sand(seed, p2d);
|
||||
hp.have_sand = mapgen::get_have_beach(seed, p2d);
|
||||
if(hp.gh > BS*WATER_LEVEL)
|
||||
hp.tree_amount = mapgen::tree_amount_2d(seed, p2d);
|
||||
else
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -214,6 +214,7 @@ bool DeleteSingleFileOrEmptyDirectory(std::string path)
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
std::vector<DirListNode> GetDirListing(std::string pathstring)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
134
src/game.cpp
134
src/game.cpp
@@ -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.
|
||||
*/
|
||||
@@ -103,7 +103,9 @@ struct TextDestNodeMetadata : public TextDest
|
||||
std::string ntext = wide_to_narrow(text);
|
||||
infostream<<"Changing text of a sign node: "
|
||||
<<ntext<<std::endl;
|
||||
m_client->sendSignNodeText(m_p, ntext);
|
||||
std::map<std::string, std::string> fields;
|
||||
fields["text"] = ntext;
|
||||
m_client->sendNodemetaFields(m_p, "", fields);
|
||||
}
|
||||
|
||||
v3s16 m_p;
|
||||
@@ -130,6 +132,28 @@ class MainRespawnInitiator: public IRespawnInitiator
|
||||
Client *m_client;
|
||||
};
|
||||
|
||||
/* Form update callback */
|
||||
|
||||
class NodeMetadataFormSource: public IFormSource
|
||||
{
|
||||
public:
|
||||
NodeMetadataFormSource(ClientMap *map, v3s16 p):
|
||||
m_map(map),
|
||||
m_p(p)
|
||||
{
|
||||
}
|
||||
std::string getForm()
|
||||
{
|
||||
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
||||
if(!meta)
|
||||
return "";
|
||||
return meta->getString("formspec");
|
||||
}
|
||||
|
||||
ClientMap *m_map;
|
||||
v3s16 m_p;
|
||||
};
|
||||
|
||||
/*
|
||||
Hotbar draw routine
|
||||
*/
|
||||
@@ -955,10 +979,14 @@ void the_game(
|
||||
ISoundManager *sound = NULL;
|
||||
bool sound_is_dummy = false;
|
||||
#if USE_SOUND
|
||||
infostream<<"Attempting to use OpenAL audio"<<std::endl;
|
||||
sound = createOpenALSoundManager(&soundfetcher);
|
||||
if(!sound)
|
||||
infostream<<"Failed to initialize OpenAL audio"<<std::endl;
|
||||
if(g_settings->getBool("enable_sound")){
|
||||
infostream<<"Attempting to use OpenAL audio"<<std::endl;
|
||||
sound = createOpenALSoundManager(&soundfetcher);
|
||||
if(!sound)
|
||||
infostream<<"Failed to initialize OpenAL audio"<<std::endl;
|
||||
} else {
|
||||
infostream<<"Sound disabled."<<std::endl;
|
||||
}
|
||||
#endif
|
||||
if(!sound){
|
||||
infostream<<"Using dummy audio."<<std::endl;
|
||||
@@ -1563,24 +1591,19 @@ void the_game(
|
||||
|
||||
GUIInventoryMenu *menu =
|
||||
new GUIInventoryMenu(guienv, guiroot, -1,
|
||||
&g_menumgr, v2s16(8,7),
|
||||
&g_menumgr,
|
||||
&client, gamedef);
|
||||
|
||||
InventoryLocation inventoryloc;
|
||||
inventoryloc.setCurrentPlayer();
|
||||
|
||||
core::array<GUIInventoryMenu::DrawSpec> draw_spec;
|
||||
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
|
||||
"list", inventoryloc, "main",
|
||||
v2s32(0, 3), v2s32(8, 4)));
|
||||
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
|
||||
"list", inventoryloc, "craft",
|
||||
v2s32(3, 0), v2s32(3, 3)));
|
||||
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
|
||||
"list", inventoryloc, "craftpreview",
|
||||
v2s32(7, 1), v2s32(1, 1)));
|
||||
|
||||
menu->setDrawSpec(draw_spec);
|
||||
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);
|
||||
|
||||
menu->drop();
|
||||
}
|
||||
@@ -1636,6 +1659,8 @@ void the_game(
|
||||
g_settings->set("free_move","true");
|
||||
statustext = L"free_move enabled";
|
||||
statustext_time = 0;
|
||||
if(!client.checkPrivilege("fly"))
|
||||
statustext += L" (note: no 'fly' privilege)";
|
||||
}
|
||||
}
|
||||
else if(input->wasKeyDown(getKeySetting("keymap_fastmove")))
|
||||
@@ -1651,6 +1676,8 @@ void the_game(
|
||||
g_settings->set("fast_move","true");
|
||||
statustext = L"fast_move enabled";
|
||||
statustext_time = 0;
|
||||
if(!client.checkPrivilege("fast"))
|
||||
statustext += L" (note: no 'fast' privilege)";
|
||||
}
|
||||
}
|
||||
else if(input->wasKeyDown(getKeySetting("keymap_screenshot")))
|
||||
@@ -2076,8 +2103,9 @@ void the_game(
|
||||
// Update sound listener
|
||||
sound->updateListener(camera.getCameraNode()->getPosition(),
|
||||
v3f(0,0,0), // velocity
|
||||
camera.getCameraNode()->getTarget(),
|
||||
camera.getDirection(),
|
||||
camera.getCameraNode()->getUpVector());
|
||||
sound->setListenerGain(g_settings->getFloat("sound_volume"));
|
||||
|
||||
/*
|
||||
Update sound maker
|
||||
@@ -2186,7 +2214,7 @@ void the_game(
|
||||
ClientMap &map = client.getEnv().getClientMap();
|
||||
NodeMetadata *meta = map.getNodeMetadata(nodepos);
|
||||
if(meta){
|
||||
infotext = narrow_to_wide(meta->infoText());
|
||||
infotext = narrow_to_wide(meta->getString("infotext"));
|
||||
} else {
|
||||
MapNode n = map.getNode(nodepos);
|
||||
if(nodedef->get(n).tname_tiles[0] == "unknown_block.png"){
|
||||
@@ -2311,35 +2339,8 @@ void the_game(
|
||||
{
|
||||
infostream<<"Ground right-clicked"<<std::endl;
|
||||
|
||||
// If metadata provides an inventory view, activate it
|
||||
if(meta && meta->getInventoryDrawSpecString() != "" && !random_input)
|
||||
{
|
||||
infostream<<"Launching custom inventory view"<<std::endl;
|
||||
|
||||
InventoryLocation inventoryloc;
|
||||
inventoryloc.setNodeMeta(nodepos);
|
||||
|
||||
|
||||
/*
|
||||
Create menu
|
||||
*/
|
||||
|
||||
core::array<GUIInventoryMenu::DrawSpec> draw_spec;
|
||||
v2s16 invsize =
|
||||
GUIInventoryMenu::makeDrawSpecArrayFromString(
|
||||
draw_spec,
|
||||
meta->getInventoryDrawSpecString(),
|
||||
inventoryloc);
|
||||
|
||||
GUIInventoryMenu *menu =
|
||||
new GUIInventoryMenu(guienv, guiroot, -1,
|
||||
&g_menumgr, invsize,
|
||||
&client, gamedef);
|
||||
menu->setDrawSpec(draw_spec);
|
||||
menu->drop();
|
||||
}
|
||||
// If metadata provides text input, activate text input
|
||||
else if(meta && meta->allowsTextInput() && !random_input)
|
||||
// sign special case, at least until formspec is properly implemented
|
||||
if(meta && meta->getString("formspec") == "hack:sign_text_input" && !random_input)
|
||||
{
|
||||
infostream<<"Launching metadata text input"<<std::endl;
|
||||
|
||||
@@ -2347,12 +2348,32 @@ void the_game(
|
||||
|
||||
TextDest *dest = new TextDestNodeMetadata(nodepos, &client);
|
||||
|
||||
std::wstring wtext = narrow_to_wide(meta->getText());
|
||||
std::wstring wtext = narrow_to_wide(meta->getString("text"));
|
||||
|
||||
(new GUITextInputMenu(guienv, guiroot, -1,
|
||||
&g_menumgr, dest,
|
||||
wtext))->drop();
|
||||
}
|
||||
// If metadata provides an inventory view, activate it
|
||||
else if(meta && meta->getString("formspec") != "" && !random_input)
|
||||
{
|
||||
infostream<<"Launching custom inventory view"<<std::endl;
|
||||
|
||||
InventoryLocation inventoryloc;
|
||||
inventoryloc.setNodeMeta(nodepos);
|
||||
|
||||
/* Create menu */
|
||||
|
||||
GUIInventoryMenu *menu =
|
||||
new GUIInventoryMenu(guienv, guiroot, -1,
|
||||
&g_menumgr,
|
||||
&client, gamedef);
|
||||
menu->setFormSpec(meta->getString("formspec"),
|
||||
inventoryloc);
|
||||
menu->setFormSource(new NodeMetadataFormSource(
|
||||
&client.getEnv().getClientMap(), nodepos));
|
||||
menu->drop();
|
||||
}
|
||||
// Otherwise report right click to server
|
||||
else
|
||||
{
|
||||
@@ -2596,11 +2617,12 @@ void the_game(
|
||||
char temptext[300];
|
||||
snprintf(temptext, 300,
|
||||
"(% .1f, % .1f, % .1f)"
|
||||
" (yaw = %.1f)",
|
||||
" (yaw = %.1f) (seed = %lli)",
|
||||
player_position.X/BS,
|
||||
player_position.Y/BS,
|
||||
player_position.Z/BS,
|
||||
wrapDegrees_0_360(camera_yaw));
|
||||
wrapDegrees_0_360(camera_yaw),
|
||||
client.getMapSeed());
|
||||
|
||||
guitext2->setText(narrow_to_wide(temptext).c_str());
|
||||
guitext2->setVisible(true);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -50,10 +50,15 @@ class IGameDef
|
||||
|
||||
// Used for keeping track of names/ids of unknown nodes
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
|
||||
|
||||
|
||||
// Only usable on the client
|
||||
virtual ISoundManager* getSoundManager()=0;
|
||||
virtual MtEventManager* getEventManager()=0;
|
||||
|
||||
// Used on the client
|
||||
virtual bool checkLocalPrivilege(const std::string &priv)
|
||||
{ return false; }
|
||||
|
||||
// Shorthands
|
||||
IItemDefManager* idef(){return getItemDefManager();}
|
||||
INodeDefManager* ndef(){return getNodeDefManager();}
|
||||
|
||||
120
src/genericobject.cpp
Normal file
120
src/genericobject.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
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 Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "genericobject.h"
|
||||
#include "utility.h"
|
||||
#include <sstream>
|
||||
|
||||
std::string gob_cmd_set_properties(const ObjectProperties &prop)
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
writeU8(os, GENERIC_CMD_SET_PROPERTIES);
|
||||
prop.serialize(os);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
ObjectProperties gob_read_set_properties(std::istream &is)
|
||||
{
|
||||
ObjectProperties prop;
|
||||
prop.deSerialize(is);
|
||||
return prop;
|
||||
}
|
||||
|
||||
std::string gob_cmd_update_position(
|
||||
v3f position,
|
||||
v3f velocity,
|
||||
v3f acceleration,
|
||||
f32 yaw,
|
||||
bool do_interpolate,
|
||||
bool is_movement_end,
|
||||
f32 update_interval
|
||||
){
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, GENERIC_CMD_UPDATE_POSITION);
|
||||
// pos
|
||||
writeV3F1000(os, position);
|
||||
// velocity
|
||||
writeV3F1000(os, velocity);
|
||||
// acceleration
|
||||
writeV3F1000(os, acceleration);
|
||||
// yaw
|
||||
writeF1000(os, yaw);
|
||||
// do_interpolate
|
||||
writeU8(os, do_interpolate);
|
||||
// is_end_position (for interpolation)
|
||||
writeU8(os, is_movement_end);
|
||||
// update_interval (for interpolation)
|
||||
writeF1000(os, update_interval);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string gob_cmd_set_texture_mod(const std::string &mod)
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, GENERIC_CMD_SET_TEXTURE_MOD);
|
||||
// parameters
|
||||
os<<serializeString(mod);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string gob_cmd_set_sprite(
|
||||
v2s16 p,
|
||||
u16 num_frames,
|
||||
f32 framelength,
|
||||
bool select_horiz_by_yawpitch
|
||||
){
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, GENERIC_CMD_SET_SPRITE);
|
||||
// parameters
|
||||
writeV2S16(os, p);
|
||||
writeU16(os, num_frames);
|
||||
writeF1000(os, framelength);
|
||||
writeU8(os, select_horiz_by_yawpitch);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string gob_cmd_punched(s16 damage, s16 result_hp)
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
// command
|
||||
writeU8(os, GENERIC_CMD_PUNCHED);
|
||||
// damage
|
||||
writeS16(os, damage);
|
||||
// result_hp
|
||||
writeS16(os, result_hp);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups)
|
||||
{
|
||||
std::ostringstream os(std::ios::binary);
|
||||
writeU8(os, GENERIC_CMD_UPDATE_ARMOR_GROUPS);
|
||||
writeU16(os, armor_groups.size());
|
||||
for(ItemGroupList::const_iterator i = armor_groups.begin();
|
||||
i != armor_groups.end(); i++){
|
||||
os<<serializeString(i->first);
|
||||
writeS16(os, i->second);
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
63
src/genericobject.h
Normal file
63
src/genericobject.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
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 Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef GENERICOBJECT_HEADER
|
||||
#define GENERICOBJECT_HEADER
|
||||
|
||||
#include <string>
|
||||
#include "irrlichttypes.h"
|
||||
#include <iostream>
|
||||
|
||||
#define GENERIC_CMD_SET_PROPERTIES 0
|
||||
#define GENERIC_CMD_UPDATE_POSITION 1
|
||||
#define GENERIC_CMD_SET_TEXTURE_MOD 2
|
||||
#define GENERIC_CMD_SET_SPRITE 3
|
||||
#define GENERIC_CMD_PUNCHED 4
|
||||
#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 5
|
||||
|
||||
#include "object_properties.h"
|
||||
std::string gob_cmd_set_properties(const ObjectProperties &prop);
|
||||
ObjectProperties gob_read_set_properties(std::istream &is);
|
||||
|
||||
std::string gob_cmd_update_position(
|
||||
v3f position,
|
||||
v3f velocity,
|
||||
v3f acceleration,
|
||||
f32 yaw,
|
||||
bool do_interpolate,
|
||||
bool is_movement_end,
|
||||
f32 update_interval
|
||||
);
|
||||
|
||||
std::string gob_cmd_set_texture_mod(const std::string &mod);
|
||||
|
||||
std::string gob_cmd_set_sprite(
|
||||
v2s16 p,
|
||||
u16 num_frames,
|
||||
f32 framelength,
|
||||
bool select_horiz_by_yawpitch
|
||||
);
|
||||
|
||||
std::string gob_cmd_punched(s16 damage, s16 result_hp);
|
||||
|
||||
#include "itemgroup.h"
|
||||
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user